mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +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) {
|
void RiscVEmitter::QuickJAL(RiscVReg scratchreg, RiscVReg rd, const u8 *dst) {
|
||||||
if (!JInRange(GetCodePointer(), dst)) {
|
if (!JInRange(GetCodePointer(), dst)) {
|
||||||
|
int32_t lower = 0;
|
||||||
static_assert(sizeof(intptr_t) <= sizeof(int64_t));
|
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();
|
int64_t pcdelta = (int64_t)dst - (int64_t)GetCodePointer();
|
||||||
int32_t lower = (int32_t)SignReduce64(pcdelta, 12);
|
if (pcdelta < 0x100000000LL && pcdelta >= -0x100000000LL) {
|
||||||
uintptr_t upper = ((pcdelta - lower) >> 12) << 12;
|
lower = (int32_t)SignReduce64(pcdelta, 12);
|
||||||
if (scratchreg != rd)
|
uintptr_t upper = ((pcdelta - lower) >> 12) << 12;
|
||||||
LI(scratchreg, (uintptr_t)GetCodePointer() + upper, rd);
|
|
||||||
else
|
|
||||||
LI(scratchreg, (uintptr_t)GetCodePointer() + upper);
|
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);
|
JALR(rd, scratchreg, lower);
|
||||||
} else {
|
} else {
|
||||||
JAL(rd, dst);
|
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 this is just a 32-bit unsigned value, use a wall to mask.
|
||||||
if ((svalue >> 32) == 0) {
|
if ((svalue >> 32) == 0) {
|
||||||
LI(rd, (int32_t)(svalue & 0xFFFFFFFF));
|
LI(rd, (int32_t)(svalue & 0xFFFFFFFF));
|
||||||
SLLI(rd, rd, BitsSupported() - 32);
|
if (SupportsBitmanip('a')) {
|
||||||
SRLI(rd, rd, BitsSupported() - 32);
|
ZEXT_W(rd, rd);
|
||||||
|
} else {
|
||||||
|
SLLI(rd, rd, BitsSupported() - 32);
|
||||||
|
SRLI(rd, rd, BitsSupported() - 32);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1277,7 +1286,7 @@ void RiscVEmitter::SetRegToImmediate(RiscVReg rd, uint64_t value, RiscVReg temp)
|
|||||||
return;
|
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;
|
int64_t upper = svalue >> 32;
|
||||||
LI(rd, upper);
|
LI(rd, upper);
|
||||||
|
|
||||||
@ -1293,7 +1302,7 @@ void RiscVEmitter::SetRegToImmediate(RiscVReg rd, uint64_t value, RiscVReg temp)
|
|||||||
int32_t chunk = (remaining >> sourceShift) & 0x07FF;
|
int32_t chunk = (remaining >> sourceShift) & 0x07FF;
|
||||||
|
|
||||||
SLLI(rd, rd, targetShift - shifted);
|
SLLI(rd, rd, targetShift - shifted);
|
||||||
ORI(rd, rd, chunk);
|
ADDI(rd, rd, chunk);
|
||||||
|
|
||||||
// Okay, increase shift and clear the bits we've deposited.
|
// Okay, increase shift and clear the bits we've deposited.
|
||||||
shifted = targetShift;
|
shifted = targetShift;
|
||||||
|
Loading…
Reference in New Issue
Block a user