constant_propagation_pass: Fold byte reversal opcodes where applicable

These are reasonably trivial to fold away when applicable. We just
perform the swap and replace the instruction with the constant value.
This commit is contained in:
Lioncash 2018-11-24 10:32:10 -05:00
parent 79d51f8d4a
commit 70a392af9e
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -6,6 +6,7 @@
#include <dynarmic/A32/config.h>
#include "common/bit_util.h"
#include "frontend/ir/basic_block.h"
#include "frontend/ir/opcodes.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:
//
// 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:
FoldZeroExtendXToLong(inst);
break;
case IR::Opcode::ByteReverseWord:
case IR::Opcode::ByteReverseHalf:
case IR::Opcode::ByteReverseDual:
FoldByteReverse(inst, opcode);
break;
default:
break;
}