Message ID | 20210922180927.666273-8-git@xen0n.name (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | LoongArch64 port of QEMU TCG | expand |
On 9/22/21 20:09, WANG Xuerui wrote: > Signed-off-by: WANG Xuerui <git@xen0n.name> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org> > --- > tcg/loongarch64/tcg-target.c.inc | 66 ++++++++++++++++++++++++++++++++ > 1 file changed, 66 insertions(+) > +/* Field Sk16, shifted right by 2; suitable for conditional jumps */ > +#define R_LOONGARCH_BR_SK16 256 > +/* Field Sd10k16, shifted right by 2; suitable for B and BL */ > +#define R_LOONGARCH_BR_SD10K16 257 > + > +static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) > +{ > + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); > + intptr_t offset = (intptr_t)target - (intptr_t)src_rx; > + > + tcg_debug_assert((offset & 3) == 0); > + offset >>= 2; > + if (offset == sextreg(offset, 0, 16)) { > + *src_rw |= (offset << 10) & 0x3fffc00; Alternatively easier to read: *src_rw = deposit64(*src_rw , 10, 16, offset); > + return true; > + } > + > + return false; > +}
Hi Philippe, On 9/23/21 02:41, Philippe Mathieu-Daudé wrote: > On 9/22/21 20:09, WANG Xuerui wrote: >> Signed-off-by: WANG Xuerui <git@xen0n.name> >> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> tcg/loongarch64/tcg-target.c.inc | 66 ++++++++++++++++++++++++++++++++ >> 1 file changed, 66 insertions(+) > >> +/* Field Sk16, shifted right by 2; suitable for conditional jumps */ >> +#define R_LOONGARCH_BR_SK16 256 >> +/* Field Sd10k16, shifted right by 2; suitable for B and BL */ >> +#define R_LOONGARCH_BR_SD10K16 257 >> + >> +static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit >> *target) >> +{ >> + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); >> + intptr_t offset = (intptr_t)target - (intptr_t)src_rx; >> + >> + tcg_debug_assert((offset & 3) == 0); >> + offset >>= 2; >> + if (offset == sextreg(offset, 0, 16)) { >> + *src_rw |= (offset << 10) & 0x3fffc00; > > Alternatively easier to read: > > *src_rw = deposit64(*src_rw , 10, 16, offset); Hmm, this helper could surely be reused at multiple places... I'll try to replace other operations like this in v4. > >> + return true; >> + } >> + >> + return false; >> +}
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index f0930f77ef..69e882ba5d 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -168,3 +168,69 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct) } return 0; } + +/* + * Relocations + */ + +/* + * Relocation records defined in LoongArch ELF psABI v1.00 is way too + * complicated; a whopping stack machine is needed to stuff the fields, at + * the very least one SOP_PUSH and one SOP_POP (of the correct format) are + * needed. + * + * Hence, define our own simpler relocation types. Numbers are chosen as to + * not collide with potential future additions to the true ELF relocation + * type enum. + */ + +/* Field Sk16, shifted right by 2; suitable for conditional jumps */ +#define R_LOONGARCH_BR_SK16 256 +/* Field Sd10k16, shifted right by 2; suitable for B and BL */ +#define R_LOONGARCH_BR_SD10K16 257 + +static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) +{ + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); + intptr_t offset = (intptr_t)target - (intptr_t)src_rx; + + tcg_debug_assert((offset & 3) == 0); + offset >>= 2; + if (offset == sextreg(offset, 0, 16)) { + *src_rw |= (offset << 10) & 0x3fffc00; + return true; + } + + return false; +} + +static bool reloc_br_sd10k16(tcg_insn_unit *src_rw, + const tcg_insn_unit *target) +{ + const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); + intptr_t offset = (intptr_t)target - (intptr_t)src_rx; + + tcg_debug_assert((offset & 3) == 0); + offset >>= 2; + if (offset == sextreg(offset, 0, 26)) { + *src_rw |= (offset >> 16) & 0x3ff; /* slot d10 */ + *src_rw |= ((offset & 0xffff) << 10) & 0x3fffc00; /* slot k16 */ + return true; + } + + return false; +} + +static bool patch_reloc(tcg_insn_unit *code_ptr, int type, + intptr_t value, intptr_t addend) +{ + tcg_debug_assert(addend == 0); + switch (type) { + case R_LOONGARCH_BR_SK16: + return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value); + case R_LOONGARCH_BR_SD10K16: + return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value); + default: + g_assert_not_reached(); + } +}