Reviewed-by: Matt Turner <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
---
tcg/riscv64/tcg-target-has.h | 12 ++++++++++--
tcg/riscv64/tcg-target.c.inc | 16 +++++++++++++++-
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/tcg/riscv64/tcg-target-has.h b/tcg/riscv64/tcg-target-has.h
index 93f8baad09f..3cdeb5c3900 100644
--- a/tcg/riscv64/tcg-target-has.h
+++ b/tcg/riscv64/tcg-target-has.h
@@ -69,7 +69,15 @@ tcg_target_sextract_valid(TCGType type, unsigned ofs,
unsigned len)
#define TCG_TARGET_deposit_valid(type, ofs, len) 0
-#define TCG_TARGET_lea_sh_valid(type, sh) 0
-#define TCG_TARGET_lea_imm_valid(type, imm) 0
+/*
+ * The SH*ADD instructions only operate on full register width.
+ * To allow TCG_TYPE_I32, we'd need a subsequent extension,
+ * with the result no better than the separate shift+add insns.
+ */
+#define TCG_TARGET_lea_sh_valid(type, sh) \
+ (cpuinfo & CPUINFO_ZBA && \
+ (type) == TCG_TYPE_REG && \
+ (sh) >= 1 && (sh) <= 3)
+#define TCG_TARGET_lea_imm_valid(type, imm) ((imm) == 0)
#endif
diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
index df4c4a9789b..ba7aab9246c 100644
--- a/tcg/riscv64/tcg-target.c.inc
+++ b/tcg/riscv64/tcg-target.c.inc
@@ -224,6 +224,7 @@ typedef enum {
/* Zba: Bit manipulation extension, address generation */
OPC_ADD_UW = 0x0800003b,
+ OPC_SHxADD = 0x20000033, /* plus sh << 13 */
/* Zbb: Bit manipulation extension, basic bit manipulation */
OPC_ANDN = 0x40007033,
@@ -2725,8 +2726,21 @@ static const TCGOutOpStore outop_st = {
.out_r = tcg_out_st,
};
+static void tgen_lea(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
+ TCGReg a2, unsigned sh, tcg_target_long imm)
+{
+ tcg_out32(s, encode_r(OPC_SHxADD, a0, a2, a1) | (sh << 13));
+}
+
+static TCGConstraintSetIndex cset_zba_rrr(TCGType type, unsigned flags)
+{
+ return cpuinfo & CPUINFO_ZBA ? C_O1_I2(r, r, r) : C_NotImplemented;
+}
+
static const TCGOutOpLea outop_lea = {
- .base.static_constraint = C_NotImplemented,
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_zba_rrr,
+ .out = tgen_lea,
};
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
--
2.53.0