mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 19:36:50 +00:00
tcg/ppc: Allow the constant pool to overflow at 32k
There is no point in coding for a 2GB offset when the max TB size is already limited to 64k. If we further restrict to 32k then we can eliminate the extra ADDIS instruction. Backports commit a7cdaf710f2aaaf0be855a338dd67463d4bb99e2 from qemu
This commit is contained in:
parent
6145e3fdd7
commit
187e80c9a5
|
@ -527,7 +527,6 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
||||||
intptr_t value, intptr_t addend)
|
intptr_t value, intptr_t addend)
|
||||||
{
|
{
|
||||||
tcg_insn_unit *target;
|
tcg_insn_unit *target;
|
||||||
tcg_insn_unit old;
|
|
||||||
|
|
||||||
value += addend;
|
value += addend;
|
||||||
target = (tcg_insn_unit *)value;
|
target = (tcg_insn_unit *)value;
|
||||||
|
@ -538,22 +537,16 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
|
||||||
case R_PPC_REL24:
|
case R_PPC_REL24:
|
||||||
return reloc_pc24(code_ptr, target);
|
return reloc_pc24(code_ptr, target);
|
||||||
case R_PPC_ADDR16:
|
case R_PPC_ADDR16:
|
||||||
/* We are abusing this relocation type. This points to a pair
|
/*
|
||||||
of insns, addis + load. If the displacement is small, we
|
* We are (slightly) abusing this relocation type. In particular,
|
||||||
can nop out the addis. */
|
* assert that the low 2 bits are zero, and do not modify them.
|
||||||
if (value == (int16_t)value) {
|
* That way we can use this with LD et al that have opcode bits
|
||||||
code_ptr[0] = NOP;
|
* in the low 2 bits of the insn.
|
||||||
old = deposit32(code_ptr[1], 0, 16, value);
|
*/
|
||||||
code_ptr[1] = deposit32(old, 16, 5, TCG_REG_TB);
|
if ((value & 3) || value != (int16_t)value) {
|
||||||
} else {
|
|
||||||
int16_t lo = value;
|
|
||||||
int hi = value - lo;
|
|
||||||
if (hi + lo != value) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
code_ptr[0] = deposit32(code_ptr[0], 0, 16, hi >> 16);
|
*code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
|
||||||
code_ptr[1] = deposit32(code_ptr[1], 0, 16, lo);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
@ -699,8 +692,7 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
|
||||||
if (!in_prologue && USE_REG_TB) {
|
if (!in_prologue && USE_REG_TB) {
|
||||||
new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
|
new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
|
||||||
-(intptr_t)s->code_gen_ptr);
|
-(intptr_t)s->code_gen_ptr);
|
||||||
tcg_out32(s, ADDIS | TAI(ret, TCG_REG_TB, 0));
|
tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
|
||||||
tcg_out32(s, LD | TAI(ret, ret, 0));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue