Merge pull request #419 from lioncash/fold-op

constant_propagation_pass: Fold byte reversal opcodes where applicable
This commit is contained in:
Merry 2018-11-25 09:50:56 +00:00 committed by MerryMage
commit dfdca2082f

View file

@ -6,6 +6,7 @@
#include <dynarmic/A32/config.h> #include <dynarmic/A32/config.h>
#include "common/bit_util.h"
#include "frontend/ir/basic_block.h" #include "frontend/ir/basic_block.h"
#include "frontend/ir/opcodes.h" #include "frontend/ir/opcodes.h"
#include "ir_opt/passes.h" #include "ir_opt/passes.h"
@ -50,6 +51,29 @@ void FoldAND(IR::Inst& inst, bool is_32_bit) {
} }
} }
// Folds byte reversal opcodes based on the following:
//
// 1. imm -> swap(imm)
//
void FoldByteReverse(IR::Inst& inst, IR::Opcode op) {
const auto operand = inst.GetArg(0);
if (!operand.IsImmediate()) {
return;
}
if (op == IR::Opcode::ByteReverseWord) {
const u32 result = Common::Swap32(static_cast<u32>(operand.GetImmediateAsU64()));
inst.ReplaceUsesWith(IR::Value{result});
} else if (op == IR::Opcode::ByteReverseHalf) {
const u16 result = Common::Swap16(static_cast<u16>(operand.GetImmediateAsU64()));
inst.ReplaceUsesWith(IR::Value{result});
} else {
const u64 result = Common::Swap64(operand.GetImmediateAsU64());
inst.ReplaceUsesWith(IR::Value{result});
}
}
// Folds division operations based on the following: // Folds division operations based on the following:
// //
// 1. x / 0 -> 0 (NOTE: This is an ARM-specific behavior defined in the architecture reference manual) // 1. x / 0 -> 0 (NOTE: This is an ARM-specific behavior defined in the architecture reference manual)
@ -332,6 +356,11 @@ void ConstantPropagation(IR::Block& block) {
case IR::Opcode::ZeroExtendWordToLong: case IR::Opcode::ZeroExtendWordToLong:
FoldZeroExtendXToLong(inst); FoldZeroExtendXToLong(inst);
break; break;
case IR::Opcode::ByteReverseWord:
case IR::Opcode::ByteReverseHalf:
case IR::Opcode::ByteReverseDual:
FoldByteReverse(inst, opcode);
break;
default: default:
break; break;
} }