From 8bef20c24de5b4ca92e2276c7aebed17f6c68d50 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 1 Jan 2018 16:19:43 +0000 Subject: [PATCH] IR: Split off A32 specific opcodes --- src/backend_x64/emit_x64.cpp | 107 +++++++++++----------- src/backend_x64/emit_x64.h | 2 + src/frontend/A32/ir_emitter.cpp | 112 +++++++++++------------ src/frontend/A32/ir_emitter.h | 1 - src/frontend/ir/ir_emitter.cpp | 4 + src/frontend/ir/ir_emitter.h | 2 + src/frontend/ir/microinstruction.cpp | 98 ++++++++++---------- src/frontend/ir/opcodes.cpp | 2 + src/frontend/ir/opcodes.h | 2 + src/frontend/ir/opcodes.inc | 100 ++++++++++---------- src/ir_opt/constant_propagation_pass.cpp | 12 +-- src/ir_opt/get_set_elimination_pass.cpp | 32 +++---- 12 files changed, 243 insertions(+), 231 deletions(-) diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index a62ce569..61ece6f6 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -84,12 +84,17 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) { // Call the relevant Emit* member function. switch (inst->GetOpcode()) { -#define OPCODE(name, type, ...) \ - case IR::Opcode::name: \ +#define OPCODE(name, type, ...) \ + case IR::Opcode::name: \ A32EmitX64::Emit##name(reg_alloc, block, inst); \ break; +#define A32OPC(name, type, ...) \ + case IR::Opcode::A32##name: \ + A32EmitX64::EmitA32##name(reg_alloc, block, inst); \ + break; #include "frontend/ir/opcodes.inc" #undef OPCODE +#undef A32OPC default: ASSERT_MSG(false, "Invalid opcode %zu", static_cast(inst->GetOpcode())); @@ -139,7 +144,7 @@ void A32EmitX64::EmitIdentity(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitGetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { A32::Reg reg = inst->GetArg(0).GetA32RegRef(); Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); @@ -147,7 +152,7 @@ void A32EmitX64::EmitGetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitGetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); ASSERT(A32::IsSingleExtReg(reg)); @@ -156,7 +161,7 @@ void A32EmitX64::EmitGetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR:: reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitGetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); ASSERT(A32::IsDoubleExtReg(reg)); @@ -165,7 +170,7 @@ void A32EmitX64::EmitGetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR:: reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); A32::Reg reg = inst->GetArg(0).GetA32RegRef(); if (args[1].IsImmediate()) { @@ -179,7 +184,7 @@ void A32EmitX64::EmitSetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst } } -void A32EmitX64::EmitSetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); ASSERT(A32::IsSingleExtReg(reg)); @@ -192,7 +197,7 @@ void A32EmitX64::EmitSetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR:: } } -void A32EmitX64::EmitSetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); ASSERT(A32::IsDoubleExtReg(reg)); @@ -209,7 +214,7 @@ static u32 GetCpsrImpl(JitState* jit_state) { return jit_state->Cpsr(); } -void A32EmitX64::EmitGetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { if (code->DoesCpuSupport(Xbyak::util::Cpu::tBMI2)) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 b = reg_alloc.ScratchGpr().cvt32(); @@ -245,14 +250,14 @@ static void SetCpsrImpl(u32 value, JitState* jit_state) { jit_state->SetCpsr(value); } -void A32EmitX64::EmitSetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.HostCall(nullptr, args[0]); code->mov(code->ABI_PARAM2, code->r15); code->CallFunction(&SetCpsrImpl); } -void A32EmitX64::EmitSetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -266,7 +271,7 @@ void A32EmitX64::EmitSetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst } } -void A32EmitX64::EmitSetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -283,14 +288,14 @@ void A32EmitX64::EmitSetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* ins } } -void A32EmitX64::EmitGetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 31); reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 31; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -309,7 +314,7 @@ void A32EmitX64::EmitSetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitGetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 30); @@ -317,7 +322,7 @@ void A32EmitX64::EmitGetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 30; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -336,7 +341,7 @@ void A32EmitX64::EmitSetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitGetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 29); @@ -344,7 +349,7 @@ void A32EmitX64::EmitGetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 29; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -363,7 +368,7 @@ void A32EmitX64::EmitSetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitGetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 28); @@ -371,7 +376,7 @@ void A32EmitX64::EmitGetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 28; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -390,7 +395,7 @@ void A32EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32OrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) @@ -402,13 +407,13 @@ void A32EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void A32EmitX64::EmitGetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Xmm result = reg_alloc.ScratchXmm(); code->movd(result, dword[r15 + offsetof(JitState, CPSR_ge)]); reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); ASSERT(!args[0].IsImmediate()); @@ -421,7 +426,7 @@ void A32EmitX64::EmitSetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) } } -void A32EmitX64::EmitSetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -453,7 +458,7 @@ void A32EmitX64::EmitSetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::I } } -void A32EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitA32BXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto& arg = args[0]; @@ -503,7 +508,7 @@ void A32EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* } } -void A32EmitX64::EmitCallSupervisor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CallSupervisor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.HostCall(nullptr); code->SwitchMxcsrOnExit(); @@ -524,7 +529,7 @@ static u32 GetFpscrImpl(JitState* jit_state) { return jit_state->Fpscr(); } -void A32EmitX64::EmitGetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.HostCall(inst); code->mov(code->ABI_PARAM1, code->r15); @@ -536,7 +541,7 @@ static void SetFpscrImpl(u32 value, JitState* jit_state) { jit_state->SetFpscr(value); } -void A32EmitX64::EmitSetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.HostCall(nullptr, args[0]); code->mov(code->ABI_PARAM2, code->r15); @@ -545,13 +550,13 @@ void A32EmitX64::EmitSetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { code->ldmxcsr(code->dword[code->r15 + offsetof(JitState, guest_MXCSR)]); } -void A32EmitX64::EmitGetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32GetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, FPSCR_nzcv)]); reg_alloc.DefineValue(inst, result); } -void A32EmitX64::EmitSetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 value = reg_alloc.UseGpr(args[0]).cvt32(); @@ -2833,11 +2838,11 @@ void A32EmitX64::EmitFPU32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* in } -void A32EmitX64::EmitClearExclusive(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitA32ClearExclusive(RegAlloc&, IR::Block&, IR::Inst*) { code->mov(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(0)); } -void A32EmitX64::EmitSetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32SetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); ASSERT(args[1].IsImmediate()); Xbyak::Reg32 address = reg_alloc.UseGpr(args[0]).cvt32(); @@ -2952,35 +2957,35 @@ static void WriteMemory(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, code->L(end); } -void A32EmitX64::EmitReadMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ReadMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 8, cb.memory.Read8); } -void A32EmitX64::EmitReadMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ReadMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 16, cb.memory.Read16); } -void A32EmitX64::EmitReadMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ReadMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 32, cb.memory.Read32); } -void A32EmitX64::EmitReadMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ReadMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 64, cb.memory.Read64); } -void A32EmitX64::EmitWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32WriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 8, cb.memory.Write8); } -void A32EmitX64::EmitWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32WriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 16, cb.memory.Write16); } -void A32EmitX64::EmitWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32WriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 32, cb.memory.Write32); } -void A32EmitX64::EmitWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32WriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 64, cb.memory.Write64); } @@ -3017,19 +3022,19 @@ static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* ins reg_alloc.DefineValue(inst, passed); } -void A32EmitX64::EmitExclusiveWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ExclusiveWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write8, false); } -void A32EmitX64::EmitExclusiveWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ExclusiveWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write16, false); } -void A32EmitX64::EmitExclusiveWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ExclusiveWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write32, false); } -void A32EmitX64::EmitExclusiveWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32ExclusiveWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write64, true); } @@ -3048,7 +3053,7 @@ static void CallCoprocCallback(BlockOfCode* code, RegAlloc& reg_alloc, Jit* jit_ code->CallFunction(callback.function); } -void A32EmitX64::EmitCoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; @@ -3074,7 +3079,7 @@ void A32EmitX64::EmitCoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR CallCoprocCallback(code, reg_alloc, jit_interface, *action); } -void A32EmitX64::EmitCoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); @@ -3115,7 +3120,7 @@ void A32EmitX64::EmitCoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst } } -void A32EmitX64::EmitCoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); @@ -3157,7 +3162,7 @@ void A32EmitX64::EmitCoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Ins } } -void A32EmitX64::EmitCoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; @@ -3199,7 +3204,7 @@ void A32EmitX64::EmitCoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* } } -void A32EmitX64::EmitCoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; @@ -3244,7 +3249,7 @@ void A32EmitX64::EmitCoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst } } -void A32EmitX64::EmitCoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); @@ -3270,7 +3275,7 @@ void A32EmitX64::EmitCoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* CallCoprocCallback(code, reg_alloc, jit_interface, *action, nullptr, args[1]); } -void A32EmitX64::EmitCoprocStoreWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitA32CoprocStoreWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); diff --git a/src/backend_x64/emit_x64.h b/src/backend_x64/emit_x64.h index 5654c3e2..75f9727e 100644 --- a/src/backend_x64/emit_x64.h +++ b/src/backend_x64/emit_x64.h @@ -67,8 +67,10 @@ public: private: // Microinstruction emitters #define OPCODE(name, type, ...) void Emit##name(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst); +#define A32OPC(name, type, ...) void EmitA32##name(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst); #include "frontend/ir/opcodes.inc" #undef OPCODE +#undef A32OPC // Helpers void EmitAddCycles(size_t cycles); diff --git a/src/frontend/A32/ir_emitter.cpp b/src/frontend/A32/ir_emitter.cpp index 8cfd2e50..28b6a3ec 100644 --- a/src/frontend/A32/ir_emitter.cpp +++ b/src/frontend/A32/ir_emitter.cpp @@ -27,16 +27,16 @@ IR::Value IREmitter::GetRegister(A32::Reg reg) { if (reg == A32::Reg::PC) { return Imm32(PC()); } - return Inst(Opcode::GetRegister, { IR::Value(reg) }); + return Inst(Opcode::A32GetRegister, { IR::Value(reg) }); } IR::Value IREmitter::GetExtendedRegister(A32::ExtReg reg) { if (A32::IsSingleExtReg(reg)) { - return Inst(Opcode::GetExtendedRegister32, {IR::Value(reg)}); + return Inst(Opcode::A32GetExtendedRegister32, {IR::Value(reg)}); } if (A32::IsDoubleExtReg(reg)) { - return Inst(Opcode::GetExtendedRegister64, {IR::Value(reg)}); + return Inst(Opcode::A32GetExtendedRegister64, {IR::Value(reg)}); } ASSERT_MSG(false, "Invalid reg."); @@ -44,14 +44,14 @@ IR::Value IREmitter::GetExtendedRegister(A32::ExtReg reg) { void IREmitter::SetRegister(const A32::Reg reg, const IR::Value& value) { ASSERT(reg != A32::Reg::PC); - Inst(Opcode::SetRegister, { IR::Value(reg), value }); + Inst(Opcode::A32SetRegister, { IR::Value(reg), value }); } void IREmitter::SetExtendedRegister(const A32::ExtReg reg, const IR::Value& value) { if (A32::IsSingleExtReg(reg)) { - Inst(Opcode::SetExtendedRegister32, {IR::Value(reg), value}); + Inst(Opcode::A32SetExtendedRegister32, {IR::Value(reg), value}); } else if (A32::IsDoubleExtReg(reg)) { - Inst(Opcode::SetExtendedRegister64, {IR::Value(reg), value}); + Inst(Opcode::A32SetExtendedRegister64, {IR::Value(reg), value}); } else { ASSERT_MSG(false, "Invalid reg."); } @@ -66,15 +66,15 @@ void IREmitter::ALUWritePC(const IR::Value& value) { void IREmitter::BranchWritePC(const IR::Value& value) { if (!current_location.TFlag()) { auto new_pc = And(value, Imm32(0xFFFFFFFC)); - Inst(Opcode::SetRegister, { IR::Value(A32::Reg::PC), new_pc }); + Inst(Opcode::A32SetRegister, { IR::Value(A32::Reg::PC), new_pc }); } else { auto new_pc = And(value, Imm32(0xFFFFFFFE)); - Inst(Opcode::SetRegister, { IR::Value(A32::Reg::PC), new_pc }); + Inst(Opcode::A32SetRegister, { IR::Value(A32::Reg::PC), new_pc }); } } void IREmitter::BXWritePC(const IR::Value& value) { - Inst(Opcode::BXWritePC, {value}); + Inst(Opcode::A32BXWritePC, {value}); } void IREmitter::LoadWritePC(const IR::Value& value) { @@ -84,159 +84,155 @@ void IREmitter::LoadWritePC(const IR::Value& value) { } void IREmitter::CallSupervisor(const IR::Value& value) { - Inst(Opcode::CallSupervisor, {value}); -} - -void IREmitter::PushRSB(const A32::LocationDescriptor& return_location) { - Inst(Opcode::PushRSB, {IR::Value(return_location.UniqueHash())}); + Inst(Opcode::A32CallSupervisor, {value}); } IR::Value IREmitter::GetCpsr() { - return Inst(Opcode::GetCpsr, {}); + return Inst(Opcode::A32GetCpsr, {}); } void IREmitter::SetCpsr(const IR::Value& value) { - Inst(Opcode::SetCpsr, {value}); + Inst(Opcode::A32SetCpsr, {value}); } void IREmitter::SetCpsrNZCV(const IR::Value& value) { - Inst(Opcode::SetCpsrNZCV, {value}); + Inst(Opcode::A32SetCpsrNZCV, {value}); } void IREmitter::SetCpsrNZCVQ(const IR::Value& value) { - Inst(Opcode::SetCpsrNZCVQ, {value}); + Inst(Opcode::A32SetCpsrNZCVQ, {value}); } IR::Value IREmitter::GetCFlag() { - return Inst(Opcode::GetCFlag, {}); + return Inst(Opcode::A32GetCFlag, {}); } void IREmitter::SetNFlag(const IR::Value& value) { - Inst(Opcode::SetNFlag, {value}); + Inst(Opcode::A32SetNFlag, {value}); } void IREmitter::SetZFlag(const IR::Value& value) { - Inst(Opcode::SetZFlag, {value}); + Inst(Opcode::A32SetZFlag, {value}); } void IREmitter::SetCFlag(const IR::Value& value) { - Inst(Opcode::SetCFlag, {value}); + Inst(Opcode::A32SetCFlag, {value}); } void IREmitter::SetVFlag(const IR::Value& value) { - Inst(Opcode::SetVFlag, {value}); + Inst(Opcode::A32SetVFlag, {value}); } void IREmitter::OrQFlag(const IR::Value& value) { - Inst(Opcode::OrQFlag, {value}); + Inst(Opcode::A32OrQFlag, {value}); } IR::Value IREmitter::GetGEFlags() { - return Inst(Opcode::GetGEFlags, {}); + return Inst(Opcode::A32GetGEFlags, {}); } void IREmitter::SetGEFlags(const IR::Value& value) { - Inst(Opcode::SetGEFlags, {value}); + Inst(Opcode::A32SetGEFlags, {value}); } void IREmitter::SetGEFlagsCompressed(const IR::Value& value) { - Inst(Opcode::SetGEFlagsCompressed, {value}); + Inst(Opcode::A32SetGEFlagsCompressed, {value}); } IR::Value IREmitter::GetFpscr() { - return Inst(Opcode::GetFpscr, {}); + return Inst(Opcode::A32GetFpscr, {}); } void IREmitter::SetFpscr(const IR::Value& new_fpscr) { - Inst(Opcode::SetFpscr, {new_fpscr}); + Inst(Opcode::A32SetFpscr, {new_fpscr}); } IR::Value IREmitter::GetFpscrNZCV() { - return Inst(Opcode::GetFpscrNZCV, {}); + return Inst(Opcode::A32GetFpscrNZCV, {}); } void IREmitter::SetFpscrNZCV(const IR::Value& new_fpscr_nzcv) { - Inst(Opcode::SetFpscrNZCV, {new_fpscr_nzcv}); + Inst(Opcode::A32SetFpscrNZCV, {new_fpscr_nzcv}); } void IREmitter::ClearExclusive() { - Inst(Opcode::ClearExclusive, {}); + Inst(Opcode::A32ClearExclusive, {}); } void IREmitter::SetExclusive(const IR::Value& vaddr, size_t byte_size) { ASSERT(byte_size == 1 || byte_size == 2 || byte_size == 4 || byte_size == 8 || byte_size == 16); - Inst(Opcode::SetExclusive, {vaddr, Imm8(u8(byte_size))}); + Inst(Opcode::A32SetExclusive, {vaddr, Imm8(u8(byte_size))}); } IR::Value IREmitter::ReadMemory8(const IR::Value& vaddr) { - return Inst(Opcode::ReadMemory8, {vaddr}); + return Inst(Opcode::A32ReadMemory8, {vaddr}); } IR::Value IREmitter::ReadMemory16(const IR::Value& vaddr) { - auto value = Inst(Opcode::ReadMemory16, {vaddr}); + auto value = Inst(Opcode::A32ReadMemory16, {vaddr}); return current_location.EFlag() ? ByteReverseHalf(value) : value; } IR::Value IREmitter::ReadMemory32(const IR::Value& vaddr) { - auto value = Inst(Opcode::ReadMemory32, {vaddr}); + auto value = Inst(Opcode::A32ReadMemory32, {vaddr}); return current_location.EFlag() ? ByteReverseWord(value) : value; } IR::Value IREmitter::ReadMemory64(const IR::Value& vaddr) { - auto value = Inst(Opcode::ReadMemory64, {vaddr}); + auto value = Inst(Opcode::A32ReadMemory64, {vaddr}); return current_location.EFlag() ? ByteReverseDual(value) : value; } void IREmitter::WriteMemory8(const IR::Value& vaddr, const IR::Value& value) { - Inst(Opcode::WriteMemory8, {vaddr, value}); + Inst(Opcode::A32WriteMemory8, {vaddr, value}); } void IREmitter::WriteMemory16(const IR::Value& vaddr, const IR::Value& value) { if (current_location.EFlag()) { auto v = ByteReverseHalf(value); - Inst(Opcode::WriteMemory16, {vaddr, v}); + Inst(Opcode::A32WriteMemory16, {vaddr, v}); } else { - Inst(Opcode::WriteMemory16, {vaddr, value}); + Inst(Opcode::A32WriteMemory16, {vaddr, value}); } } void IREmitter::WriteMemory32(const IR::Value& vaddr, const IR::Value& value) { if (current_location.EFlag()) { auto v = ByteReverseWord(value); - Inst(Opcode::WriteMemory32, {vaddr, v}); + Inst(Opcode::A32WriteMemory32, {vaddr, v}); } else { - Inst(Opcode::WriteMemory32, {vaddr, value}); + Inst(Opcode::A32WriteMemory32, {vaddr, value}); } } void IREmitter::WriteMemory64(const IR::Value& vaddr, const IR::Value& value) { if (current_location.EFlag()) { auto v = ByteReverseDual(value); - Inst(Opcode::WriteMemory64, {vaddr, v}); + Inst(Opcode::A32WriteMemory64, {vaddr, v}); } else { - Inst(Opcode::WriteMemory64, {vaddr, value}); + Inst(Opcode::A32WriteMemory64, {vaddr, value}); } } IR::Value IREmitter::ExclusiveWriteMemory8(const IR::Value& vaddr, const IR::Value& value) { - return Inst(Opcode::ExclusiveWriteMemory8, {vaddr, value}); + return Inst(Opcode::A32ExclusiveWriteMemory8, {vaddr, value}); } IR::Value IREmitter::ExclusiveWriteMemory16(const IR::Value& vaddr, const IR::Value& value) { if (current_location.EFlag()) { auto v = ByteReverseHalf(value); - return Inst(Opcode::ExclusiveWriteMemory16, {vaddr, v}); + return Inst(Opcode::A32ExclusiveWriteMemory16, {vaddr, v}); } else { - return Inst(Opcode::ExclusiveWriteMemory16, {vaddr, value}); + return Inst(Opcode::A32ExclusiveWriteMemory16, {vaddr, value}); } } IR::Value IREmitter::ExclusiveWriteMemory32(const IR::Value& vaddr, const IR::Value& value) { if (current_location.EFlag()) { auto v = ByteReverseWord(value); - return Inst(Opcode::ExclusiveWriteMemory32, {vaddr, v}); + return Inst(Opcode::A32ExclusiveWriteMemory32, {vaddr, v}); } else { - return Inst(Opcode::ExclusiveWriteMemory32, {vaddr, value}); + return Inst(Opcode::A32ExclusiveWriteMemory32, {vaddr, value}); } } @@ -244,9 +240,9 @@ IR::Value IREmitter::ExclusiveWriteMemory64(const IR::Value& vaddr, const IR::Va if (current_location.EFlag()) { auto vlo = ByteReverseWord(value_lo); auto vhi = ByteReverseWord(value_hi); - return Inst(Opcode::ExclusiveWriteMemory64, {vaddr, vlo, vhi}); + return Inst(Opcode::A32ExclusiveWriteMemory64, {vaddr, vlo, vhi}); } else { - return Inst(Opcode::ExclusiveWriteMemory64, {vaddr, value_lo, value_hi}); + return Inst(Opcode::A32ExclusiveWriteMemory64, {vaddr, value_lo, value_hi}); } } @@ -259,7 +255,7 @@ void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, static_cast(CRn), static_cast(CRm), static_cast(opc2)}; - Inst(Opcode::CoprocInternalOperation, {IR::Value(coproc_info)}); + Inst(Opcode::A32CoprocInternalOperation, {IR::Value(coproc_info)}); } void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2, const IR::Value& word) { @@ -270,7 +266,7 @@ void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32:: static_cast(CRn), static_cast(CRm), static_cast(opc2)}; - Inst(Opcode::CoprocSendOneWord, {IR::Value(coproc_info), word}); + Inst(Opcode::A32CoprocSendOneWord, {IR::Value(coproc_info), word}); } void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm, const IR::Value& word1, const IR::Value& word2) { @@ -279,7 +275,7 @@ void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32:: static_cast(two ? 1 : 0), static_cast(opc), static_cast(CRm)}; - Inst(Opcode::CoprocSendTwoWords, {IR::Value(coproc_info), word1, word2}); + Inst(Opcode::A32CoprocSendTwoWords, {IR::Value(coproc_info), word1, word2}); } IR::Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2) { @@ -290,7 +286,7 @@ IR::Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A static_cast(CRn), static_cast(CRm), static_cast(opc2)}; - return Inst(Opcode::CoprocGetOneWord, {IR::Value(coproc_info)}); + return Inst(Opcode::A32CoprocGetOneWord, {IR::Value(coproc_info)}); } IR::Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm) { @@ -299,7 +295,7 @@ IR::Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A static_cast(two ? 1 : 0), static_cast(opc), static_cast(CRm)}; - return Inst(Opcode::CoprocGetTwoWords, {IR::Value(coproc_info)}); + return Inst(Opcode::A32CoprocGetTwoWords, {IR::Value(coproc_info)}); } void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const IR::Value& address, bool has_option, u8 option) { @@ -310,7 +306,7 @@ void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, static_cast(CRd), static_cast(has_option ? 1 : 0), static_cast(option)}; - Inst(Opcode::CoprocLoadWords, {IR::Value(coproc_info), address}); + Inst(Opcode::A32CoprocLoadWords, {IR::Value(coproc_info), address}); } void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const IR::Value& address, bool has_option, u8 option) { @@ -321,7 +317,7 @@ void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, static_cast(CRd), static_cast(has_option ? 1 : 0), static_cast(option)}; - Inst(Opcode::CoprocStoreWords, {IR::Value(coproc_info), address}); + Inst(Opcode::A32CoprocStoreWords, {IR::Value(coproc_info), address}); } } // namespace IR diff --git a/src/frontend/A32/ir_emitter.h b/src/frontend/A32/ir_emitter.h index f6cf1393..5ee83099 100644 --- a/src/frontend/A32/ir_emitter.h +++ b/src/frontend/A32/ir_emitter.h @@ -43,7 +43,6 @@ public: void BXWritePC(const IR::Value& value); void LoadWritePC(const IR::Value& value); void CallSupervisor(const IR::Value& value); - void PushRSB(const A32::LocationDescriptor& return_location); IR::Value GetCpsr(); void SetCpsr(const IR::Value& value); diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 126fe5cb..7921f940 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -31,6 +31,10 @@ Value IREmitter::Imm64(u64 imm64) { return Value(imm64); } +void IREmitter::PushRSB(const LocationDescriptor& return_location) { + Inst(Opcode::PushRSB, {IR::Value(return_location.Value())}); +} + Value IREmitter::Pack2x32To1x64(const Value& lo, const Value& hi) { return Inst(Opcode::Pack2x32To1x64, {lo, hi}); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index b0d65f36..2d451483 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -67,6 +67,8 @@ public: Value Imm32(u32 value); Value Imm64(u64 value); + void PushRSB(const LocationDescriptor& return_location); + Value Pack2x32To1x64(const Value& lo, const Value& hi); Value LeastSignificantWord(const Value& value); ResultAndCarry MostSignificantWord(const Value& value); diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index 9882752a..dd92687c 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -41,10 +41,10 @@ bool Inst::IsShift() const { bool Inst::IsSharedMemoryRead() const { switch (op) { - case Opcode::ReadMemory8: - case Opcode::ReadMemory16: - case Opcode::ReadMemory32: - case Opcode::ReadMemory64: + case Opcode::A32ReadMemory8: + case Opcode::A32ReadMemory16: + case Opcode::A32ReadMemory32: + case Opcode::A32ReadMemory64: return true; default: @@ -54,10 +54,10 @@ bool Inst::IsSharedMemoryRead() const { bool Inst::IsSharedMemoryWrite() const { switch (op) { - case Opcode::WriteMemory8: - case Opcode::WriteMemory16: - case Opcode::WriteMemory32: - case Opcode::WriteMemory64: + case Opcode::A32WriteMemory8: + case Opcode::A32WriteMemory16: + case Opcode::A32WriteMemory32: + case Opcode::A32WriteMemory64: return true; default: @@ -71,10 +71,10 @@ bool Inst::IsSharedMemoryReadOrWrite() const { bool Inst::IsExclusiveMemoryWrite() const { switch (op) { - case Opcode::ExclusiveWriteMemory8: - case Opcode::ExclusiveWriteMemory16: - case Opcode::ExclusiveWriteMemory32: - case Opcode::ExclusiveWriteMemory64: + case Opcode::A32ExclusiveWriteMemory8: + case Opcode::A32ExclusiveWriteMemory16: + case Opcode::A32ExclusiveWriteMemory32: + case Opcode::A32ExclusiveWriteMemory64: return true; default: @@ -96,12 +96,12 @@ bool Inst::IsMemoryReadOrWrite() const { bool Inst::ReadsFromCPSR() const { switch (op) { - case Opcode::GetCpsr: - case Opcode::GetNFlag: - case Opcode::GetZFlag: - case Opcode::GetCFlag: - case Opcode::GetVFlag: - case Opcode::GetGEFlags: + case Opcode::A32GetCpsr: + case Opcode::A32GetNFlag: + case Opcode::A32GetZFlag: + case Opcode::A32GetCFlag: + case Opcode::A32GetVFlag: + case Opcode::A32GetGEFlags: return true; default: @@ -111,16 +111,16 @@ bool Inst::ReadsFromCPSR() const { bool Inst::WritesToCPSR() const { switch (op) { - case Opcode::SetCpsr: - case Opcode::SetCpsrNZCV: - case Opcode::SetCpsrNZCVQ: - case Opcode::SetNFlag: - case Opcode::SetZFlag: - case Opcode::SetCFlag: - case Opcode::SetVFlag: - case Opcode::OrQFlag: - case Opcode::SetGEFlags: - case Opcode::SetGEFlagsCompressed: + case Opcode::A32SetCpsr: + case Opcode::A32SetCpsrNZCV: + case Opcode::A32SetCpsrNZCVQ: + case Opcode::A32SetNFlag: + case Opcode::A32SetZFlag: + case Opcode::A32SetCFlag: + case Opcode::A32SetVFlag: + case Opcode::A32OrQFlag: + case Opcode::A32SetGEFlags: + case Opcode::A32SetGEFlagsCompressed: return true; default: @@ -130,9 +130,9 @@ bool Inst::WritesToCPSR() const { bool Inst::ReadsFromCoreRegister() const { switch (op) { - case Opcode::GetRegister: - case Opcode::GetExtendedRegister32: - case Opcode::GetExtendedRegister64: + case Opcode::A32GetRegister: + case Opcode::A32GetExtendedRegister32: + case Opcode::A32GetExtendedRegister64: return true; default: @@ -142,10 +142,10 @@ bool Inst::ReadsFromCoreRegister() const { bool Inst::WritesToCoreRegister() const { switch (op) { - case Opcode::SetRegister: - case Opcode::SetExtendedRegister32: - case Opcode::SetExtendedRegister64: - case Opcode::BXWritePC: + case Opcode::A32SetRegister: + case Opcode::A32SetExtendedRegister32: + case Opcode::A32SetExtendedRegister64: + case Opcode::A32BXWritePC: return true; default: @@ -155,8 +155,8 @@ bool Inst::WritesToCoreRegister() const { bool Inst::ReadsFromFPSCR() const { switch (op) { - case Opcode::GetFpscr: - case Opcode::GetFpscrNZCV: + case Opcode::A32GetFpscr: + case Opcode::A32GetFpscrNZCV: case Opcode::FPAbs32: case Opcode::FPAbs64: case Opcode::FPAdd32: @@ -182,8 +182,8 @@ bool Inst::ReadsFromFPSCR() const { bool Inst::WritesToFPSCR() const { switch (op) { - case Opcode::SetFpscr: - case Opcode::SetFpscrNZCV: + case Opcode::A32SetFpscr: + case Opcode::A32SetFpscrNZCV: case Opcode::FPAbs32: case Opcode::FPAbs64: case Opcode::FPAdd32: @@ -209,24 +209,24 @@ bool Inst::WritesToFPSCR() const { bool Inst::CausesCPUException() const { return op == Opcode::Breakpoint || - op == Opcode::CallSupervisor; + op == Opcode::A32CallSupervisor; } bool Inst::AltersExclusiveState() const { - return op == Opcode::ClearExclusive || - op == Opcode::SetExclusive || + return op == Opcode::A32ClearExclusive || + op == Opcode::A32SetExclusive || IsExclusiveMemoryWrite(); } bool Inst::IsCoprocessorInstruction() const { switch (op) { - case Opcode::CoprocInternalOperation: - case Opcode::CoprocSendOneWord: - case Opcode::CoprocSendTwoWords: - case Opcode::CoprocGetOneWord: - case Opcode::CoprocGetTwoWords: - case Opcode::CoprocLoadWords: - case Opcode::CoprocStoreWords: + case Opcode::A32CoprocInternalOperation: + case Opcode::A32CoprocSendOneWord: + case Opcode::A32CoprocSendTwoWords: + case Opcode::A32CoprocGetOneWord: + case Opcode::A32CoprocGetTwoWords: + case Opcode::A32CoprocLoadWords: + case Opcode::A32CoprocStoreWords: return true; default: diff --git a/src/frontend/ir/opcodes.cpp b/src/frontend/ir/opcodes.cpp index c96f53f8..1eea876b 100644 --- a/src/frontend/ir/opcodes.cpp +++ b/src/frontend/ir/opcodes.cpp @@ -27,8 +27,10 @@ struct Meta { static const std::map opcode_info {{ #define OPCODE(name, type, ...) { Opcode::name, { #name, type, { __VA_ARGS__ } } }, +#define A32OPC(name, type, ...) { Opcode::A32##name, { #name, type, { __VA_ARGS__ } } }, #include "opcodes.inc" #undef OPCODE +#undef A32OPC }}; } // namespace OpcodeInfo diff --git a/src/frontend/ir/opcodes.h b/src/frontend/ir/opcodes.h index 88306898..06cea365 100644 --- a/src/frontend/ir/opcodes.h +++ b/src/frontend/ir/opcodes.h @@ -17,8 +17,10 @@ namespace IR { */ enum class Opcode { #define OPCODE(name, type, ...) name, +#define A32OPC(name, type, ...) A32##name, #include "opcodes.inc" #undef OPCODE +#undef A32OPC NUM_OPCODE }; diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 6c41782e..fea73632 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -4,35 +4,35 @@ OPCODE(Void, T::Void, OPCODE(Identity, T::Opaque, T::Opaque ) OPCODE(Breakpoint, T::Void, ) -// ARM Context getters/setters -OPCODE(GetRegister, T::U32, T::RegRef ) -OPCODE(GetExtendedRegister32, T::F32, T::ExtRegRef ) -OPCODE(GetExtendedRegister64, T::F64, T::ExtRegRef ) -OPCODE(SetRegister, T::Void, T::RegRef, T::U32 ) -OPCODE(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32 ) -OPCODE(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 ) -OPCODE(GetCpsr, T::U32, ) -OPCODE(SetCpsr, T::Void, T::U32 ) -OPCODE(SetCpsrNZCV, T::Void, T::U32 ) -OPCODE(SetCpsrNZCVQ, T::Void, T::U32 ) -OPCODE(GetNFlag, T::U1, ) -OPCODE(SetNFlag, T::Void, T::U1 ) -OPCODE(GetZFlag, T::U1, ) -OPCODE(SetZFlag, T::Void, T::U1 ) -OPCODE(GetCFlag, T::U1, ) -OPCODE(SetCFlag, T::Void, T::U1 ) -OPCODE(GetVFlag, T::U1, ) -OPCODE(SetVFlag, T::Void, T::U1 ) -OPCODE(OrQFlag, T::Void, T::U1 ) -OPCODE(GetGEFlags, T::U32, ) -OPCODE(SetGEFlags, T::Void, T::U32 ) -OPCODE(SetGEFlagsCompressed, T::Void, T::U32 ) -OPCODE(BXWritePC, T::Void, T::U32 ) -OPCODE(CallSupervisor, T::Void, T::U32 ) -OPCODE(GetFpscr, T::U32, ) -OPCODE(SetFpscr, T::Void, T::U32, ) -OPCODE(GetFpscrNZCV, T::U32, ) -OPCODE(SetFpscrNZCV, T::Void, T::U32, ) +// A32 Context getters/setters +A32OPC(GetRegister, T::U32, T::RegRef ) +A32OPC(GetExtendedRegister32, T::F32, T::ExtRegRef ) +A32OPC(GetExtendedRegister64, T::F64, T::ExtRegRef ) +A32OPC(SetRegister, T::Void, T::RegRef, T::U32 ) +A32OPC(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32 ) +A32OPC(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 ) +A32OPC(GetCpsr, T::U32, ) +A32OPC(SetCpsr, T::Void, T::U32 ) +A32OPC(SetCpsrNZCV, T::Void, T::U32 ) +A32OPC(SetCpsrNZCVQ, T::Void, T::U32 ) +A32OPC(GetNFlag, T::U1, ) +A32OPC(SetNFlag, T::Void, T::U1 ) +A32OPC(GetZFlag, T::U1, ) +A32OPC(SetZFlag, T::Void, T::U1 ) +A32OPC(GetCFlag, T::U1, ) +A32OPC(SetCFlag, T::Void, T::U1 ) +A32OPC(GetVFlag, T::U1, ) +A32OPC(SetVFlag, T::Void, T::U1 ) +A32OPC(OrQFlag, T::Void, T::U1 ) +A32OPC(GetGEFlags, T::U32, ) +A32OPC(SetGEFlags, T::Void, T::U32 ) +A32OPC(SetGEFlagsCompressed, T::Void, T::U32 ) +A32OPC(BXWritePC, T::Void, T::U32 ) +A32OPC(CallSupervisor, T::Void, T::U32 ) +A32OPC(GetFpscr, T::U32, ) +A32OPC(SetFpscr, T::Void, T::U32, ) +A32OPC(GetFpscrNZCV, T::U32, ) +A32OPC(SetFpscrNZCV, T::Void, T::U32, ) // Hints OPCODE(PushRSB, T::Void, T::U64 ) @@ -155,26 +155,26 @@ OPCODE(FPU32ToDouble, T::F64, T::F32, T::U1 OPCODE(FPS32ToDouble, T::F64, T::F32, T::U1 ) // Memory access -OPCODE(ClearExclusive, T::Void, ) -OPCODE(SetExclusive, T::Void, T::U32, T::U8 ) -OPCODE(ReadMemory8, T::U8, T::U32 ) -OPCODE(ReadMemory16, T::U16, T::U32 ) -OPCODE(ReadMemory32, T::U32, T::U32 ) -OPCODE(ReadMemory64, T::U64, T::U32 ) -OPCODE(WriteMemory8, T::Void, T::U32, T::U8 ) -OPCODE(WriteMemory16, T::Void, T::U32, T::U16 ) -OPCODE(WriteMemory32, T::Void, T::U32, T::U32 ) -OPCODE(WriteMemory64, T::Void, T::U32, T::U64 ) -OPCODE(ExclusiveWriteMemory8, T::U32, T::U32, T::U8 ) -OPCODE(ExclusiveWriteMemory16, T::U32, T::U32, T::U16 ) -OPCODE(ExclusiveWriteMemory32, T::U32, T::U32, T::U32 ) -OPCODE(ExclusiveWriteMemory64, T::U32, T::U32, T::U32, T::U32 ) +A32OPC(ClearExclusive, T::Void, ) +A32OPC(SetExclusive, T::Void, T::U32, T::U8 ) +A32OPC(ReadMemory8, T::U8, T::U32 ) +A32OPC(ReadMemory16, T::U16, T::U32 ) +A32OPC(ReadMemory32, T::U32, T::U32 ) +A32OPC(ReadMemory64, T::U64, T::U32 ) +A32OPC(WriteMemory8, T::Void, T::U32, T::U8 ) +A32OPC(WriteMemory16, T::Void, T::U32, T::U16 ) +A32OPC(WriteMemory32, T::Void, T::U32, T::U32 ) +A32OPC(WriteMemory64, T::Void, T::U32, T::U64 ) +A32OPC(ExclusiveWriteMemory8, T::U32, T::U32, T::U8 ) +A32OPC(ExclusiveWriteMemory16, T::U32, T::U32, T::U16 ) +A32OPC(ExclusiveWriteMemory32, T::U32, T::U32, T::U32 ) +A32OPC(ExclusiveWriteMemory64, T::U32, T::U32, T::U32, T::U32 ) // Coprocessor -OPCODE(CoprocInternalOperation, T::Void, T::CoprocInfo ) -OPCODE(CoprocSendOneWord, T::Void, T::CoprocInfo, T::U32 ) -OPCODE(CoprocSendTwoWords, T::Void, T::CoprocInfo, T::U32, T::U32 ) -OPCODE(CoprocGetOneWord, T::U32, T::CoprocInfo ) -OPCODE(CoprocGetTwoWords, T::U64, T::CoprocInfo ) -OPCODE(CoprocLoadWords, T::Void, T::CoprocInfo, T::U32 ) -OPCODE(CoprocStoreWords, T::Void, T::CoprocInfo, T::U32 ) +A32OPC(CoprocInternalOperation, T::Void, T::CoprocInfo ) +A32OPC(CoprocSendOneWord, T::Void, T::CoprocInfo, T::U32 ) +A32OPC(CoprocSendTwoWords, T::Void, T::CoprocInfo, T::U32, T::U32 ) +A32OPC(CoprocGetOneWord, T::U32, T::CoprocInfo ) +A32OPC(CoprocGetTwoWords, T::U64, T::CoprocInfo ) +A32OPC(CoprocLoadWords, T::Void, T::CoprocInfo, T::U32 ) +A32OPC(CoprocStoreWords, T::Void, T::CoprocInfo, T::U32 ) diff --git a/src/ir_opt/constant_propagation_pass.cpp b/src/ir_opt/constant_propagation_pass.cpp index 84fd5376..8e015333 100644 --- a/src/ir_opt/constant_propagation_pass.cpp +++ b/src/ir_opt/constant_propagation_pass.cpp @@ -16,9 +16,9 @@ namespace Optimization { void ConstantPropagation(IR::Block& block, const UserCallbacks::Memory& memory_callbacks) { for (auto& inst : block) { switch (inst.GetOpcode()) { - case IR::Opcode::SetCFlag: { + case IR::Opcode::A32SetCFlag: { IR::Value arg = inst.GetArg(0); - if (!arg.IsImmediate() && arg.GetInst()->GetOpcode() == IR::Opcode::GetCFlag) { + if (!arg.IsImmediate() && arg.GetInst()->GetOpcode() == IR::Opcode::A32GetCFlag) { inst.Invalidate(); } break; @@ -41,7 +41,7 @@ void ConstantPropagation(IR::Block& block, const UserCallbacks::Memory& memory_c } break; } - case IR::Opcode::ReadMemory8: { + case IR::Opcode::A32ReadMemory8: { if (!inst.AreAllArgsImmediates()) break; @@ -52,7 +52,7 @@ void ConstantPropagation(IR::Block& block, const UserCallbacks::Memory& memory_c } break; } - case IR::Opcode::ReadMemory16: { + case IR::Opcode::A32ReadMemory16: { if (!inst.AreAllArgsImmediates()) break; @@ -63,7 +63,7 @@ void ConstantPropagation(IR::Block& block, const UserCallbacks::Memory& memory_c } break; } - case IR::Opcode::ReadMemory32: { + case IR::Opcode::A32ReadMemory32: { if (!inst.AreAllArgsImmediates()) break; @@ -74,7 +74,7 @@ void ConstantPropagation(IR::Block& block, const UserCallbacks::Memory& memory_c } break; } - case IR::Opcode::ReadMemory64: { + case IR::Opcode::A32ReadMemory64: { if (!inst.AreAllArgsImmediates()) break; diff --git a/src/ir_opt/get_set_elimination_pass.cpp b/src/ir_opt/get_set_elimination_pass.cpp index da4172e4..1a6622ba 100644 --- a/src/ir_opt/get_set_elimination_pass.cpp +++ b/src/ir_opt/get_set_elimination_pass.cpp @@ -54,7 +54,7 @@ void GetSetElimination(IR::Block& block) { for (auto inst = block.begin(); inst != block.end(); ++inst) { switch (inst->GetOpcode()) { - case IR::Opcode::SetRegister: { + case IR::Opcode::A32SetRegister: { A32::Reg reg = inst->GetArg(0).GetA32RegRef(); if (reg == A32::Reg::PC) break; @@ -62,14 +62,14 @@ void GetSetElimination(IR::Block& block) { do_set(reg_info[reg_index], inst->GetArg(1), inst); break; } - case IR::Opcode::GetRegister: { + case IR::Opcode::A32GetRegister: { A32::Reg reg = inst->GetArg(0).GetA32RegRef(); ASSERT(reg != A32::Reg::PC); size_t reg_index = static_cast(reg); do_get(reg_info[reg_index], inst); break; } - case IR::Opcode::SetExtendedRegister32: { + case IR::Opcode::A32SetExtendedRegister32: { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); size_t reg_index = A32::RegNumber(reg); do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst); @@ -80,7 +80,7 @@ void GetSetElimination(IR::Block& block) { } break; } - case IR::Opcode::GetExtendedRegister32: { + case IR::Opcode::A32GetExtendedRegister32: { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); size_t reg_index = A32::RegNumber(reg); do_get(ext_reg_singles_info[reg_index], inst); @@ -91,7 +91,7 @@ void GetSetElimination(IR::Block& block) { } break; } - case IR::Opcode::SetExtendedRegister64: { + case IR::Opcode::A32SetExtendedRegister64: { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); size_t reg_index = A32::RegNumber(reg); do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst); @@ -103,7 +103,7 @@ void GetSetElimination(IR::Block& block) { } break; } - case IR::Opcode::GetExtendedRegister64: { + case IR::Opcode::A32GetExtendedRegister64: { A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); size_t reg_index = A32::RegNumber(reg); do_get(ext_reg_doubles_info[reg_index], inst); @@ -115,43 +115,43 @@ void GetSetElimination(IR::Block& block) { } break; } - case IR::Opcode::SetNFlag: { + case IR::Opcode::A32SetNFlag: { do_set(cpsr_info.n, inst->GetArg(0), inst); break; } - case IR::Opcode::GetNFlag: { + case IR::Opcode::A32GetNFlag: { do_get(cpsr_info.n, inst); break; } - case IR::Opcode::SetZFlag: { + case IR::Opcode::A32SetZFlag: { do_set(cpsr_info.z, inst->GetArg(0), inst); break; } - case IR::Opcode::GetZFlag: { + case IR::Opcode::A32GetZFlag: { do_get(cpsr_info.z, inst); break; } - case IR::Opcode::SetCFlag: { + case IR::Opcode::A32SetCFlag: { do_set(cpsr_info.c, inst->GetArg(0), inst); break; } - case IR::Opcode::GetCFlag: { + case IR::Opcode::A32GetCFlag: { do_get(cpsr_info.c, inst); break; } - case IR::Opcode::SetVFlag: { + case IR::Opcode::A32SetVFlag: { do_set(cpsr_info.v, inst->GetArg(0), inst); break; } - case IR::Opcode::GetVFlag: { + case IR::Opcode::A32GetVFlag: { do_get(cpsr_info.v, inst); break; } - case IR::Opcode::SetGEFlags: { + case IR::Opcode::A32SetGEFlags: { do_set(cpsr_info.ge, inst->GetArg(0), inst); break; } - case IR::Opcode::GetGEFlags: { + case IR::Opcode::A32GetGEFlags: { do_get(cpsr_info.ge, inst); break; }