backend/x64: Fixup NZ flag emission
This commit is contained in:
parent
b97147e187
commit
52aa68c31c
2 changed files with 15 additions and 13 deletions
|
@ -544,12 +544,13 @@ void A32EmitX64::EmitA32SetCpsrNZCVQ(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
void A32EmitX64::EmitA32SetCpsrNZ(A32EmitContext& ctx, IR::Inst* inst) {
|
void A32EmitX64::EmitA32SetCpsrNZ(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
ctx.reg_alloc.Use(args[0], HostLoc::RAX);
|
const Xbyak::Reg32 nz = ctx.reg_alloc.UseGpr(args[0]).cvt32();
|
||||||
|
const Xbyak::Reg32 tmp = ctx.reg_alloc.ScratchGpr().cvt32();
|
||||||
|
|
||||||
code.mov(al, code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1]);
|
code.movzx(tmp, code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1]);
|
||||||
code.and_(al, 1);
|
code.and_(tmp, 1);
|
||||||
code.or_(al, ah);
|
code.or_(tmp, nz);
|
||||||
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al);
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], tmp.cvt8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
@ -566,20 +567,18 @@ void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], c);
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.reg_alloc.Use(args[0], HostLoc::RAX);
|
const Xbyak::Reg32 nz = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32();
|
||||||
|
|
||||||
if (args[1].IsImmediate()) {
|
if (args[1].IsImmediate()) {
|
||||||
const bool c = args[1].GetImmediateU1();
|
const bool c = args[1].GetImmediateU1();
|
||||||
|
|
||||||
code.mov(al, ah);
|
code.or_(nz, c);
|
||||||
code.or_(al, c);
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], nz.cvt8());
|
||||||
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al);
|
|
||||||
} else {
|
} else {
|
||||||
const Xbyak::Reg8 c = ctx.reg_alloc.UseGpr(args[1]).cvt8();
|
const Xbyak::Reg32 c = ctx.reg_alloc.UseGpr(args[1]).cvt32();
|
||||||
|
|
||||||
code.mov(al, ah);
|
code.or_(nz, c);
|
||||||
code.or_(al, c);
|
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], nz.cvt8());
|
||||||
code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,9 @@ void EmitX64::EmitGetNZFromOp(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[0]).changeBit(bitsize);
|
const Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[0]).changeBit(bitsize);
|
||||||
code.cmp(value, 0);
|
code.cmp(value, 0);
|
||||||
code.lahf();
|
code.lahf();
|
||||||
|
code.db(0x0f);
|
||||||
|
code.db(0xb6);
|
||||||
|
code.db(0xc4);
|
||||||
ctx.reg_alloc.DefineValue(inst, nz);
|
ctx.reg_alloc.DefineValue(inst, nz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue