IR: Split off A32 specific opcodes
This commit is contained in:
parent
b1f0cf9278
commit
8bef20c24d
12 changed files with 243 additions and 231 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue