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. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
aeee05f53a
commit
a7cdaf710f
@ -529,7 +529,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;
|
||||||
@ -540,22 +539,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 {
|
return false;
|
||||||
int16_t lo = value;
|
|
||||||
int hi = value - lo;
|
|
||||||
if (hi + lo != value) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
code_ptr[0] = deposit32(code_ptr[0], 0, 16, hi >> 16);
|
|
||||||
code_ptr[1] = deposit32(code_ptr[1], 0, 16, lo);
|
|
||||||
}
|
}
|
||||||
|
*code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@ -701,8 +694,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 New Issue
Block a user