a32_get_set_elimination_pass: Reduce NZC to 00C
This commit is contained in:
parent
03dcc3fa50
commit
b97147e187
4 changed files with 35 additions and 11 deletions
|
@ -555,6 +555,17 @@ void A32EmitX64::EmitA32SetCpsrNZ(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
if (args[0].IsImmediate()) {
|
||||||
|
if (args[1].IsImmediate()) {
|
||||||
|
const bool c = args[1].GetImmediateU1();
|
||||||
|
|
||||||
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], c);
|
||||||
|
} else {
|
||||||
|
const Xbyak::Reg8 c = ctx.reg_alloc.UseGpr(args[1]).cvt8();
|
||||||
|
|
||||||
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], c);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ctx.reg_alloc.Use(args[0], HostLoc::RAX);
|
ctx.reg_alloc.Use(args[0], HostLoc::RAX);
|
||||||
|
|
||||||
if (args[1].IsImmediate()) {
|
if (args[1].IsImmediate()) {
|
||||||
|
@ -571,6 +582,7 @@ void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al);
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void EmitGetFlag(BlockOfCode& code, A32EmitContext& ctx, IR::Inst* inst, size_t flag_bit) {
|
static void EmitGetFlag(BlockOfCode& code, A32EmitContext& ctx, IR::Inst* inst, size_t flag_bit) {
|
||||||
const Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
|
const Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
|
||||||
|
|
|
@ -204,8 +204,12 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR::Opcode::A32SetCpsrNZ: {
|
case IR::Opcode::A32SetCpsrNZ: {
|
||||||
|
if (cpsr_info.nzc.set_instruction_present) {
|
||||||
|
cpsr_info.nzc.last_set_instruction->SetArg(0, IR::Value::EmptyNZCVImmediateMarker());
|
||||||
|
}
|
||||||
|
|
||||||
// cpsr_info.c remains valid
|
// cpsr_info.c remains valid
|
||||||
cpsr_info.nzc = {}; // TODO: Consider reduction of previous to a SetCFlag operation
|
cpsr_info.nzc = {};
|
||||||
cpsr_info.nzcv = {};
|
cpsr_info.nzcv = {};
|
||||||
do_set(cpsr_info.nz, inst->GetArg(0), inst);
|
do_set(cpsr_info.nz, inst->GetArg(0), inst);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -79,6 +79,12 @@ Value::Value(AccType value)
|
||||||
inner.imm_acctype = value;
|
inner.imm_acctype = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value Value::EmptyNZCVImmediateMarker() {
|
||||||
|
Value result{};
|
||||||
|
result.type = Type::NZCVFlags;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool Value::IsIdentity() const {
|
bool Value::IsIdentity() const {
|
||||||
if (type == Type::Opaque)
|
if (type == Type::Opaque)
|
||||||
return inner.inst->GetOpcode() == Opcode::Identity;
|
return inner.inst->GetOpcode() == Opcode::Identity;
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
explicit Value(Cond value);
|
explicit Value(Cond value);
|
||||||
explicit Value(AccType value);
|
explicit Value(AccType value);
|
||||||
|
|
||||||
|
static Value EmptyNZCVImmediateMarker();
|
||||||
|
|
||||||
bool IsIdentity() const;
|
bool IsIdentity() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
bool IsImmediate() const;
|
bool IsImmediate() const;
|
||||||
|
|
Loading…
Reference in a new issue