diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d80d10e8..1c85d68f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,8 @@ if (ARCHITECTURE_x86_64) target_sources(dynarmic PRIVATE backend_x64/a32_emit_x64.cpp backend_x64/a32_emit_x64.h + backend_x64/a32_jitstate.cpp + backend_x64/a32_jitstate.h backend_x64/abi.cpp backend_x64/abi.h backend_x64/block_of_code.cpp @@ -88,8 +90,6 @@ if (ARCHITECTURE_x86_64) backend_x64/hostloc.cpp backend_x64/hostloc.h backend_x64/interface_x64.cpp - backend_x64/jitstate.cpp - backend_x64/jitstate.h backend_x64/oparg.h backend_x64/reg_alloc.cpp backend_x64/reg_alloc.h diff --git a/src/backend_x64/a32_emit_x64.cpp b/src/backend_x64/a32_emit_x64.cpp index f161afce..88aff084 100644 --- a/src/backend_x64/a32_emit_x64.cpp +++ b/src/backend_x64/a32_emit_x64.cpp @@ -10,10 +10,10 @@ #include #include "backend_x64/a32_emit_x64.h" +#include "backend_x64/a32_jitstate.h" #include "backend_x64/abi.h" #include "backend_x64/block_of_code.h" #include "backend_x64/emit_x64.h" -#include "backend_x64/jitstate.h" #include "common/address_range.h" #include "common/assert.h" #include "common/bit_util.h" @@ -34,17 +34,17 @@ namespace BackendX64 { using namespace Xbyak::util; static Xbyak::Address MJitStateReg(A32::Reg reg) { - return dword[r15 + offsetof(JitState, Reg) + sizeof(u32) * static_cast(reg)]; + return dword[r15 + offsetof(A32JitState, Reg) + sizeof(u32) * static_cast(reg)]; } static Xbyak::Address MJitStateExtReg(A32::ExtReg reg) { if (A32::IsSingleExtReg(reg)) { size_t index = static_cast(reg) - static_cast(A32::ExtReg::S0); - return dword[r15 + offsetof(JitState, ExtReg) + sizeof(u32) * index]; + return dword[r15 + offsetof(A32JitState, ExtReg) + sizeof(u32) * index]; } if (A32::IsDoubleExtReg(reg)) { size_t index = static_cast(reg) - static_cast(A32::ExtReg::D0); - return qword[r15 + offsetof(JitState, ExtReg) + sizeof(u64) * index]; + return qword[r15 + offsetof(A32JitState, ExtReg) + sizeof(u64) * index]; } ASSERT_MSG(false, "Should never happen."); } @@ -174,7 +174,7 @@ void A32EmitX64::EmitA32SetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, I } } -static u32 GetCpsrImpl(JitState* jit_state) { +static u32 GetCpsrImpl(A32JitState* jit_state) { return jit_state->Cpsr(); } @@ -184,11 +184,11 @@ void A32EmitX64::EmitA32GetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) Xbyak::Reg32 b = reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 c = reg_alloc.ScratchGpr().cvt32(); - code->mov(c, dword[r15 + offsetof(JitState, CPSR_ge)]); + code->mov(c, dword[r15 + offsetof(A32JitState, CPSR_ge)]); // Here we observe that CPSR_q and CPSR_nzcv are right next to each other in memory, // so we load them both at the same time with one 64-bit read. This allows us to // extract all of their bits together at once with one pext. - code->mov(result.cvt64(), qword[r15 + offsetof(JitState, CPSR_q)]); + code->mov(result.cvt64(), qword[r15 + offsetof(A32JitState, CPSR_q)]); code->mov(b.cvt64(), 0xF000000000000001ull); code->pext(result.cvt64(), result.cvt64(), b.cvt64()); code->mov(b, 0x80808080); @@ -197,9 +197,9 @@ void A32EmitX64::EmitA32GetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) code->shl(c, 16); code->or_(result, c); code->mov(b, 0x00000220); - code->mov(c, dword[r15 + offsetof(JitState, CPSR_et)]); + code->mov(c, dword[r15 + offsetof(A32JitState, CPSR_et)]); code->pdep(c.cvt64(), c.cvt64(), b.cvt64()); - code->or_(result, dword[r15 + offsetof(JitState, CPSR_jaifm)]); + code->or_(result, dword[r15 + offsetof(A32JitState, CPSR_jaifm)]); code->or_(result, c); reg_alloc.DefineValue(inst, result); @@ -210,7 +210,7 @@ void A32EmitX64::EmitA32GetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) } } -static void SetCpsrImpl(u32 value, JitState* jit_state) { +static void SetCpsrImpl(u32 value, A32JitState* jit_state) { jit_state->SetCpsr(value); } @@ -226,12 +226,12 @@ void A32EmitX64::EmitA32SetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* i if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); - code->mov(dword[r15 + offsetof(JitState, CPSR_nzcv)], u32(imm & 0xF0000000)); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], u32(imm & 0xF0000000)); } else { Xbyak::Reg32 a = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->and_(a, 0xF0000000); - code->mov(dword[r15 + offsetof(JitState, CPSR_nzcv)], a); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], a); } } @@ -240,21 +240,21 @@ void A32EmitX64::EmitA32SetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); - code->mov(dword[r15 + offsetof(JitState, CPSR_nzcv)], u32(imm & 0xF0000000)); - code->mov(code->byte[r15 + offsetof(JitState, CPSR_q)], u8((imm & 0x08000000) != 0 ? 1 : 0)); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], u32(imm & 0xF0000000)); + code->mov(code->byte[r15 + offsetof(A32JitState, CPSR_q)], u8((imm & 0x08000000) != 0 ? 1 : 0)); } else { Xbyak::Reg32 a = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->bt(a, 27); - code->setc(code->byte[r15 + offsetof(JitState, CPSR_q)]); + code->setc(code->byte[r15 + offsetof(A32JitState, CPSR_q)]); code->and_(a, 0xF0000000); - code->mov(dword[r15 + offsetof(JitState, CPSR_nzcv)], a); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], a); } } 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->mov(result, dword[r15 + offsetof(A32JitState, CPSR_nzcv)]); code->shr(result, 31); reg_alloc.DefineValue(inst, result); } @@ -265,22 +265,22 @@ void A32EmitX64::EmitA32SetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) { - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], flag_mask); } else { - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); } } else { Xbyak::Reg32 to_store = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->shl(to_store, flag_bit); - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], to_store); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], to_store); } } 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->mov(result, dword[r15 + offsetof(A32JitState, CPSR_nzcv)]); code->shr(result, 30); code->and_(result, 1); reg_alloc.DefineValue(inst, result); @@ -292,22 +292,22 @@ void A32EmitX64::EmitA32SetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) { - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], flag_mask); } else { - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); } } else { Xbyak::Reg32 to_store = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->shl(to_store, flag_bit); - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], to_store); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], to_store); } } 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->mov(result, dword[r15 + offsetof(A32JitState, CPSR_nzcv)]); code->shr(result, 29); code->and_(result, 1); reg_alloc.DefineValue(inst, result); @@ -319,22 +319,22 @@ void A32EmitX64::EmitA32SetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) { - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], flag_mask); } else { - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); } } else { Xbyak::Reg32 to_store = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->shl(to_store, flag_bit); - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], to_store); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], to_store); } } 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->mov(result, dword[r15 + offsetof(A32JitState, CPSR_nzcv)]); code->shr(result, 28); code->and_(result, 1); reg_alloc.DefineValue(inst, result); @@ -346,16 +346,16 @@ void A32EmitX64::EmitA32SetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) { - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], flag_mask); } else { - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); } } else { Xbyak::Reg32 to_store = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->shl(to_store, flag_bit); - code->and_(dword[r15 + offsetof(JitState, CPSR_nzcv)], ~flag_mask); - code->or_(dword[r15 + offsetof(JitState, CPSR_nzcv)], to_store); + code->and_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], ~flag_mask); + code->or_(dword[r15 + offsetof(A32JitState, CPSR_nzcv)], to_store); } } @@ -363,17 +363,17 @@ 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()) - code->mov(dword[r15 + offsetof(JitState, CPSR_q)], 1); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_q)], 1); } else { Xbyak::Reg8 to_store = reg_alloc.UseGpr(args[0]).cvt8(); - code->or_(code->byte[r15 + offsetof(JitState, CPSR_q)], to_store); + code->or_(code->byte[r15 + offsetof(A32JitState, CPSR_q)], to_store); } } 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)]); + code->movd(result, dword[r15 + offsetof(A32JitState, CPSR_ge)]); reg_alloc.DefineValue(inst, result); } @@ -383,10 +383,10 @@ void A32EmitX64::EmitA32SetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* in if (args[0].IsInXmm()) { Xbyak::Xmm to_store = reg_alloc.UseXmm(args[0]); - code->movd(dword[r15 + offsetof(JitState, CPSR_ge)], to_store); + code->movd(dword[r15 + offsetof(A32JitState, CPSR_ge)], to_store); } else { Xbyak::Reg32 to_store = reg_alloc.UseGpr(args[0]).cvt32(); - code->mov(dword[r15 + offsetof(JitState, CPSR_ge)], to_store); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_ge)], to_store); } } @@ -400,7 +400,7 @@ void A32EmitX64::EmitA32SetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR ge |= Common::Bit<17>(imm) ? 0x0000FF00 : 0; ge |= Common::Bit<16>(imm) ? 0x000000FF : 0; - code->mov(dword[r15 + offsetof(JitState, CPSR_ge)], ge); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_ge)], ge); } else if (code->DoesCpuSupport(Xbyak::util::Cpu::tBMI2)) { Xbyak::Reg32 a = reg_alloc.UseScratchGpr(args[0]).cvt32(); Xbyak::Reg32 b = reg_alloc.ScratchGpr().cvt32(); @@ -409,7 +409,7 @@ void A32EmitX64::EmitA32SetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR code->shr(a, 16); code->pdep(a, a, b); code->imul(a, a, 0xFF); - code->mov(dword[r15 + offsetof(JitState, CPSR_ge)], a); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_ge)], a); } else { Xbyak::Reg32 a = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -418,7 +418,7 @@ void A32EmitX64::EmitA32SetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR code->imul(a, a, 0x00204081); code->and_(a, 0x01010101); code->imul(a, a, 0xFF); - code->mov(dword[r15 + offsetof(JitState, CPSR_ge)], a); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_ge)], a); } } @@ -444,7 +444,7 @@ void A32EmitX64::EmitA32BXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Ins et |= Common::Bit<0>(new_pc) ? 1 : 0; code->mov(MJitStateReg(A32::Reg::PC), new_pc & mask); - code->mov(dword[r15 + offsetof(JitState, CPSR_et)], et); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_et)], et); } else { if (A32::LocationDescriptor{block.Location()}.EFlag()) { Xbyak::Reg32 new_pc = reg_alloc.UseScratchGpr(arg).cvt32(); @@ -454,7 +454,7 @@ void A32EmitX64::EmitA32BXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Ins code->mov(mask, new_pc); code->and_(mask, 1); code->lea(et, ptr[mask.cvt64() + 2]); - code->mov(dword[r15 + offsetof(JitState, CPSR_et)], et); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_et)], et); code->lea(mask, ptr[mask.cvt64() + mask.cvt64() * 1 - 4]); // mask = pc & 1 ? 0xFFFFFFFE : 0xFFFFFFFC code->and_(new_pc, mask); code->mov(MJitStateReg(A32::Reg::PC), new_pc); @@ -464,7 +464,7 @@ void A32EmitX64::EmitA32BXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Ins code->mov(mask, new_pc); code->and_(mask, 1); - code->mov(dword[r15 + offsetof(JitState, CPSR_et)], mask); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_et)], mask); code->lea(mask, ptr[mask.cvt64() + mask.cvt64() * 1 - 4]); // mask = pc & 1 ? 0xFFFFFFFE : 0xFFFFFFFC code->and_(new_pc, mask); code->mov(MJitStateReg(A32::Reg::PC), new_pc); @@ -476,20 +476,20 @@ void A32EmitX64::EmitA32CallSupervisor(RegAlloc& reg_alloc, IR::Block&, IR::Inst reg_alloc.HostCall(nullptr); code->SwitchMxcsrOnExit(); - code->mov(code->ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_to_run)]); - code->sub(code->ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_remaining)]); + code->mov(code->ABI_PARAM1, qword[r15 + offsetof(A32JitState, cycles_to_run)]); + code->sub(code->ABI_PARAM1, qword[r15 + offsetof(A32JitState, cycles_remaining)]); code->CallFunction(cb.AddTicks); reg_alloc.EndOfAllocScope(); auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.HostCall(nullptr, args[0]); code->CallFunction(cb.CallSVC); code->CallFunction(cb.GetTicksRemaining); - code->mov(qword[r15 + offsetof(JitState, cycles_to_run)], code->ABI_RETURN); - code->mov(qword[r15 + offsetof(JitState, cycles_remaining)], code->ABI_RETURN); + code->mov(qword[r15 + offsetof(A32JitState, cycles_to_run)], code->ABI_RETURN); + code->mov(qword[r15 + offsetof(A32JitState, cycles_remaining)], code->ABI_RETURN); code->SwitchMxcsrOnEntry(); } -static u32 GetFpscrImpl(JitState* jit_state) { +static u32 GetFpscrImpl(A32JitState* jit_state) { return jit_state->Fpscr(); } @@ -497,11 +497,11 @@ void A32EmitX64::EmitA32GetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst reg_alloc.HostCall(inst); code->mov(code->ABI_PARAM1, code->r15); - code->stmxcsr(code->dword[code->r15 + offsetof(JitState, guest_MXCSR)]); + code->stmxcsr(code->dword[code->r15 + offsetof(A32JitState, guest_MXCSR)]); code->CallFunction(&GetFpscrImpl); } -static void SetFpscrImpl(u32 value, JitState* jit_state) { +static void SetFpscrImpl(u32 value, A32JitState* jit_state) { jit_state->SetFpscr(value); } @@ -511,12 +511,12 @@ void A32EmitX64::EmitA32SetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst code->mov(code->ABI_PARAM2, code->r15); code->CallFunction(&SetFpscrImpl); - code->ldmxcsr(code->dword[code->r15 + offsetof(JitState, guest_MXCSR)]); + code->ldmxcsr(code->dword[code->r15 + offsetof(A32JitState, guest_MXCSR)]); } 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)]); + code->mov(result, dword[r15 + offsetof(A32JitState, FPSCR_nzcv)]); reg_alloc.DefineValue(inst, result); } @@ -524,11 +524,11 @@ void A32EmitX64::EmitA32SetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 value = reg_alloc.UseGpr(args[0]).cvt32(); - code->mov(dword[r15 + offsetof(JitState, FPSCR_nzcv)], value); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_nzcv)], value); } void A32EmitX64::EmitA32ClearExclusive(RegAlloc&, IR::Block&, IR::Inst*) { - code->mov(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(0)); + code->mov(code->byte[r15 + offsetof(A32JitState, exclusive_state)], u8(0)); } void A32EmitX64::EmitA32SetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { @@ -536,8 +536,8 @@ void A32EmitX64::EmitA32SetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* ASSERT(args[1].IsImmediate()); Xbyak::Reg32 address = reg_alloc.UseGpr(args[0]).cvt32(); - code->mov(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(1)); - code->mov(dword[r15 + offsetof(JitState, exclusive_address)], address); + code->mov(code->byte[r15 + offsetof(A32JitState, exclusive_state)], u8(1)); + code->mov(dword[r15 + offsetof(A32JitState, exclusive_address)], address); } template @@ -690,13 +690,13 @@ static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* ins Xbyak::Label end; code->mov(passed, u32(1)); - code->cmp(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(0)); + code->cmp(code->byte[r15 + offsetof(A32JitState, exclusive_state)], u8(0)); code->je(end); code->mov(tmp, code->ABI_PARAM1); - code->xor_(tmp, dword[r15 + offsetof(JitState, exclusive_address)]); - code->test(tmp, JitState::RESERVATION_GRANULE_MASK); + code->xor_(tmp, dword[r15 + offsetof(A32JitState, exclusive_address)]); + code->test(tmp, A32JitState::RESERVATION_GRANULE_MASK); code->jne(end); - code->mov(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(0)); + code->mov(code->byte[r15 + offsetof(A32JitState, exclusive_state)], u8(0)); if (prepend_high_word) { code->mov(code->ABI_PARAM2.cvt32(), code->ABI_PARAM2.cvt32()); // zero extend to 64-bits code->shl(code->ABI_PARAM3, 32); @@ -1014,10 +1014,10 @@ static u32 CalculateCpsr_et(const A32::LocationDescriptor& desc) { void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location) { if (CalculateCpsr_et(terminal.next) != CalculateCpsr_et(initial_location)) { - code->mov(dword[r15 + offsetof(JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); } - code->cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0); + code->cmp(qword[r15 + offsetof(A32JitState, cycles_remaining)], 0); patch_information[terminal.next].jg.emplace_back(code->getCurr()); if (auto next_bb = GetBasicBlock(terminal.next)) { @@ -1039,7 +1039,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc void A32EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location) { if (CalculateCpsr_et(terminal.next) != CalculateCpsr_et(initial_location)) { - code->mov(dword[r15 + offsetof(JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); + code->mov(dword[r15 + offsetof(A32JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); } patch_information[terminal.next].jmp.emplace_back(code->getCurr()); @@ -1055,17 +1055,17 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor) // TODO: Optimization is available here based on known state of FPSCR_mode and CPSR_et. code->mov(ecx, MJitStateReg(A32::Reg::PC)); code->shl(rcx, 32); - code->mov(ebx, dword[r15 + offsetof(JitState, FPSCR_mode)]); - code->or_(ebx, dword[r15 + offsetof(JitState, CPSR_et)]); + code->mov(ebx, dword[r15 + offsetof(A32JitState, FPSCR_mode)]); + code->or_(ebx, dword[r15 + offsetof(A32JitState, CPSR_et)]); code->or_(rbx, rcx); - code->mov(eax, dword[r15 + offsetof(JitState, rsb_ptr)]); + code->mov(eax, dword[r15 + offsetof(A32JitState, rsb_ptr)]); code->sub(eax, 1); - code->and_(eax, u32(JitState::RSBPtrMask)); - code->mov(dword[r15 + offsetof(JitState, rsb_ptr)], eax); - code->cmp(rbx, qword[r15 + offsetof(JitState, rsb_location_descriptors) + rax * sizeof(u64)]); + code->and_(eax, u32(A32JitState::RSBPtrMask)); + code->mov(dword[r15 + offsetof(A32JitState, rsb_ptr)], eax); + code->cmp(rbx, qword[r15 + offsetof(A32JitState, rsb_location_descriptors) + rax * sizeof(u64)]); code->jne(code->GetReturnFromRunCodeAddress()); - code->mov(rax, qword[r15 + offsetof(JitState, rsb_codeptrs) + rax * sizeof(u64)]); + code->mov(rax, qword[r15 + offsetof(A32JitState, rsb_codeptrs) + rax * sizeof(u64)]); code->jmp(rax); } @@ -1077,7 +1077,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor } void A32EmitX64::EmitTerminalImpl(IR::Term::CheckHalt terminal, IR::LocationDescriptor initial_location) { - code->cmp(code->byte[r15 + offsetof(JitState, halt_requested)], u8(0)); + code->cmp(code->byte[r15 + offsetof(A32JitState, halt_requested)], u8(0)); code->jne(code->GetForceReturnFromRunCodeAddress()); EmitTerminal(terminal.else_, initial_location); } diff --git a/src/backend_x64/jitstate.cpp b/src/backend_x64/a32_jitstate.cpp similarity index 96% rename from src/backend_x64/jitstate.cpp rename to src/backend_x64/a32_jitstate.cpp index f7ad6dfe..ec6c56c2 100644 --- a/src/backend_x64/jitstate.cpp +++ b/src/backend_x64/a32_jitstate.cpp @@ -4,8 +4,8 @@ * General Public License version 2 or any later version. */ +#include "backend_x64/a32_jitstate.h" #include "backend_x64/block_of_code.h" -#include "backend_x64/jitstate.h" #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" @@ -44,7 +44,7 @@ namespace BackendX64 { * OF bit 0 Overflow flag */ -u32 JitState::Cpsr() const { +u32 A32JitState::Cpsr() const { ASSERT((CPSR_nzcv & ~0xF0000000) == 0); ASSERT((CPSR_q & ~1) == 0); ASSERT((CPSR_et & ~3) == 0); @@ -70,7 +70,7 @@ u32 JitState::Cpsr() const { return cpsr; } -void JitState::SetCpsr(u32 cpsr) { +void A32JitState::SetCpsr(u32 cpsr) { // NZCV flags CPSR_nzcv = cpsr & 0xF0000000; // Q flag @@ -89,7 +89,7 @@ void JitState::SetCpsr(u32 cpsr) { CPSR_jaifm = cpsr & 0x07F0FDDF; } -void JitState::ResetRSB() { +void A32JitState::ResetRSB() { rsb_location_descriptors.fill(0xFFFFFFFFFFFFFFFFull); rsb_codeptrs.fill(0); } @@ -153,7 +153,7 @@ void JitState::ResetRSB() { constexpr u32 FPSCR_MODE_MASK = A32::LocationDescriptor::FPSCR_MODE_MASK; constexpr u32 FPSCR_NZCV_MASK = 0xF0000000; -u32 JitState::Fpscr() const { +u32 A32JitState::Fpscr() const { ASSERT((FPSCR_mode & ~FPSCR_MODE_MASK) == 0); ASSERT((FPSCR_nzcv & ~FPSCR_NZCV_MASK) == 0); ASSERT((FPSCR_IDC & ~(1 << 7)) == 0); @@ -168,7 +168,7 @@ u32 JitState::Fpscr() const { return FPSCR; } -void JitState::SetFpscr(u32 FPSCR) { +void A32JitState::SetFpscr(u32 FPSCR) { old_FPSCR = FPSCR; FPSCR_mode = FPSCR & FPSCR_MODE_MASK; FPSCR_nzcv = FPSCR & FPSCR_NZCV_MASK; @@ -199,7 +199,7 @@ void JitState::SetFpscr(u32 FPSCR) { } } -u64 JitState::GetUniqueHash() const { +u64 A32JitState::GetUniqueHash() const { return CPSR_et | FPSCR_mode | (static_cast(Reg[15]) << 32); } diff --git a/src/backend_x64/jitstate.h b/src/backend_x64/a32_jitstate.h similarity index 97% rename from src/backend_x64/jitstate.h rename to src/backend_x64/a32_jitstate.h index ea968432..7fe6df63 100644 --- a/src/backend_x64/jitstate.h +++ b/src/backend_x64/a32_jitstate.h @@ -22,8 +22,8 @@ constexpr size_t SpillCount = 64; #pragma warning(disable:4324) // Structure was padded due to alignment specifier #endif -struct JitState { - JitState() { ResetRSB(); } +struct A32JitState { + A32JitState() { ResetRSB(); } std::array Reg{}; // Current register file. // TODO: Mode-specific register sets unimplemented. diff --git a/src/backend_x64/block_of_code.cpp b/src/backend_x64/block_of_code.cpp index a1a7cdd6..38b51ac2 100644 --- a/src/backend_x64/block_of_code.cpp +++ b/src/backend_x64/block_of_code.cpp @@ -9,9 +9,9 @@ #include +#include "backend_x64/a32_jitstate.h" #include "backend_x64/abi.h" #include "backend_x64/block_of_code.h" -#include "backend_x64/jitstate.h" #include "common/assert.h" #include "dynarmic/callbacks.h" @@ -76,14 +76,14 @@ size_t BlockOfCode::SpaceRemaining() const { return std::min(TOTAL_CODE_SIZE - far_code_offset, FAR_CODE_OFFSET - near_code_offset); } -void BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const { +void BlockOfCode::RunCode(A32JitState* jit_state, size_t cycles_to_run) const { constexpr size_t max_cycles_to_run = static_cast(std::numeric_limitscycles_remaining)>::max()); ASSERT(cycles_to_run <= max_cycles_to_run); jit_state->cycles_to_run = cycles_to_run; jit_state->cycles_remaining = cycles_to_run; - u32 new_rsb_ptr = (jit_state->rsb_ptr - 1) & JitState::RSBPtrMask; + u32 new_rsb_ptr = (jit_state->rsb_ptr - 1) & A32JitState::RSBPtrMask; if (jit_state->GetUniqueHash() == jit_state->rsb_location_descriptors[new_rsb_ptr]) { jit_state->rsb_ptr = new_rsb_ptr; run_code_from(jit_state, jit_state->rsb_codeptrs[new_rsb_ptr]); @@ -139,7 +139,7 @@ void BlockOfCode::GenRunCode() { // Return from run code variants const auto emit_return_from_run_code = [this, &loop, &enter_mxcsr_then_loop](bool mxcsr_already_exited, bool force_return){ if (!force_return) { - cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0); + cmp(qword[r15 + offsetof(A32JitState, cycles_remaining)], 0); jg(mxcsr_already_exited ? enter_mxcsr_then_loop : loop); } @@ -147,8 +147,8 @@ void BlockOfCode::GenRunCode() { SwitchMxcsrOnExit(); } - mov(ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_to_run)]); - sub(ABI_PARAM1, qword[r15 + offsetof(JitState, cycles_remaining)]); + mov(ABI_PARAM1, qword[r15 + offsetof(A32JitState, cycles_to_run)]); + sub(ABI_PARAM1, qword[r15 + offsetof(A32JitState, cycles_remaining)]); CallFunction(cb.AddTicks); ABI_PopCalleeSaveRegistersAndAdjustStack(this); @@ -231,13 +231,13 @@ void BlockOfCode::GenMemoryAccessors() { } void BlockOfCode::SwitchMxcsrOnEntry() { - stmxcsr(dword[r15 + offsetof(JitState, save_host_MXCSR)]); - ldmxcsr(dword[r15 + offsetof(JitState, guest_MXCSR)]); + stmxcsr(dword[r15 + offsetof(A32JitState, save_host_MXCSR)]); + ldmxcsr(dword[r15 + offsetof(A32JitState, guest_MXCSR)]); } void BlockOfCode::SwitchMxcsrOnExit() { - stmxcsr(dword[r15 + offsetof(JitState, guest_MXCSR)]); - ldmxcsr(dword[r15 + offsetof(JitState, save_host_MXCSR)]); + stmxcsr(dword[r15 + offsetof(A32JitState, guest_MXCSR)]); + ldmxcsr(dword[r15 + offsetof(A32JitState, save_host_MXCSR)]); } Xbyak::Address BlockOfCode::MConst(u64 constant) { diff --git a/src/backend_x64/block_of_code.h b/src/backend_x64/block_of_code.h index 9df949ef..287f2698 100644 --- a/src/backend_x64/block_of_code.h +++ b/src/backend_x64/block_of_code.h @@ -12,8 +12,8 @@ #include #include +#include "backend_x64/a32_jitstate.h" #include "backend_x64/constant_pool.h" -#include "backend_x64/jitstate.h" #include "common/common_types.h" #include "dynarmic/callbacks.h" @@ -32,7 +32,7 @@ public: size_t SpaceRemaining() const; /// Runs emulated code for approximately `cycles_to_run` cycles. - void RunCode(JitState* jit_state, size_t cycles_to_run) const; + void RunCode(A32JitState* jit_state, size_t cycles_to_run) const; /// Code emitter: Returns to dispatcher void ReturnFromRunCode(bool mxcsr_already_exited = false); /// Code emitter: Returns to dispatcher, forces return to host @@ -137,8 +137,8 @@ private: CodePtr near_code_ptr; CodePtr far_code_ptr; - using RunCodeFuncType = void(*)(JitState*); - using RunCodeFromFuncType = void(*)(JitState*, u64); + using RunCodeFuncType = void(*)(A32JitState*); + using RunCodeFromFuncType = void(*)(A32JitState*, u64); RunCodeFuncType run_code = nullptr; RunCodeFromFuncType run_code_from = nullptr; static constexpr size_t MXCSR_ALREADY_EXITED = 1 << 0; diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index be531a2b..967c7ec1 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -11,7 +11,6 @@ #include "backend_x64/abi.h" #include "backend_x64/block_of_code.h" #include "backend_x64/emit_x64.h" -#include "backend_x64/jitstate.h" #include "common/address_range.h" #include "common/assert.h" #include "common/bit_util.h" @@ -89,19 +88,19 @@ void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_r ? iter->second.entrypoint : code->GetReturnFromRunCodeAddress(); - code->mov(index_reg.cvt32(), dword[r15 + offsetof(JitState, rsb_ptr)]); + code->mov(index_reg.cvt32(), dword[r15 + offsetof(A32JitState, rsb_ptr)]); code->mov(loc_desc_reg, target.Value()); patch_information[target].mov_rcx.emplace_back(code->getCurr()); EmitPatchMovRcx(target_code_ptr); - code->mov(qword[r15 + index_reg * 8 + offsetof(JitState, rsb_location_descriptors)], loc_desc_reg); - code->mov(qword[r15 + index_reg * 8 + offsetof(JitState, rsb_codeptrs)], rcx); + code->mov(qword[r15 + index_reg * 8 + offsetof(A32JitState, rsb_location_descriptors)], loc_desc_reg); + code->mov(qword[r15 + index_reg * 8 + offsetof(A32JitState, rsb_codeptrs)], rcx); code->add(index_reg.cvt32(), 1); - code->and_(index_reg.cvt32(), u32(JitState::RSBPtrMask)); - code->mov(dword[r15 + offsetof(JitState, rsb_ptr)], index_reg.cvt32()); + code->and_(index_reg.cvt32(), u32(A32JitState::RSBPtrMask)); + code->mov(dword[r15 + offsetof(A32JitState, rsb_ptr)], index_reg.cvt32()); } template @@ -1839,7 +1838,7 @@ static void DenormalsAreZero32(BlockOfCode* code, Xbyak::Xmm xmm_value, Xbyak::R code->cmp(gpr_scratch, u32(0x007FFFFE)); code->ja(end); code->pxor(xmm_value, xmm_value); - code->mov(dword[r15 + offsetof(JitState, FPSCR_IDC)], u32(1 << 7)); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_IDC)], u32(1 << 7)); code->L(end); } @@ -1857,7 +1856,7 @@ static void DenormalsAreZero64(BlockOfCode* code, Xbyak::Xmm xmm_value, Xbyak::R code->cmp(gpr_scratch, penult_denormal); code->ja(end); code->pxor(xmm_value, xmm_value); - code->mov(dword[r15 + offsetof(JitState, FPSCR_IDC)], u32(1 << 7)); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_IDC)], u32(1 << 7)); code->L(end); } @@ -1870,7 +1869,7 @@ static void FlushToZero32(BlockOfCode* code, Xbyak::Xmm xmm_value, Xbyak::Reg32 code->cmp(gpr_scratch, u32(0x007FFFFE)); code->ja(end); code->pxor(xmm_value, xmm_value); - code->mov(dword[r15 + offsetof(JitState, FPSCR_UFC)], u32(1 << 3)); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_UFC)], u32(1 << 3)); code->L(end); } @@ -1888,7 +1887,7 @@ static void FlushToZero64(BlockOfCode* code, Xbyak::Xmm xmm_value, Xbyak::Reg64 code->cmp(gpr_scratch, penult_denormal); code->ja(end); code->pxor(xmm_value, xmm_value); - code->mov(dword[r15 + offsetof(JitState, FPSCR_UFC)], u32(1 << 3)); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_UFC)], u32(1 << 3)); code->L(end); } @@ -2138,7 +2137,7 @@ static void SetFpscrNzcvFromFlags(BlockOfCode* code, RegAlloc& reg_alloc) { code->rcl(cl, 3); code->shl(nzcv, cl); code->and_(nzcv, 0xF0000000); - code->mov(dword[r15 + offsetof(JitState, FPSCR_nzcv)], nzcv); + code->mov(dword[r15 + offsetof(A32JitState, FPSCR_nzcv)], nzcv); } template @@ -2463,7 +2462,7 @@ void EmitX64::EmitFPU32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* template void EmitX64::EmitAddCycles(size_t cycles) { ASSERT(cycles < std::numeric_limits::max()); - code->sub(qword[r15 + offsetof(JitState, cycles_remaining)], static_cast(cycles)); + code->sub(qword[r15 + offsetof(A32JitState, cycles_remaining)], static_cast(cycles)); } template @@ -2471,7 +2470,7 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) { Xbyak::Label label; const Xbyak::Reg32 cpsr = eax; - code->mov(cpsr, dword[r15 + offsetof(JitState, CPSR_nzcv)]); + code->mov(cpsr, dword[r15 + offsetof(A32JitState, CPSR_nzcv)]); constexpr size_t n_shift = 31; constexpr size_t z_shift = 30; diff --git a/src/backend_x64/hostloc.cpp b/src/backend_x64/hostloc.cpp index 6349e4a8..45d6806b 100644 --- a/src/backend_x64/hostloc.cpp +++ b/src/backend_x64/hostloc.cpp @@ -4,6 +4,9 @@ * General Public License version 2 or any later version. */ +#include + +#include "backend_x64/a32_jitstate.h" #include "backend_x64/hostloc.h" namespace Dynarmic { @@ -22,11 +25,11 @@ Xbyak::Xmm HostLocToXmm(HostLoc loc) { Xbyak::Address SpillToOpArg(HostLoc loc) { using namespace Xbyak::util; - static_assert(std::is_same::value, "Spill must be u64"); + static_assert(std::is_same::value, "Spill must be u64"); ASSERT(HostLocIsSpill(loc)); size_t i = static_cast(loc) - static_cast(HostLoc::FirstSpill); - return qword[r15 + offsetof(JitState, Spill) + i * sizeof(u64)]; + return qword[r15 + offsetof(A32JitState, Spill) + i * sizeof(u64)]; } } // namespace BackendX64 diff --git a/src/backend_x64/hostloc.h b/src/backend_x64/hostloc.h index 97e09f52..41b96bea 100644 --- a/src/backend_x64/hostloc.h +++ b/src/backend_x64/hostloc.h @@ -7,7 +7,7 @@ #include -#include "backend_x64/jitstate.h" +#include "backend_x64/a32_jitstate.h" #include "common/assert.h" #include "common/common_types.h" @@ -92,7 +92,7 @@ const HostLocList any_xmm = { Xbyak::Reg64 HostLocToReg64(HostLoc loc); Xbyak::Xmm HostLocToXmm(HostLoc loc); -Xbyak::Address SpillToOpArg(HostLoc loc); +Xbyak::Address SpillToOpArg(HostLoc loc); ///< TODO: Remove from this file } // namespace BackendX64 } // namespace Dynarmic diff --git a/src/backend_x64/interface_x64.cpp b/src/backend_x64/interface_x64.cpp index 2bd21beb..3c32d2d9 100644 --- a/src/backend_x64/interface_x64.cpp +++ b/src/backend_x64/interface_x64.cpp @@ -15,8 +15,8 @@ #endif #include "backend_x64/a32_emit_x64.h" +#include "backend_x64/a32_jitstate.h" #include "backend_x64/block_of_code.h" -#include "backend_x64/jitstate.h" #include "common/assert.h" #include "common/common_types.h" #include "common/scope_exit.h" @@ -41,7 +41,7 @@ struct Jit::Impl { {} BlockOfCode block_of_code; - JitState jit_state; + A32JitState jit_state; A32EmitX64 emitter; const UserCallbacks callbacks; @@ -128,7 +128,7 @@ private: static CodePtr GetCurrentBlock(void *this_voidptr) { Jit::Impl& this_ = *reinterpret_cast(this_voidptr); - JitState& jit_state = this_.jit_state; + A32JitState& jit_state = this_.jit_state; u32 pc = jit_state.Reg[15]; A32::PSR cpsr{jit_state.Cpsr()}; @@ -232,7 +232,7 @@ Context Jit::SaveContext() const { } struct Context::Impl { - JitState jit_state; + A32JitState jit_state; size_t invalid_cache_generation; }; @@ -278,7 +278,7 @@ void Context::SetFpscr(std::uint32_t value) { return impl->jit_state.SetFpscr(value); } -void TransferJitState(JitState& dest, const JitState& src, bool reset_rsb) { +void TransferJitState(A32JitState& dest, const A32JitState& src, bool reset_rsb) { dest.CPSR_ge = src.CPSR_ge; dest.CPSR_et = src.CPSR_et; dest.CPSR_q = src.CPSR_q; diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 22446c2f..8b6dfd93 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -10,7 +10,6 @@ #include #include "backend_x64/abi.h" -#include "backend_x64/jitstate.h" #include "backend_x64/reg_alloc.h" #include "common/assert.h"