From 6f643b23524c9bb3072e9974588ef32c616e89a8 Mon Sep 17 00:00:00 2001 From: SachinVin Date: Sun, 3 Nov 2019 08:52:09 +0530 Subject: [PATCH] IR + backend/*: add SetCpsrNZCVRaw and change arg1 type of SetCpsrNZCV to IR::NZCV --- src/backend/A64/a32_emit_a64.cpp | 6 +++++- src/backend/A64/opcodes.inc | 3 ++- src/backend/x64/a32_emit_x64.cpp | 13 ++++++++++++- src/frontend/A32/ir_emitter.cpp | 4 ++++ src/frontend/A32/ir_emitter.h | 1 + src/frontend/ir/microinstruction.cpp | 1 + src/frontend/ir/opcodes.inc | 3 ++- 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/backend/A64/a32_emit_a64.cpp b/src/backend/A64/a32_emit_a64.cpp index a5a429d6..d1b86191 100644 --- a/src/backend/A64/a32_emit_a64.cpp +++ b/src/backend/A64/a32_emit_a64.cpp @@ -424,7 +424,7 @@ void A32EmitA64::EmitA32SetCpsr(A32EmitContext& ctx, IR::Inst* inst) { code.QuickCallFunction(&SetCpsrImpl); } -void A32EmitA64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { +void A32EmitA64::EmitA32SetCpsrNZCVRaw(A32EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ARM64Reg a = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); @@ -432,6 +432,10 @@ void A32EmitA64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { code.STR(INDEX_UNSIGNED, a, X28, offsetof(A32JitState, CPSR_nzcv)); } +void A32EmitA64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { + EmitA32SetCpsrNZCVRaw(ctx, inst); +} + void A32EmitA64::EmitA32SetCpsrNZCVQ(A32EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ARM64Reg host_fpsr = ctx.reg_alloc.ScratchGpr(); diff --git a/src/backend/A64/opcodes.inc b/src/backend/A64/opcodes.inc index cfb262df..8c1c72ca 100644 --- a/src/backend/A64/opcodes.inc +++ b/src/backend/A64/opcodes.inc @@ -14,7 +14,8 @@ A32OPC(SetExtendedRegister32, Void, A32E A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 ) A32OPC(GetCpsr, U32, ) A32OPC(SetCpsr, Void, U32 ) -A32OPC(SetCpsrNZCV, Void, U32 ) +A32OPC(SetCpsrNZCVRaw, Void, U32 ) +A32OPC(SetCpsrNZCV, Void, NZCV ) A32OPC(SetCpsrNZCVQ, Void, U32 ) A32OPC(GetNFlag, U1, ) A32OPC(SetNFlag, Void, U1 ) diff --git a/src/backend/x64/a32_emit_x64.cpp b/src/backend/x64/a32_emit_x64.cpp index 6010a798..e234e2b0 100644 --- a/src/backend/x64/a32_emit_x64.cpp +++ b/src/backend/x64/a32_emit_x64.cpp @@ -479,7 +479,7 @@ void A32EmitX64::EmitA32SetCpsr(A32EmitContext& ctx, IR::Inst* inst) { } } -void A32EmitX64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { +void A32EmitX64::EmitA32SetCpsrNZCVRaw(A32EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { const u32 imm = args[0].GetImmediateU32(); @@ -503,6 +503,17 @@ void A32EmitX64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { } } +void A32EmitX64::EmitA32SetCpsrNZCV(A32EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + const Xbyak::Reg32 to_store = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); + code.and_(to_store, 0b11000001'00000001); + code.imul(to_store, to_store, 0b00010000'00100001); + code.shl(to_store, 16); + code.and_(to_store, 0xF0000000); + code.mov(dword[r15 + offsetof(A32JitState, cpsr_nzcv)], to_store); +} + + void A32EmitX64::EmitA32SetCpsrNZCVQ(A32EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { diff --git a/src/frontend/A32/ir_emitter.cpp b/src/frontend/A32/ir_emitter.cpp index 83ddff34..64c892c0 100644 --- a/src/frontend/A32/ir_emitter.cpp +++ b/src/frontend/A32/ir_emitter.cpp @@ -99,6 +99,10 @@ void IREmitter::SetCpsr(const IR::U32& value) { } void IREmitter::SetCpsrNZCV(const IR::U32& value) { + Inst(Opcode::A32SetCpsrNZCVRaw, value); +} + +void IREmitter::SetCpsrNZCV(const IR::NZCV& value) { Inst(Opcode::A32SetCpsrNZCV, value); } diff --git a/src/frontend/A32/ir_emitter.h b/src/frontend/A32/ir_emitter.h index ff625842..cf1dc901 100644 --- a/src/frontend/A32/ir_emitter.h +++ b/src/frontend/A32/ir_emitter.h @@ -47,6 +47,7 @@ public: IR::U32 GetCpsr(); void SetCpsr(const IR::U32& value); void SetCpsrNZCV(const IR::U32& value); + void SetCpsrNZCV(const IR::NZCV& value); void SetCpsrNZCVQ(const IR::U32& value); void SetCheckBit(const IR::U1& value); IR::U1 GetCFlag(); diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index 7aa002b0..2d8e20cb 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -166,6 +166,7 @@ bool Inst::ReadsFromCPSR() const { bool Inst::WritesToCPSR() const { switch (op) { case Opcode::A32SetCpsr: + case Opcode::A32SetCpsrNZCVRaw: case Opcode::A32SetCpsrNZCV: case Opcode::A32SetCpsrNZCVQ: case Opcode::A32SetNFlag: diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 4a5ca362..01c9db26 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -14,7 +14,8 @@ A32OPC(SetExtendedRegister32, Void, A32E A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 ) A32OPC(GetCpsr, U32, ) A32OPC(SetCpsr, Void, U32 ) -A32OPC(SetCpsrNZCV, Void, U32 ) +A32OPC(SetCpsrNZCVRaw, Void, U32 ) +A32OPC(SetCpsrNZCV, Void, NZCV ) A32OPC(SetCpsrNZCVQ, Void, U32 ) A32OPC(GetNFlag, U1, ) A32OPC(SetNFlag, Void, U1 )