Skip to content

Commit

Permalink
Merge pull request #18060 from unknownbrackets/x86-jitbase
Browse files Browse the repository at this point in the history
x86jit: Bake emuhack mask into jitbase
  • Loading branch information
hrydgard committed Sep 3, 2023
2 parents daa0586 + 9439a43 commit 2f300c2
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 20 deletions.
5 changes: 3 additions & 2 deletions Core/MIPS/IR/IRRegCache.cpp
Expand Up @@ -784,18 +784,19 @@ void IRNativeRegCacheBase::ApplyMapping(const Mapping *mapping, int count) {
return;
}

bool mapSIMD = config_.mapFPUSIMD || mapping[i].type == 'G';
MIPSMap flags = mapping[i].flags;
for (int j = 0; j < count; ++j) {
if (mapping[j].type == mapping[i].type && mapping[j].reg == mapping[i].reg && i != j) {
_assert_msg_(mapping[j].lanes == mapping[i].lanes, "Lane aliasing not supported yet");
_assert_msg_(!mapSIMD || mapping[j].lanes == mapping[i].lanes, "Lane aliasing not supported yet");

if (!isNoinit(mapping[j].flags) && isNoinit(flags)) {
flags = (flags & MIPSMap::BACKEND_MASK) | MIPSMap::DIRTY;
}
}
}

if (config_.mapFPUSIMD || mapping[i].type == 'G') {
if (mapSIMD) {
MapNativeReg(type, mapping[i].reg, mapping[i].lanes, flags);
return;
}
Expand Down
6 changes: 2 additions & 4 deletions Core/MIPS/RiscV/RiscVAsm.cpp
Expand Up @@ -121,7 +121,7 @@ void RiscVJitBackend::GenerateFixedCode(MIPSState *mipsState) {
// Fixed registers, these are always kept when in Jit context.
LI(MEMBASEREG, Memory::base, SCRATCH1);
LI(CTXREG, mipsState, SCRATCH1);
LI(JITBASEREG, GetBasePtr(), SCRATCH1);
LI(JITBASEREG, GetBasePtr() - MIPS_EMUHACK_OPCODE, SCRATCH1);

LoadStaticRegisters();
MovFromPC(SCRATCH1);
Expand Down Expand Up @@ -173,9 +173,7 @@ void RiscVJitBackend::GenerateFixedCode(MIPSState *mipsState) {
// We're in other words comparing to the top 8 bits of MIPS_EMUHACK_OPCODE by subtracting.
ADDI(SCRATCH2, SCRATCH2, -(MIPS_EMUHACK_OPCODE >> 24));
FixupBranch needsCompile = BNE(SCRATCH2, R_ZERO);
// Use a wall to mask by 0x00FFFFFF and extract the block jit offset.
SLLI(SCRATCH1, SCRATCH1, XLEN - 24);
SRLI(SCRATCH1, SCRATCH1, XLEN - 24);
// No need to mask, JITBASEREG has already accounted for the upper bits.
ADD(SCRATCH1, JITBASEREG, SCRATCH1);
JR(SCRATCH1);
SetJumpTarget(needsCompile);
Expand Down
24 changes: 19 additions & 5 deletions Core/MIPS/RiscV/RiscVCompVec.cpp
Expand Up @@ -35,6 +35,10 @@ namespace MIPSComp {
using namespace RiscVGen;
using namespace RiscVJitConstants;

static bool Overlap(IRReg r1, int l1, IRReg r2, int l2) {
return r1 < r2 + l2 && r1 + l1 > r2;
}

void RiscVJitBackend::CompIR_VecAssign(IRInst inst) {
CONDITIONAL_DISABLE;

Expand Down Expand Up @@ -215,10 +219,21 @@ void RiscVJitBackend::CompIR_VecArith(IRInst inst) {
break;

case IROp::Vec4Scale:
// TODO: This works for now, but may need to handle aliasing for vectors.
regs_.Map(inst);
for (int i = 0; i < 4; ++i)
FMUL(32, regs_.F(inst.dest + i), regs_.F(inst.src1 + i), regs_.F(inst.src2));
if (Overlap(inst.src2, 1, inst.dest, 3)) {
// We have to handle overlap, doing dest == src2 last.
for (int i = 0; i < 4; ++i) {
if (inst.src2 != inst.dest + i)
FMUL(32, regs_.F(inst.dest + i), regs_.F(inst.src1 + i), regs_.F(inst.src2));
}
for (int i = 0; i < 4; ++i) {
if (inst.src2 == inst.dest + i)
FMUL(32, regs_.F(inst.dest + i), regs_.F(inst.src1 + i), regs_.F(inst.src2));
}
} else {
for (int i = 0; i < 4; ++i)
FMUL(32, regs_.F(inst.dest + i), regs_.F(inst.src1 + i), regs_.F(inst.src2));
}
break;

case IROp::Vec4Neg:
Expand All @@ -244,9 +259,8 @@ void RiscVJitBackend::CompIR_VecHoriz(IRInst inst) {

switch (inst.op) {
case IROp::Vec4Dot:
// TODO: This works for now, but may need to handle aliasing for vectors.
regs_.Map(inst);
if ((inst.dest < inst.src1 + 4 && inst.dest >= inst.src1) || (inst.dest < inst.src2 + 4 && inst.dest >= inst.src2)) {
if (Overlap(inst.dest, 1, inst.src1, 4) || Overlap(inst.dest, 1, inst.src2, 4)) {
// This means inst.dest overlaps one of src1 or src2. We have to do that one first.
// Technically this may impact -0.0 and such, but dots accurately need to be aligned anyway.
for (int i = 0; i < 4; ++i) {
Expand Down
4 changes: 4 additions & 0 deletions Core/MIPS/RiscV/RiscVRegCache.cpp
Expand Up @@ -205,6 +205,10 @@ RiscVGen::RiscVReg RiscVRegCache::Normalize32(IRReg mipsReg, RiscVGen::RiscVReg
emit_->SEXT_W(destReg, (RiscVReg)mr[mipsReg].nReg);
}
break;

default:
_assert_msg_(false, "Should not normalize32 floats");
break;
}

return destReg == INVALID_REG ? reg : destReg;
Expand Down
18 changes: 9 additions & 9 deletions Core/MIPS/x86/X64IRAsm.cpp
Expand Up @@ -56,15 +56,16 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) {
#if PPSSPP_ARCH(AMD64)
bool jitbaseInR15 = false;
int jitbaseCtxDisp = 0;
uintptr_t jitbase = (uintptr_t)GetBasePtr();
if (jitbase > 0x7FFFFFFFULL && !Accessible((const u8 *)&mipsState->f[0], GetBasePtr())) {
// We pre-bake the MIPS_EMUHACK_OPCODE subtraction into our jitbase value.
intptr_t jitbase = (intptr_t)GetBasePtr() - MIPS_EMUHACK_OPCODE;
if ((jitbase < -0x80000000ULL || jitbase > 0x7FFFFFFFULL) && !Accessible((const u8 *)&mipsState->f[0], GetBasePtr())) {
jo.reserveR15ForAsm = true;
jitbaseInR15 = true;
} else {
jo.downcountInRegister = true;
jo.reserveR15ForAsm = true;
if (jitbase > 0x7FFFFFFFULL) {
jitbaseCtxDisp = (int)(GetBasePtr() - (const u8 *)&mipsState->f[0]);
if (jitbase < -0x80000000ULL || jitbase > 0x7FFFFFFFULL) {
jitbaseCtxDisp = (int)(jitbase - (intptr_t)&mipsState->f[0]);
}
}
#endif
Expand Down Expand Up @@ -139,7 +140,7 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) {
// Two x64-specific statically allocated registers.
MOV(64, R(MEMBASEREG), ImmPtr(Memory::base));
if (jitbaseInR15)
MOV(64, R(JITBASEREG), ImmPtr(GetBasePtr()));
MOV(64, R(JITBASEREG), ImmPtr((const void *)jitbase));
#endif
// From the start of the FP reg, a single byte offset can reach all GPR + all FPR (but not VFPR.)
MOV(PTRBITS, R(CTXREG), ImmPtr(&mipsState->f[0]));
Expand Down Expand Up @@ -228,18 +229,17 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) {
CMP(32, R(EDX), Imm8(MIPS_EMUHACK_OPCODE >> 24));
}
FixupBranch needsCompile = J_CC(CC_NE);
// Mask by 0x00FFFFFF and extract the block jit offset.
AND(32, R(SCRATCH1), Imm32(MIPS_EMUHACK_VALUE_MASK));
// We don't mask here - that's baked into jitbase.
#if PPSSPP_ARCH(X86)
LEA(32, SCRATCH1, MDisp(SCRATCH1, (u32)GetBasePtr()));
LEA(32, SCRATCH1, MDisp(SCRATCH1, (u32)GetBasePtr() - MIPS_EMUHACK_VALUE_MASK));
#elif PPSSPP_ARCH(AMD64)
if (jitbaseInR15) {
ADD(64, R(SCRATCH1), R(JITBASEREG));
} else if (jitbaseCtxDisp) {
LEA(64, SCRATCH1, MComplex(CTXREG, SCRATCH1, SCALE_1, jitbaseCtxDisp));
} else {
// See above, reserveR15ForAsm is used when above 0x7FFFFFFF.
LEA(64, SCRATCH1, MDisp(SCRATCH1, (u32)jitbase));
LEA(64, SCRATCH1, MDisp(SCRATCH1, (s32)jitbase));
}
#endif
JMPptr(R(SCRATCH1));
Expand Down
1 change: 1 addition & 0 deletions Core/MIPS/x86/X64IRRegCache.h
Expand Up @@ -30,6 +30,7 @@ namespace X64IRJitConstants {
#if PPSSPP_ARCH(AMD64)
const Gen::X64Reg MEMBASEREG = Gen::RBX;
const Gen::X64Reg CTXREG = Gen::R14;
// Note: this is actually offset from the base.
const Gen::X64Reg JITBASEREG = Gen::R15;
const Gen::X64Reg DOWNCOUNTREG = Gen::R15;
#else
Expand Down

0 comments on commit 2f300c2

Please sign in to comment.