The instruction is a combined zero-extend and add.
Use it for exactly that.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.c.inc | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 53a7f97b29..f64eaa8515 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1039,14 +1039,18 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0);
/* TLB Hit - translate address using addend. */
- addr_adj = addr_reg;
- if (TARGET_LONG_BITS == 32) {
- addr_adj = TCG_REG_TMP0;
- tcg_out_ext32u(s, addr_adj, addr_reg);
+ if (TARGET_LONG_BITS == 64) {
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
+ } else if (have_zba) {
+ tcg_out_opc_reg(s, OPC_ADD_UW, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
+ } else {
+ tcg_out_ext32u(s, TCG_REG_TMP0, addr_reg);
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP0, TCG_REG_TMP2);
}
- tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addr_adj);
*pbase = TCG_REG_TMP0;
#else
+ TCGReg base;
+
if (a_mask) {
ldst = new_ldst_label(s);
ldst->is_ld = is_ld;
@@ -1061,14 +1065,21 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP1, TCG_REG_ZERO, 0);
}
- TCGReg base = addr_reg;
- if (TARGET_LONG_BITS == 32) {
- tcg_out_ext32u(s, TCG_REG_TMP0, base);
- base = TCG_REG_TMP0;
- }
if (guest_base != 0) {
- tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
base = TCG_REG_TMP0;
+ if (TARGET_LONG_BITS == 64) {
+ tcg_out_opc_reg(s, OPC_ADD, base, addr_reg, TCG_GUEST_BASE_REG);
+ } else if (have_zba) {
+ tcg_out_opc_reg(s, OPC_ADD_UW, base, addr_reg, TCG_GUEST_BASE_REG);
+ } else {
+ tcg_out_ext32u(s, base, addr_reg);
+ tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_GUEST_BASE_REG);
+ }
+ } else if (TARGET_LONG_BITS == 64) {
+ base = addr_reg;
+ } else {
+ base = TCG_REG_TMP0;
+ tcg_out_ext32u(s, base, addr_reg);
}
*pbase = base;
#endif
--
2.34.1
On Wed, May 3, 2023 at 6:58 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The instruction is a combined zero-extend and add.
> Use it for exactly that.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.c.inc | 33 ++++++++++++++++++++++-----------
> 1 file changed, 22 insertions(+), 11 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 53a7f97b29..f64eaa8515 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1039,14 +1039,18 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
> tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0);
>
> /* TLB Hit - translate address using addend. */
> - addr_adj = addr_reg;
> - if (TARGET_LONG_BITS == 32) {
> - addr_adj = TCG_REG_TMP0;
> - tcg_out_ext32u(s, addr_adj, addr_reg);
> + if (TARGET_LONG_BITS == 64) {
> + tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
> + } else if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
> + } else {
> + tcg_out_ext32u(s, TCG_REG_TMP0, addr_reg);
> + tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP0, TCG_REG_TMP2);
> }
> - tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addr_adj);
> *pbase = TCG_REG_TMP0;
> #else
> + TCGReg base;
> +
> if (a_mask) {
> ldst = new_ldst_label(s);
> ldst->is_ld = is_ld;
> @@ -1061,14 +1065,21 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
> tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP1, TCG_REG_ZERO, 0);
> }
>
> - TCGReg base = addr_reg;
> - if (TARGET_LONG_BITS == 32) {
> - tcg_out_ext32u(s, TCG_REG_TMP0, base);
> - base = TCG_REG_TMP0;
> - }
> if (guest_base != 0) {
> - tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
> base = TCG_REG_TMP0;
> + if (TARGET_LONG_BITS == 64) {
> + tcg_out_opc_reg(s, OPC_ADD, base, addr_reg, TCG_GUEST_BASE_REG);
> + } else if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, base, addr_reg, TCG_GUEST_BASE_REG);
> + } else {
> + tcg_out_ext32u(s, base, addr_reg);
> + tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_GUEST_BASE_REG);
> + }
> + } else if (TARGET_LONG_BITS == 64) {
> + base = addr_reg;
> + } else {
> + base = TCG_REG_TMP0;
> + tcg_out_ext32u(s, base, addr_reg);
> }
> *pbase = base;
> #endif
> --
> 2.34.1
>
>
On 5/3/23 05:56, Richard Henderson wrote:
> The instruction is a combined zero-extend and add.
> Use it for exactly that.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/riscv/tcg-target.c.inc | 33 ++++++++++++++++++++++-----------
> 1 file changed, 22 insertions(+), 11 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 53a7f97b29..f64eaa8515 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1039,14 +1039,18 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
> tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0);
>
> /* TLB Hit - translate address using addend. */
> - addr_adj = addr_reg;
> - if (TARGET_LONG_BITS == 32) {
> - addr_adj = TCG_REG_TMP0;
> - tcg_out_ext32u(s, addr_adj, addr_reg);
> + if (TARGET_LONG_BITS == 64) {
> + tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
> + } else if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
> + } else {
> + tcg_out_ext32u(s, TCG_REG_TMP0, addr_reg);
> + tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP0, TCG_REG_TMP2);
> }
> - tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addr_adj);
> *pbase = TCG_REG_TMP0;
> #else
> + TCGReg base;
> +
> if (a_mask) {
> ldst = new_ldst_label(s);
> ldst->is_ld = is_ld;
> @@ -1061,14 +1065,21 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
> tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP1, TCG_REG_ZERO, 0);
> }
>
> - TCGReg base = addr_reg;
> - if (TARGET_LONG_BITS == 32) {
> - tcg_out_ext32u(s, TCG_REG_TMP0, base);
> - base = TCG_REG_TMP0;
> - }
> if (guest_base != 0) {
> - tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
> base = TCG_REG_TMP0;
> + if (TARGET_LONG_BITS == 64) {
> + tcg_out_opc_reg(s, OPC_ADD, base, addr_reg, TCG_GUEST_BASE_REG);
> + } else if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, base, addr_reg, TCG_GUEST_BASE_REG);
> + } else {
> + tcg_out_ext32u(s, base, addr_reg);
> + tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_GUEST_BASE_REG);
> + }
> + } else if (TARGET_LONG_BITS == 64) {
> + base = addr_reg;
> + } else {
> + base = TCG_REG_TMP0;
> + tcg_out_ext32u(s, base, addr_reg);
I tried to find a way to remove some of these IFs but all my alternatives weren't
much better.
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> }
> *pbase = base;
> #endif
© 2016 - 2026 Red Hat, Inc.