/* This file is part of the dynarmic project. * Copyright (c) 2016 MerryMage * This software may be used and distributed according to the terms of the GNU * General Public License version 2 or any later version. */ #include #include "frontend/ir/basic_block.h" #include "frontend/ir/opcodes.h" #include "ir_opt/passes.h" namespace Dynarmic { namespace Optimization { void ConstantPropagation(IR::Block& block) { for (auto& inst : block) { switch (inst.GetOpcode()) { case IR::Opcode::LogicalShiftLeft32: case IR::Opcode::LogicalShiftRight32: case IR::Opcode::ArithmeticShiftRight32: case IR::Opcode::RotateRight32: { if (!inst.GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp)) { inst.SetArg(2, IR::Value(false)); } auto shift_amount = inst.GetArg(1); if (shift_amount.IsImmediate() && shift_amount.GetU8() == 0) { IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); if (carry_inst) { carry_inst->ReplaceUsesWith(inst.GetArg(2)); } inst.ReplaceUsesWith(inst.GetArg(0)); } break; } case IR::Opcode::ZeroExtendByteToWord: { if (!inst.AreAllArgsImmediates()) break; u8 byte = inst.GetArg(0).GetU8(); u32 value = static_cast(byte); inst.ReplaceUsesWith(IR::Value{value}); break; } case IR::Opcode::ZeroExtendHalfToWord: { if (!inst.AreAllArgsImmediates()) break; u16 half = inst.GetArg(0).GetU16(); u32 value = static_cast(half); inst.ReplaceUsesWith(IR::Value{value}); break; } default: break; } } } } // namespace Optimization } // namespace Dynarmic