IR: Split off A32 specific opcodes

This commit is contained in:
MerryMage 2018-01-01 16:19:43 +00:00
parent b1f0cf9278
commit 8bef20c24d
12 changed files with 243 additions and 231 deletions

View file

@ -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<size_t>(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();

View file

@ -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);

View file

@ -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<u8>(CRn),
static_cast<u8>(CRm),
static_cast<u8>(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<u8>(CRn),
static_cast<u8>(CRm),
static_cast<u8>(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<u8>(two ? 1 : 0),
static_cast<u8>(opc),
static_cast<u8>(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<u8>(CRn),
static_cast<u8>(CRm),
static_cast<u8>(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<u8>(two ? 1 : 0),
static_cast<u8>(opc),
static_cast<u8>(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<u8>(CRd),
static_cast<u8>(has_option ? 1 : 0),
static_cast<u8>(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<u8>(CRd),
static_cast<u8>(has_option ? 1 : 0),
static_cast<u8>(option)};
Inst(Opcode::CoprocStoreWords, {IR::Value(coproc_info), address});
Inst(Opcode::A32CoprocStoreWords, {IR::Value(coproc_info), address});
}
} // namespace IR

View file

@ -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);

View file

@ -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});
}

View file

@ -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);

View file

@ -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:

View file

@ -27,8 +27,10 @@ struct Meta {
static const std::map<Opcode, Meta> 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

View file

@ -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
};

View file

@ -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 )

View file

@ -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;

View file

@ -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<size_t>(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;
}