mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
riscv: Improve immediate generation.
Use compressed instructions more, better jumps when outside PC 32-bit range.
This commit is contained in:
parent
50ea506b6a
commit
fc476020ba
@ -1182,14 +1182,19 @@ bool RiscVEmitter::CJInRange(const void *src, const void *dst) const {
|
||||
|
||||
void RiscVEmitter::QuickJAL(RiscVReg scratchreg, RiscVReg rd, const u8 *dst) {
|
||||
if (!JInRange(GetCodePointer(), dst)) {
|
||||
int32_t lower = 0;
|
||||
static_assert(sizeof(intptr_t) <= sizeof(int64_t));
|
||||
// If it's near PC, we're better off shooting for AUIPC. Should take 8 bytes.
|
||||
int64_t pcdelta = (int64_t)dst - (int64_t)GetCodePointer();
|
||||
int32_t lower = (int32_t)SignReduce64(pcdelta, 12);
|
||||
uintptr_t upper = ((pcdelta - lower) >> 12) << 12;
|
||||
if (scratchreg != rd)
|
||||
LI(scratchreg, (uintptr_t)GetCodePointer() + upper, rd);
|
||||
else
|
||||
if (pcdelta < 0x100000000LL && pcdelta >= -0x100000000LL) {
|
||||
lower = (int32_t)SignReduce64(pcdelta, 12);
|
||||
uintptr_t upper = ((pcdelta - lower) >> 12) << 12;
|
||||
LI(scratchreg, (uintptr_t)GetCodePointer() + upper);
|
||||
} else {
|
||||
lower = (int32_t)SignReduce64((int64_t)dst, 12);
|
||||
// Abuse rd as a temporary if we need to.
|
||||
LI(scratchreg, dst - lower, rd == scratchreg ? R_ZERO : rd);
|
||||
}
|
||||
JALR(rd, scratchreg, lower);
|
||||
} else {
|
||||
JAL(rd, dst);
|
||||
@ -1258,8 +1263,12 @@ void RiscVEmitter::SetRegToImmediate(RiscVReg rd, uint64_t value, RiscVReg temp)
|
||||
// If this is just a 32-bit unsigned value, use a wall to mask.
|
||||
if ((svalue >> 32) == 0) {
|
||||
LI(rd, (int32_t)(svalue & 0xFFFFFFFF));
|
||||
SLLI(rd, rd, BitsSupported() - 32);
|
||||
SRLI(rd, rd, BitsSupported() - 32);
|
||||
if (SupportsBitmanip('a')) {
|
||||
ZEXT_W(rd, rd);
|
||||
} else {
|
||||
SLLI(rd, rd, BitsSupported() - 32);
|
||||
SRLI(rd, rd, BitsSupported() - 32);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1277,7 +1286,7 @@ void RiscVEmitter::SetRegToImmediate(RiscVReg rd, uint64_t value, RiscVReg temp)
|
||||
return;
|
||||
}
|
||||
|
||||
// Okay, let's just start with the upper 32 bits and add the rest via ORI.
|
||||
// Okay, let's just start with the upper 32 bits and add the rest via ADDI.
|
||||
int64_t upper = svalue >> 32;
|
||||
LI(rd, upper);
|
||||
|
||||
@ -1293,7 +1302,7 @@ void RiscVEmitter::SetRegToImmediate(RiscVReg rd, uint64_t value, RiscVReg temp)
|
||||
int32_t chunk = (remaining >> sourceShift) & 0x07FF;
|
||||
|
||||
SLLI(rd, rd, targetShift - shifted);
|
||||
ORI(rd, rd, chunk);
|
||||
ADDI(rd, rd, chunk);
|
||||
|
||||
// Okay, increase shift and clear the bits we've deposited.
|
||||
shifted = targetShift;
|
||||
|
Loading…
Reference in New Issue
Block a user