Message ID | 20230808030250.50602-5-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | tcg/ppc: Support power10 prefixed instructions | expand |
On Tue Aug 8, 2023 at 1:02 PM AEST, Richard Henderson wrote: > The prefixed instruction has a pc-relative form to use here. I don't understand this code very well but going by existing relocs it looks okay. Reviewed-by: Nicholas Piggin <npiggin@gmail.com> > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > tcg/ppc/tcg-target.c.inc | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc > index 61ae9d8ab7..b3b2e9874d 100644 > --- a/tcg/ppc/tcg-target.c.inc > +++ b/tcg/ppc/tcg-target.c.inc > @@ -101,6 +101,10 @@ > #define ALL_GENERAL_REGS 0xffffffffu > #define ALL_VECTOR_REGS 0xffffffff00000000ull > > +#ifndef R_PPC64_PCREL34 > +#define R_PPC64_PCREL34 132 > +#endif > + > #define have_isel (cpuinfo & CPUINFO_ISEL) > > #ifndef CONFIG_SOFTMMU > @@ -260,6 +264,19 @@ static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target) > return false; > } > > +static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target) > +{ > + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); > + ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx); > + > + if (disp == sextract64(disp, 0, 34)) { > + src_rw[0] = (src_rw[0] & ~0x3ffff) | ((disp >> 16) & 0x3ffff); > + src_rw[1] = (src_rw[1] & ~0xffff) | (disp & 0xffff); > + return true; > + } > + return false; > +} > + > /* test if a constant matches the constraint */ > static bool tcg_target_const_match(int64_t val, TCGType type, int ct) > { > @@ -684,6 +701,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type, > return reloc_pc14(code_ptr, target); > case R_PPC_REL24: > return reloc_pc24(code_ptr, target); > + case R_PPC64_PCREL34: > + return reloc_pc34(code_ptr, target); > case R_PPC_ADDR16: > /* > * We are (slightly) abusing this relocation type. In particular, > @@ -1111,6 +1130,11 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret, > } > > /* Use the constant pool, if possible. */ > + if (have_isa_3_10) { > + tcg_out_8ls_d(s, PLD, ret, 0, 0, 1); > + new_pool_label(s, arg, R_PPC64_PCREL34, s->code_ptr - 2, 0); > + return; > + } > if (!in_prologue && USE_REG_TB) { > new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr, > tcg_tbrel_diff(s, NULL));
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 61ae9d8ab7..b3b2e9874d 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -101,6 +101,10 @@ #define ALL_GENERAL_REGS 0xffffffffu #define ALL_VECTOR_REGS 0xffffffff00000000ull +#ifndef R_PPC64_PCREL34 +#define R_PPC64_PCREL34 132 +#endif + #define have_isel (cpuinfo & CPUINFO_ISEL) #ifndef CONFIG_SOFTMMU @@ -260,6 +264,19 @@ static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target) return false; } +static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target) +{ + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); + ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx); + + if (disp == sextract64(disp, 0, 34)) { + src_rw[0] = (src_rw[0] & ~0x3ffff) | ((disp >> 16) & 0x3ffff); + src_rw[1] = (src_rw[1] & ~0xffff) | (disp & 0xffff); + return true; + } + return false; +} + /* test if a constant matches the constraint */ static bool tcg_target_const_match(int64_t val, TCGType type, int ct) { @@ -684,6 +701,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type, return reloc_pc14(code_ptr, target); case R_PPC_REL24: return reloc_pc24(code_ptr, target); + case R_PPC64_PCREL34: + return reloc_pc34(code_ptr, target); case R_PPC_ADDR16: /* * We are (slightly) abusing this relocation type. In particular, @@ -1111,6 +1130,11 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret, } /* Use the constant pool, if possible. */ + if (have_isa_3_10) { + tcg_out_8ls_d(s, PLD, ret, 0, 0, 1); + new_pool_label(s, arg, R_PPC64_PCREL34, s->code_ptr - 2, 0); + return; + } if (!in_prologue && USE_REG_TB) { new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr, tcg_tbrel_diff(s, NULL));
The prefixed instruction has a pc-relative form to use here. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/ppc/tcg-target.c.inc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)