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:
parent
79d51f8d4a
commit
70a392af9e
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user