Message ID | 20230411010512.5375-50-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | tcg: Simplify calls to load/store helpers | expand |
On 4/10/23 22:05, Richard Henderson wrote: > Allocate TCG_REG_TMP2. Use R0, TMP1, TMP2 instead of any of > the normally allocated registers for the tlb load. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> > tcg/ppc/tcg-target.c.inc | 84 +++++++++++++++++++++++----------------- > 1 file changed, 49 insertions(+), 35 deletions(-) > > diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc > index 1b60166d2f..613cd73583 100644 > --- a/tcg/ppc/tcg-target.c.inc > +++ b/tcg/ppc/tcg-target.c.inc > @@ -68,6 +68,7 @@ > #else > # define TCG_REG_TMP1 TCG_REG_R12 > #endif > +#define TCG_REG_TMP2 TCG_REG_R11 > > #define TCG_VEC_TMP1 TCG_REG_V0 > #define TCG_VEC_TMP2 TCG_REG_V1 > @@ -2007,10 +2008,11 @@ static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { > QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); > QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768); > > -/* Perform the TLB load and compare. Places the result of the comparison > - in CR7, loads the addend of the TLB into R3, and returns the register > - containing the guest address (zero-extended into R4). Clobbers R0 and R2. */ > - > +/* > + * Perform the TLB load and compare. Places the result of the comparison > + * in CR7, loads the addend of the TLB into TMP1, and returns the register > + * containing the guest address (zero-extended into TMP2). Clobbers R0. > + */ > static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, > TCGReg addrlo, TCGReg addrhi, > int mem_index, bool is_read) > @@ -2026,40 +2028,44 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, > unsigned a_bits = get_alignment_bits(opc); > > /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */ > - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off); > - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off); > + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off); > + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_AREG0, table_off); > > /* Extract the page index, shifted into place for tlb index. */ > if (TCG_TARGET_REG_BITS == 32) { > - tcg_out_shri32(s, TCG_REG_TMP1, addrlo, > + tcg_out_shri32(s, TCG_REG_R0, addrlo, > TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); > } else { > - tcg_out_shri64(s, TCG_REG_TMP1, addrlo, > + tcg_out_shri64(s, TCG_REG_R0, addrlo, > TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); > } > - tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1)); > + tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0)); > > - /* Load the TLB comparator. */ > + /* Load the (low part) TLB comparator into TMP2. */ > if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { > uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32 > ? LWZUX : LDUX); > - tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4)); > + tcg_out32(s, lxu | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2)); > } else { > - tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4)); > + tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2)); > if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { > - tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4); > - tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off); > + tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, > + TCG_REG_TMP1, cmp_off + 4); > } else { > - tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off); > + tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off); > } > } > > - /* Load the TLB addend for use on the fast path. Do this asap > - to minimize any load use delay. */ > - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, > - offsetof(CPUTLBEntry, addend)); > + /* > + * Load the TLB addend for use on the fast path. > + * Do this asap to minimize any load use delay. > + */ > + if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { > + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, > + offsetof(CPUTLBEntry, addend)); > + } > > - /* Clear the non-page, non-alignment bits from the address */ > + /* Clear the non-page, non-alignment bits from the address into R0. */ > if (TCG_TARGET_REG_BITS == 32) { > /* We don't support unaligned accesses on 32-bits. > * Preserve the bottom bits and thus trigger a comparison > @@ -2090,9 +2096,6 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, > if (TARGET_LONG_BITS == 32) { > tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0, > (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS); > - /* Zero-extend the address for use in the final address. */ > - tcg_out_ext32u(s, TCG_REG_R4, addrlo); > - addrlo = TCG_REG_R4; > } else if (a_bits == 0) { > tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS); > } else { > @@ -2102,16 +2105,28 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, > } > } > > + /* Full or low part comparison into cr7. */ > + tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2, 0, 7, TCG_TYPE_I32); > + > if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { > - tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, > - 0, 7, TCG_TYPE_I32); > - tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32); > + tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R0, TCG_REG_TMP1, cmp_off); > + > + /* Load addend, deferred for this case. */ > + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, > + offsetof(CPUTLBEntry, addend)); > + > + /* High part comparison into cr6. */ > + tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, addrhi, 0, 6, TCG_TYPE_I32); > + > + /* Combine comparisons into cr7. */ > tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ)); > - } else { > - tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, > - 0, 7, TCG_TYPE_TL); > } > > + if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { > + /* Zero-extend the address for use in the final address. */ > + tcg_out_ext32u(s, TCG_REG_TMP2, addrlo); > + return TCG_REG_TMP2; > + } > return addrlo; > } > > @@ -2149,13 +2164,11 @@ static TCGReg ldst_ra_gen(TCGContext *s, const TCGLabelQemuLdst *l, int arg) > /* > * For the purposes of ppc32 sorting 4 input registers into 4 argument > * registers, there is an outside chance we would require 3 temps. > - * Because of constraints, no inputs are in r3, and env will not be > - * placed into r3 until after the sorting is done, and is thus free. > */ > static const TCGLdstHelperParam ldst_helper_param = { > .ra_gen = ldst_ra_gen, > .ntmp = 3, > - .tmp = { TCG_REG_TMP1, TCG_REG_R0, TCG_REG_R3 } > + .tmp = { TCG_REG_TMP1, TCG_REG_TMP2, TCG_REG_R0 } > }; > > static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) > @@ -2272,7 +2285,7 @@ static void tcg_out_qemu_ld(TCGContext *s, > label_ptr = s->code_ptr; > tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); > > - rbase = TCG_REG_R3; > + rbase = TCG_REG_TMP1; > #else /* !CONFIG_SOFTMMU */ > unsigned a_bits = get_alignment_bits(opc); > if (a_bits) { > @@ -2344,7 +2357,7 @@ static void tcg_out_qemu_st(TCGContext *s, > label_ptr = s->code_ptr; > tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); > > - rbase = TCG_REG_R3; > + rbase = TCG_REG_TMP1; > #else /* !CONFIG_SOFTMMU */ > unsigned a_bits = get_alignment_bits(opc); > if (a_bits) { > @@ -3944,7 +3957,8 @@ static void tcg_target_init(TCGContext *s) > #if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64 > tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */ > #endif > - tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */ > + tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); > + tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); > tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP1); > tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP2); > if (USE_REG_TB) {
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 1b60166d2f..613cd73583 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -68,6 +68,7 @@ #else # define TCG_REG_TMP1 TCG_REG_R12 #endif +#define TCG_REG_TMP2 TCG_REG_R11 #define TCG_VEC_TMP1 TCG_REG_V0 #define TCG_VEC_TMP2 TCG_REG_V1 @@ -2007,10 +2008,11 @@ static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768); -/* Perform the TLB load and compare. Places the result of the comparison - in CR7, loads the addend of the TLB into R3, and returns the register - containing the guest address (zero-extended into R4). Clobbers R0 and R2. */ - +/* + * Perform the TLB load and compare. Places the result of the comparison + * in CR7, loads the addend of the TLB into TMP1, and returns the register + * containing the guest address (zero-extended into TMP2). Clobbers R0. + */ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, TCGReg addrlo, TCGReg addrhi, int mem_index, bool is_read) @@ -2026,40 +2028,44 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, unsigned a_bits = get_alignment_bits(opc); /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */ - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off); - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off); + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off); + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_AREG0, table_off); /* Extract the page index, shifted into place for tlb index. */ if (TCG_TARGET_REG_BITS == 32) { - tcg_out_shri32(s, TCG_REG_TMP1, addrlo, + tcg_out_shri32(s, TCG_REG_R0, addrlo, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); } else { - tcg_out_shri64(s, TCG_REG_TMP1, addrlo, + tcg_out_shri64(s, TCG_REG_R0, addrlo, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); } - tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1)); + tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0)); - /* Load the TLB comparator. */ + /* Load the (low part) TLB comparator into TMP2. */ if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32 ? LWZUX : LDUX); - tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4)); + tcg_out32(s, lxu | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2)); } else { - tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4)); + tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2)); if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { - tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4); - tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off); + tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, + TCG_REG_TMP1, cmp_off + 4); } else { - tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off); + tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off); } } - /* Load the TLB addend for use on the fast path. Do this asap - to minimize any load use delay. */ - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, - offsetof(CPUTLBEntry, addend)); + /* + * Load the TLB addend for use on the fast path. + * Do this asap to minimize any load use delay. + */ + if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, + offsetof(CPUTLBEntry, addend)); + } - /* Clear the non-page, non-alignment bits from the address */ + /* Clear the non-page, non-alignment bits from the address into R0. */ if (TCG_TARGET_REG_BITS == 32) { /* We don't support unaligned accesses on 32-bits. * Preserve the bottom bits and thus trigger a comparison @@ -2090,9 +2096,6 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, if (TARGET_LONG_BITS == 32) { tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0, (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS); - /* Zero-extend the address for use in the final address. */ - tcg_out_ext32u(s, TCG_REG_R4, addrlo); - addrlo = TCG_REG_R4; } else if (a_bits == 0) { tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS); } else { @@ -2102,16 +2105,28 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc, } } + /* Full or low part comparison into cr7. */ + tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2, 0, 7, TCG_TYPE_I32); + if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { - tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, - 0, 7, TCG_TYPE_I32); - tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32); + tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R0, TCG_REG_TMP1, cmp_off); + + /* Load addend, deferred for this case. */ + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1, + offsetof(CPUTLBEntry, addend)); + + /* High part comparison into cr6. */ + tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, addrhi, 0, 6, TCG_TYPE_I32); + + /* Combine comparisons into cr7. */ tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ)); - } else { - tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1, - 0, 7, TCG_TYPE_TL); } + if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { + /* Zero-extend the address for use in the final address. */ + tcg_out_ext32u(s, TCG_REG_TMP2, addrlo); + return TCG_REG_TMP2; + } return addrlo; } @@ -2149,13 +2164,11 @@ static TCGReg ldst_ra_gen(TCGContext *s, const TCGLabelQemuLdst *l, int arg) /* * For the purposes of ppc32 sorting 4 input registers into 4 argument * registers, there is an outside chance we would require 3 temps. - * Because of constraints, no inputs are in r3, and env will not be - * placed into r3 until after the sorting is done, and is thus free. */ static const TCGLdstHelperParam ldst_helper_param = { .ra_gen = ldst_ra_gen, .ntmp = 3, - .tmp = { TCG_REG_TMP1, TCG_REG_R0, TCG_REG_R3 } + .tmp = { TCG_REG_TMP1, TCG_REG_TMP2, TCG_REG_R0 } }; static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) @@ -2272,7 +2285,7 @@ static void tcg_out_qemu_ld(TCGContext *s, label_ptr = s->code_ptr; tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); - rbase = TCG_REG_R3; + rbase = TCG_REG_TMP1; #else /* !CONFIG_SOFTMMU */ unsigned a_bits = get_alignment_bits(opc); if (a_bits) { @@ -2344,7 +2357,7 @@ static void tcg_out_qemu_st(TCGContext *s, label_ptr = s->code_ptr; tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK); - rbase = TCG_REG_R3; + rbase = TCG_REG_TMP1; #else /* !CONFIG_SOFTMMU */ unsigned a_bits = get_alignment_bits(opc); if (a_bits) { @@ -3944,7 +3957,8 @@ static void tcg_target_init(TCGContext *s) #if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */ #endif - tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */ + tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); + tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP1); tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP2); if (USE_REG_TB) {
Allocate TCG_REG_TMP2. Use R0, TMP1, TMP2 instead of any of the normally allocated registers for the tlb load. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/ppc/tcg-target.c.inc | 84 +++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 35 deletions(-)