dynarmic/src/ir_opt/constant_propagation_pass.cpp

63 lines
1.9 KiB
C++
Raw Normal View History

/* 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.
*/
2018-01-04 21:12:02 +00:00
#include <dynarmic/A32/callbacks.h>
#include "frontend/ir/basic_block.h"
#include "frontend/ir/opcodes.h"
#include "ir_opt/passes.h"
namespace Dynarmic {
namespace Optimization {
2018-01-10 19:24:19 +00:00
void ConstantPropagation(IR::Block& block) {
for (auto& inst : block) {
switch (inst.GetOpcode()) {
2018-01-07 00:11:57 +00:00
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<u32>(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<u32>(half);
inst.ReplaceUsesWith(IR::Value{value});
break;
}
default:
break;
}
}
}
} // namespace Optimization
} // namespace Dynarmic