* [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions
@ 2023-05-03 8:56 Richard Henderson
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
` (11 more replies)
0 siblings, 12 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Based-on: 20230503070656.1746170-1-richard.henderson@linaro.org
("[PATCH v4 00/57] tcg: Improve atomicity support")
I've been vaguely following the __hw_probe syscall progress
in the upstream kernel. The initial version only handled
bog standard F+D and C extensions, which everything expects
to be present anyway, which was disappointing. But at least
the basis is there for proper extensions.
In the meantime, probe via sigill. Tested with qemu-on-qemu.
I understand the Ventana core has all of these, if you'd be
so kind as to test.
r~
Richard Henderson (11):
disas/riscv: Decode czero.{eqz,nez}
tcg/riscv: Probe for Zba, Zbb, Zicond extensions
tcg/riscv: Support ANDN, ORN, XNOR from Zbb
tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb
tcg/riscv: Use ADD.UW for guest address generation
tcg/riscv: Support rotates from Zbb
tcg/riscv: Support REV8 from Zbb
tcg/riscv: Support CPOP from Zbb
tcg/riscv: Improve setcond expansion
tcg/riscv: Implement movcond
tcg/riscv: Support CTZ, CLZ from Zbb
tcg/riscv/tcg-target-con-set.h | 3 +
tcg/riscv/tcg-target-con-str.h | 1 +
tcg/riscv/tcg-target.h | 48 +--
disas/riscv.c | 8 +-
tcg/riscv/tcg-target.c.inc | 612 +++++++++++++++++++++++++++++----
5 files changed, 587 insertions(+), 85 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez}
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:33 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions Richard Henderson
` (10 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
disas/riscv.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/disas/riscv.c b/disas/riscv.c
index d6b0fbe5e8..c0a8b1006a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -935,6 +935,8 @@ typedef enum {
rv_op_vsetvli = 766,
rv_op_vsetivli = 767,
rv_op_vsetvl = 768,
+ rv_op_czero_eqz = 769,
+ rv_op_czero_nez = 770,
} rv_op;
/* structures */
@@ -2066,7 +2068,9 @@ const rv_opcode_data opcode_data[] = {
{ "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 },
{ "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 },
{ "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 },
- { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 }
+ { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 },
+ { "czero.eqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+ { "czero.nez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2792,6 +2796,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 45: op = rv_op_minu; break;
case 46: op = rv_op_max; break;
case 47: op = rv_op_maxu; break;
+ case 075: op = rv_op_czero_eqz; break;
+ case 077: op = rv_op_czero_nez; break;
case 130: op = rv_op_sh1add; break;
case 132: op = rv_op_sh2add; break;
case 134: op = rv_op_sh3add; break;
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:35 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb Richard Henderson
` (9 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Define a useful subset of the extensions. Probe for them
via compiler pre-processor feature macros and SIGILL.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.h | 6 +++
tcg/riscv/tcg-target.c.inc | 96 ++++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 494c986b49..863ac8ba2f 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -90,6 +90,12 @@ typedef enum {
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
+#if defined(__riscv_arch_test) && defined(__riscv_zbb)
+# define have_zbb true
+#else
+extern bool have_zbb;
+#endif
+
/* optional instructions */
#define TCG_TARGET_HAS_movcond_i32 0
#define TCG_TARGET_HAS_div_i32 1
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 4dd33c73e8..49ff9c8b9d 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = {
TCG_REG_A7,
};
+#ifndef have_zbb
+bool have_zbb;
+#endif
+#if defined(__riscv_arch_test) && defined(__riscv_zba)
+# define have_zba true
+#else
+static bool have_zba;
+#endif
+#if defined(__riscv_arch_test) && defined(__riscv_zicond)
+# define have_zicond true
+#else
+static bool have_zicond;
+#endif
+
static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
{
tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
@@ -234,6 +248,34 @@ typedef enum {
OPC_FENCE = 0x0000000f,
OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */
+
+ /* Zba: Bit manipulation extension, address generation */
+ OPC_ADD_UW = 0x0800003b,
+
+ /* Zbb: Bit manipulation extension, basic bit manipulaton */
+ OPC_ANDN = 0x40007033,
+ OPC_CLZ = 0x60001013,
+ OPC_CLZW = 0x6000101b,
+ OPC_CPOP = 0x60201013,
+ OPC_CPOPW = 0x6020101b,
+ OPC_CTZ = 0x60101013,
+ OPC_CTZW = 0x6010101b,
+ OPC_ORN = 0x40006033,
+ OPC_REV8 = 0x6b805013,
+ OPC_ROL = 0x60001033,
+ OPC_ROLW = 0x6000103b,
+ OPC_ROR = 0x60005033,
+ OPC_RORW = 0x6000503b,
+ OPC_RORI = 0x60005013,
+ OPC_RORIW = 0x6000501b,
+ OPC_SEXT_B = 0x60401013,
+ OPC_SEXT_H = 0x60501013,
+ OPC_XNOR = 0x40004033,
+ OPC_ZEXT_H = 0x0800403b,
+
+ /* Zicond: integer conditional operations */
+ OPC_CZERO_EQZ = 0x0e005033,
+ OPC_CZERO_NEZ = 0x0e007033,
} RISCVInsn;
/*
@@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s)
tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
}
+static volatile sig_atomic_t got_sigill;
+
+static void sigill_handler(int signo, siginfo_t *si, void *data)
+{
+ /* Skip the faulty instruction */
+ ucontext_t *uc = (ucontext_t *)data;
+ uc->uc_mcontext.__gregs[REG_PC] += 4;
+
+ got_sigill = 1;
+}
+
+static void tcg_target_detect_isa(void)
+{
+#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond)
+ /*
+ * TODO: It is expected that this will be determinable via
+ * linux riscv_hwprobe syscall, not yet merged.
+ * In the meantime, test via sigill.
+ */
+
+ struct sigaction sa_old, sa_new;
+
+ memset(&sa_new, 0, sizeof(sa_new));
+ sa_new.sa_flags = SA_SIGINFO;
+ sa_new.sa_sigaction = sigill_handler;
+ sigaction(SIGILL, &sa_new, &sa_old);
+
+#ifndef have_zba
+ /* Probe for Zba: add.uw zero,zero,zero. */
+ got_sigill = 0;
+ asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory");
+ have_zba = !got_sigill;
+#endif
+
+#ifndef have_zbb
+ /* Probe for Zba: andn zero,zero,zero. */
+ got_sigill = 0;
+ asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory");
+ have_zbb = !got_sigill;
+#endif
+
+#ifndef have_zicond
+ /* Probe for Zicond: czero.eqz zero,zero,zero. */
+ got_sigill = 0;
+ asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory");
+ have_zicond = !got_sigill;
+#endif
+
+ sigaction(SIGILL, &sa_old, NULL);
+#endif
+}
+
static void tcg_target_init(TCGContext *s)
{
+ tcg_target_detect_isa();
+
tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
2023-05-03 8:56 ` [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:38 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb Richard Henderson
` (8 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target-con-set.h | 1 +
tcg/riscv/tcg-target-con-str.h | 1 +
tcg/riscv/tcg-target.h | 12 +++++-----
tcg/riscv/tcg-target.c.inc | 41 ++++++++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index d88888d3ac..1a33ece98f 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -15,6 +15,7 @@ C_O0_I2(rZ, rZ)
C_O1_I1(r, r)
C_O1_I2(r, r, ri)
C_O1_I2(r, r, rI)
+C_O1_I2(r, r, rJ)
C_O1_I2(r, rZ, rN)
C_O1_I2(r, rZ, rZ)
C_O2_I4(r, r, rZ, rZ, rM, rM)
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
index 6f1cfb976c..d5c419dff1 100644
--- a/tcg/riscv/tcg-target-con-str.h
+++ b/tcg/riscv/tcg-target-con-str.h
@@ -15,6 +15,7 @@ REGS('r', ALL_GENERAL_REGS)
* CONST(letter, TCG_CT_CONST_* bit set)
*/
CONST('I', TCG_CT_CONST_S12)
+CONST('J', TCG_CT_CONST_J12)
CONST('N', TCG_CT_CONST_N12)
CONST('M', TCG_CT_CONST_M12)
CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 863ac8ba2f..9f58d46208 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -120,9 +120,9 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_bswap32_i32 0
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_neg_i32 1
-#define TCG_TARGET_HAS_andc_i32 0
-#define TCG_TARGET_HAS_orc_i32 0
-#define TCG_TARGET_HAS_eqv_i32 0
+#define TCG_TARGET_HAS_andc_i32 have_zbb
+#define TCG_TARGET_HAS_orc_i32 have_zbb
+#define TCG_TARGET_HAS_eqv_i32 have_zbb
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 0
@@ -154,9 +154,9 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_bswap64_i64 0
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_neg_i64 1
-#define TCG_TARGET_HAS_andc_i64 0
-#define TCG_TARGET_HAS_orc_i64 0
-#define TCG_TARGET_HAS_eqv_i64 0
+#define TCG_TARGET_HAS_andc_i64 have_zbb
+#define TCG_TARGET_HAS_orc_i64 have_zbb
+#define TCG_TARGET_HAS_eqv_i64 have_zbb
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 49ff9c8b9d..c5b060023f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -138,6 +138,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
#define TCG_CT_CONST_S12 0x200
#define TCG_CT_CONST_N12 0x400
#define TCG_CT_CONST_M12 0x800
+#define TCG_CT_CONST_J12 0x1000
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
@@ -174,6 +175,13 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
return 1;
}
+ /*
+ * Inverse of sign extended from 12 bits: ~[-0x800, 0x7ff].
+ * Used to map ANDN back to ANDI, etc.
+ */
+ if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
+ return 1;
+ }
return 0;
}
@@ -1306,6 +1314,31 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ case INDEX_op_andc_i32:
+ case INDEX_op_andc_i64:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_ANDI, a0, a1, ~a2);
+ } else {
+ tcg_out_opc_reg(s, OPC_ANDN, a0, a1, a2);
+ }
+ break;
+ case INDEX_op_orc_i32:
+ case INDEX_op_orc_i64:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_ORI, a0, a1, ~a2);
+ } else {
+ tcg_out_opc_reg(s, OPC_ORN, a0, a1, a2);
+ }
+ break;
+ case INDEX_op_eqv_i32:
+ case INDEX_op_eqv_i64:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_XORI, a0, a1, ~a2);
+ } else {
+ tcg_out_opc_reg(s, OPC_XNOR, a0, a1, a2);
+ }
+ break;
+
case INDEX_op_not_i32:
case INDEX_op_not_i64:
tcg_out_opc_imm(s, OPC_XORI, a0, a1, -1);
@@ -1536,6 +1569,14 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_xor_i64:
return C_O1_I2(r, r, rI);
+ case INDEX_op_andc_i32:
+ case INDEX_op_andc_i64:
+ case INDEX_op_orc_i32:
+ case INDEX_op_orc_i64:
+ case INDEX_op_eqv_i32:
+ case INDEX_op_eqv_i64:
+ return C_O1_I2(r, r, rJ);
+
case INDEX_op_sub_i32:
case INDEX_op_sub_i64:
return C_O1_I2(r, rZ, rN);
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (2 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:39 ` Daniel Henrique Barboza
2023-05-16 23:40 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation Richard Henderson
` (7 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.c.inc | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index c5b060023f..53a7f97b29 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -593,26 +593,42 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
{
- tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
- tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
+ if (have_zbb) {
+ tcg_out_opc_reg(s, OPC_ZEXT_H, ret, arg, TCG_REG_ZERO);
+ } else {
+ tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
+ tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
+ }
}
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
{
- tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
- tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
+ if (have_zba) {
+ tcg_out_opc_reg(s, OPC_ADD_UW, ret, arg, TCG_REG_ZERO);
+ } else {
+ tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
+ tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
+ }
}
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
- tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
- tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
+ if (have_zbb) {
+ tcg_out_opc_imm(s, OPC_SEXT_B, ret, arg, 0);
+ } else {
+ tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
+ tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
+ }
}
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
- tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
- tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
+ if (have_zbb) {
+ tcg_out_opc_imm(s, OPC_SEXT_H, ret, arg, 0);
+ } else {
+ tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
+ tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
+ }
}
static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (3 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:43 ` Daniel Henrique Barboza
2023-05-16 23:43 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 06/11] tcg/riscv: Support rotates from Zbb Richard Henderson
` (6 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
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
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 06/11] tcg/riscv: Support rotates from Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (4 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:44 ` Daniel Henrique Barboza
2023-05-16 23:48 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 07/11] tcg/riscv: Support REV8 " Richard Henderson
` (5 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.h | 4 ++--
tcg/riscv/tcg-target.c.inc | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 9f58d46208..317d385924 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -101,7 +101,7 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
-#define TCG_TARGET_HAS_rot_i32 0
+#define TCG_TARGET_HAS_rot_i32 have_zbb
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_extract_i32 0
#define TCG_TARGET_HAS_sextract_i32 0
@@ -136,7 +136,7 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
-#define TCG_TARGET_HAS_rot_i64 0
+#define TCG_TARGET_HAS_rot_i64 have_zbb
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_extract_i64 0
#define TCG_TARGET_HAS_sextract_i64 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index f64eaa8515..58f969b4fe 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1458,6 +1458,36 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ case INDEX_op_rotl_i32:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_RORIW, a0, a1, -a2 & 0x1f);
+ } else {
+ tcg_out_opc_reg(s, OPC_ROLW, a0, a1, a2);
+ }
+ break;
+ case INDEX_op_rotl_i64:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_RORI, a0, a1, -a2 & 0x3f);
+ } else {
+ tcg_out_opc_reg(s, OPC_ROL, a0, a1, a2);
+ }
+ break;
+
+ case INDEX_op_rotr_i32:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_RORIW, a0, a1, a2 & 0x1f);
+ } else {
+ tcg_out_opc_reg(s, OPC_RORW, a0, a1, a2);
+ }
+ break;
+ case INDEX_op_rotr_i64:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_RORI, a0, a1, a2 & 0x3f);
+ } else {
+ tcg_out_opc_reg(s, OPC_ROR, a0, a1, a2);
+ }
+ break;
+
case INDEX_op_add2_i32:
tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
const_args[4], const_args[5], false, true);
@@ -1629,9 +1659,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_shl_i32:
case INDEX_op_shr_i32:
case INDEX_op_sar_i32:
+ case INDEX_op_rotl_i32:
+ case INDEX_op_rotr_i32:
case INDEX_op_shl_i64:
case INDEX_op_shr_i64:
case INDEX_op_sar_i64:
+ case INDEX_op_rotl_i64:
+ case INDEX_op_rotr_i64:
return C_O1_I2(r, r, ri);
case INDEX_op_brcond_i32:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 07/11] tcg/riscv: Support REV8 from Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (5 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 06/11] tcg/riscv: Support rotates from Zbb Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 08/11] tcg/riscv: Support CPOP " Richard Henderson
` (4 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.h | 10 +++++-----
tcg/riscv/tcg-target.c.inc | 29 +++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 317d385924..8e327afc3a 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -116,8 +116,8 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
-#define TCG_TARGET_HAS_bswap16_i32 0
-#define TCG_TARGET_HAS_bswap32_i32 0
+#define TCG_TARGET_HAS_bswap16_i32 have_zbb
+#define TCG_TARGET_HAS_bswap32_i32 have_zbb
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_andc_i32 have_zbb
@@ -149,9 +149,9 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
-#define TCG_TARGET_HAS_bswap16_i64 0
-#define TCG_TARGET_HAS_bswap32_i64 0
-#define TCG_TARGET_HAS_bswap64_i64 0
+#define TCG_TARGET_HAS_bswap16_i64 have_zbb
+#define TCG_TARGET_HAS_bswap32_i64 have_zbb
+#define TCG_TARGET_HAS_bswap64_i64 have_zbb
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_andc_i64 have_zbb
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 58f969b4fe..9cbefb2833 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1488,6 +1488,30 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ case INDEX_op_bswap64_i64:
+ tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
+ break;
+ case INDEX_op_bswap32_i32:
+ a2 = 0;
+ /* fall through */
+ case INDEX_op_bswap32_i64:
+ tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
+ if (a2 & TCG_BSWAP_OZ) {
+ tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 32);
+ } else {
+ tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 32);
+ }
+ break;
+ case INDEX_op_bswap16_i64:
+ case INDEX_op_bswap16_i32:
+ tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
+ if (a2 & TCG_BSWAP_OZ) {
+ tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 48);
+ } else {
+ tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 48);
+ }
+ break;
+
case INDEX_op_add2_i32:
tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
const_args[4], const_args[5], false, true);
@@ -1605,6 +1629,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extrl_i64_i32:
case INDEX_op_extrh_i64_i32:
case INDEX_op_ext_i32_i64:
+ case INDEX_op_bswap16_i32:
+ case INDEX_op_bswap32_i32:
+ case INDEX_op_bswap16_i64:
+ case INDEX_op_bswap32_i64:
+ case INDEX_op_bswap64_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 08/11] tcg/riscv: Support CPOP from Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (6 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 07/11] tcg/riscv: Support REV8 " Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 09/11] tcg/riscv: Improve setcond expansion Richard Henderson
` (3 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.h | 4 ++--
tcg/riscv/tcg-target.c.inc | 9 +++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 8e327afc3a..e0b23006c4 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -127,7 +127,7 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
-#define TCG_TARGET_HAS_ctpop_i32 0
+#define TCG_TARGET_HAS_ctpop_i32 have_zbb
#define TCG_TARGET_HAS_brcond2 1
#define TCG_TARGET_HAS_setcond2 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
@@ -161,7 +161,7 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
-#define TCG_TARGET_HAS_ctpop_i64 0
+#define TCG_TARGET_HAS_ctpop_i64 have_zbb
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 9cbefb2833..044ddfb160 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1512,6 +1512,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ case INDEX_op_ctpop_i32:
+ tcg_out_opc_imm(s, OPC_CPOPW, a0, a1, 0);
+ break;
+ case INDEX_op_ctpop_i64:
+ tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
+ break;
+
case INDEX_op_add2_i32:
tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
const_args[4], const_args[5], false, true);
@@ -1634,6 +1641,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_bswap16_i64:
case INDEX_op_bswap32_i64:
case INDEX_op_bswap64_i64:
+ case INDEX_op_ctpop_i32:
+ case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 09/11] tcg/riscv: Improve setcond expansion
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (7 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 08/11] tcg/riscv: Support CPOP " Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:46 ` Daniel Henrique Barboza
2023-05-17 0:16 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 10/11] tcg/riscv: Implement movcond Richard Henderson
` (2 subsequent siblings)
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Split out a helper function, tcg_out_setcond_int, which does not
always produce the complete boolean result, but returns a set of
flags to do so.
Based on 21af16198425, the same improvement for loongarch64.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target.c.inc | 164 +++++++++++++++++++++++++++----------
1 file changed, 121 insertions(+), 43 deletions(-)
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 044ddfb160..84b646105c 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -812,50 +812,128 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
tcg_out_opc_branch(s, op, arg1, arg2, 0);
}
-static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
- TCGReg arg1, TCGReg arg2)
+#define SETCOND_INV TCG_TARGET_NB_REGS
+#define SETCOND_NEZ (SETCOND_INV << 1)
+#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
+
+static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg arg1, tcg_target_long arg2, bool c2)
{
+ int flags = 0;
+
switch (cond) {
- case TCG_COND_EQ:
- tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
- tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
- break;
- case TCG_COND_NE:
- tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
- tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
- break;
- case TCG_COND_LT:
- tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
- break;
- case TCG_COND_GE:
- tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
- tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
- break;
- case TCG_COND_LE:
- tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
- tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
- break;
- case TCG_COND_GT:
- tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
- break;
- case TCG_COND_LTU:
- tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
- break;
- case TCG_COND_GEU:
- tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
- tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
- break;
- case TCG_COND_LEU:
- tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
- tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
- break;
- case TCG_COND_GTU:
- tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
+ case TCG_COND_EQ: /* -> NE */
+ case TCG_COND_GE: /* -> LT */
+ case TCG_COND_GEU: /* -> LTU */
+ case TCG_COND_GT: /* -> LE */
+ case TCG_COND_GTU: /* -> LEU */
+ cond = tcg_invert_cond(cond);
+ flags ^= SETCOND_INV;
break;
default:
- g_assert_not_reached();
- break;
- }
+ break;
+ }
+
+ switch (cond) {
+ case TCG_COND_LE:
+ case TCG_COND_LEU:
+ /*
+ * If we have a constant input, the most efficient way to implement
+ * LE is by adding 1 and using LT. Watch out for wrap around for LEU.
+ * We don't need to care for this for LE because the constant input
+ * is constrained to signed 12-bit, and 0x800 is representable in the
+ * temporary register.
+ */
+ if (c2) {
+ if (cond == TCG_COND_LEU) {
+ /* unsigned <= -1 is true */
+ if (arg2 == -1) {
+ tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
+ return ret;
+ }
+ cond = TCG_COND_LTU;
+ } else {
+ cond = TCG_COND_LT;
+ }
+ tcg_debug_assert(arg2 <= 0x7ff);
+ if (++arg2 == 0x800) {
+ tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
+ arg2 = TCG_REG_TMP0;
+ c2 = false;
+ }
+ } else {
+ TCGReg tmp = arg2;
+ arg2 = arg1;
+ arg1 = tmp;
+ cond = tcg_swap_cond(cond); /* LE -> GE */
+ cond = tcg_invert_cond(cond); /* GE -> LT */
+ flags ^= SETCOND_INV;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (cond) {
+ case TCG_COND_NE:
+ flags |= SETCOND_NEZ;
+ if (!c2) {
+ tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
+ } else if (arg2 == 0) {
+ ret = arg1;
+ } else {
+ tcg_out_opc_reg(s, OPC_XORI, ret, arg1, arg2);
+ }
+ break;
+
+ case TCG_COND_LT:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_SLTI, ret, arg1, arg2);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
+ }
+ break;
+
+ case TCG_COND_LTU:
+ if (c2) {
+ tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, arg2);
+ } else {
+ tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
+ }
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ return ret | flags;
+}
+
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg arg1, tcg_target_long arg2, bool c2)
+{
+ int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
+
+ if (tmpflags != ret) {
+ TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
+
+ switch (tmpflags & SETCOND_FLAGS) {
+ case SETCOND_INV:
+ /* Intermediate result is boolean: simply invert. */
+ tcg_out_opc_imm(s, OPC_XORI, ret, tmp, 1);
+ break;
+ case SETCOND_NEZ:
+ /* Intermediate result is zero/non-zero: test != 0. */
+ tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp);
+ break;
+ case SETCOND_NEZ | SETCOND_INV:
+ /* Intermediate result is zero/non-zero: test == 0. */
+ tcg_out_opc_imm(s, OPC_SLTIU, ret, tmp, 1);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
}
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
@@ -1543,7 +1621,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_setcond_i32:
case INDEX_op_setcond_i64:
- tcg_out_setcond(s, args[3], a0, a1, a2);
+ tcg_out_setcond(s, args[3], a0, a1, a2, c2);
break;
case INDEX_op_qemu_ld_i32:
@@ -1662,6 +1740,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_and_i64:
case INDEX_op_or_i64:
case INDEX_op_xor_i64:
+ case INDEX_op_setcond_i32:
+ case INDEX_op_setcond_i64:
return C_O1_I2(r, r, rI);
case INDEX_op_andc_i32:
@@ -1683,7 +1763,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_divu_i32:
case INDEX_op_rem_i32:
case INDEX_op_remu_i32:
- case INDEX_op_setcond_i32:
case INDEX_op_mul_i64:
case INDEX_op_mulsh_i64:
case INDEX_op_muluh_i64:
@@ -1691,7 +1770,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_divu_i64:
case INDEX_op_rem_i64:
case INDEX_op_remu_i64:
- case INDEX_op_setcond_i64:
return C_O1_I2(r, rZ, rZ);
case INDEX_op_shl_i32:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 10/11] tcg/riscv: Implement movcond
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (8 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 09/11] tcg/riscv: Improve setcond expansion Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 0:19 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb Richard Henderson
2023-05-08 12:53 ` [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Daniel Henrique Barboza
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Implement with and without Zicond. Without Zicond, we were letting
the middle-end expand to a 5 insn sequence; better to use a branch
over a single insn.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target-con-set.h | 1 +
tcg/riscv/tcg-target.h | 4 +-
tcg/riscv/tcg-target.c.inc | 139 ++++++++++++++++++++++++++++++++-
3 files changed, 141 insertions(+), 3 deletions(-)
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index 1a33ece98f..a5cadd303f 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -18,4 +18,5 @@ C_O1_I2(r, r, rI)
C_O1_I2(r, r, rJ)
C_O1_I2(r, rZ, rN)
C_O1_I2(r, rZ, rZ)
+C_O1_I4(r, r, rI, rM, rM)
C_O2_I4(r, r, rZ, rZ, rM, rM)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index e0b23006c4..e9e84be9a5 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -97,7 +97,7 @@ extern bool have_zbb;
#endif
/* optional instructions */
-#define TCG_TARGET_HAS_movcond_i32 0
+#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
@@ -132,7 +132,7 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_setcond2 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
-#define TCG_TARGET_HAS_movcond_i64 0
+#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 84b646105c..1c57b64182 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -169,7 +169,7 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
}
/*
* Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
- * Used by addsub2, which may need the negative operation,
+ * Used by addsub2 and movcond, which may need the negative value,
* and requires the modified constant to be representable.
*/
if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
@@ -936,6 +936,133 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
}
}
+static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne,
+ int val1, bool c_val1,
+ int val2, bool c_val2)
+{
+ if (val1 == 0) {
+ if (c_val2) {
+ tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val2);
+ val2 = TCG_REG_TMP1;
+ }
+ tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, val2, test_ne);
+ return;
+ }
+
+ if (val2 == 0) {
+ if (c_val1) {
+ tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1);
+ val1 = TCG_REG_TMP1;
+ }
+ tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, val1, test_ne);
+ return;
+ }
+
+ if (c_val2) {
+ if (c_val1) {
+ tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1 - val2);
+ } else {
+ tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val1, -val2);
+ }
+ tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, TCG_REG_TMP1, test_ne);
+ tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val2);
+ return;
+ }
+
+ if (c_val1) {
+ tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val2, -val1);
+ tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, TCG_REG_TMP1, test_ne);
+ tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val1);
+ return;
+ }
+
+ tcg_out_opc_reg(s, OPC_CZERO_NEZ, TCG_REG_TMP1, val2, test_ne);
+ tcg_out_opc_reg(s, OPC_CZERO_EQZ, TCG_REG_TMP0, val1, test_ne);
+ tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_TMP0, TCG_REG_TMP1);
+}
+
+static void tcg_out_movcond_br1(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg cmp1, TCGReg cmp2,
+ int val, bool c_val)
+{
+ RISCVInsn op;
+ int disp = 8;
+
+ tcg_debug_assert((unsigned)cond < ARRAY_SIZE(tcg_brcond_to_riscv));
+ op = tcg_brcond_to_riscv[cond].op;
+ tcg_debug_assert(op != 0);
+
+ if (tcg_brcond_to_riscv[cond].swap) {
+ tcg_out_opc_branch(s, op, cmp2, cmp1, disp);
+ } else {
+ tcg_out_opc_branch(s, op, cmp1, cmp2, disp);
+ }
+ if (c_val) {
+ tcg_out_opc_imm(s, OPC_ADDI, ret, TCG_REG_ZERO, val);
+ } else {
+ tcg_out_opc_imm(s, OPC_ADDI, ret, val, 0);
+ }
+}
+
+static void tcg_out_movcond_br2(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg cmp1, TCGReg cmp2,
+ int val1, bool c_val1,
+ int val2, bool c_val2)
+{
+ TCGReg tmp;
+
+ /* TCG optimizer reorders to prefer ret matching val2. */
+ if (!c_val2 && ret == val2) {
+ cond = tcg_invert_cond(cond);
+ tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val1, c_val1);
+ return;
+ }
+
+ if (!c_val1 && ret == val1) {
+ tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val2, c_val2);
+ return;
+ }
+
+ tmp = (ret == cmp1 || ret == cmp2 ? TCG_REG_TMP1 : ret);
+ if (c_val1) {
+ tcg_out_movi(s, TCG_TYPE_REG, tmp, val1);
+ } else {
+ tcg_out_mov(s, TCG_TYPE_REG, tmp, val1);
+ }
+ tcg_out_movcond_br1(s, cond, tmp, cmp1, cmp2, val2, c_val2);
+ tcg_out_mov(s, TCG_TYPE_REG, ret, tmp);
+}
+
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg cmp1, int cmp2, bool c_cmp2,
+ TCGReg val1, bool c_val1,
+ TCGReg val2, bool c_val2)
+{
+ int tmpflags;
+ TCGReg t;
+
+ if (!have_zicond && (!c_cmp2 || cmp2 == 0)) {
+ tcg_out_movcond_br2(s, cond, ret, cmp1, cmp2,
+ val1, c_val1, val2, c_val2);
+ return;
+ }
+
+ tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, cmp1, cmp2, c_cmp2);
+ t = tmpflags & ~SETCOND_FLAGS;
+
+ if (have_zicond) {
+ if (tmpflags & SETCOND_INV) {
+ tcg_out_movcond_zicond(s, ret, t, val2, c_val2, val1, c_val1);
+ } else {
+ tcg_out_movcond_zicond(s, ret, t, val1, c_val1, val2, c_val2);
+ }
+ } else {
+ cond = tmpflags & SETCOND_INV ? TCG_COND_EQ : TCG_COND_NE;
+ tcg_out_movcond_br2(s, cond, ret, t, TCG_REG_ZERO,
+ val1, c_val1, val2, c_val2);
+ }
+}
+
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
{
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
@@ -1624,6 +1751,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_setcond(s, args[3], a0, a1, a2, c2);
break;
+ case INDEX_op_movcond_i32:
+ case INDEX_op_movcond_i64:
+ tcg_out_movcond(s, args[5], a0, a1, a2, c2,
+ args[3], const_args[3], args[4], const_args[4]);
+ break;
+
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
break;
@@ -1788,6 +1921,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_brcond_i64:
return C_O0_I2(rZ, rZ);
+ case INDEX_op_movcond_i32:
+ case INDEX_op_movcond_i64:
+ return C_O1_I4(r, r, rI, rM, rM);
+
case INDEX_op_add2_i32:
case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (9 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 10/11] tcg/riscv: Implement movcond Richard Henderson
@ 2023-05-03 8:56 ` Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 1:47 ` Alistair Francis
2023-05-08 12:53 ` [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Daniel Henrique Barboza
11 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-05-03 8:56 UTC (permalink / raw)
To: qemu-devel; +Cc: dbarboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/riscv/tcg-target-con-set.h | 1 +
tcg/riscv/tcg-target.h | 8 ++++----
tcg/riscv/tcg-target.c.inc | 35 ++++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index a5cadd303f..aac5ceee2b 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -18,5 +18,6 @@ C_O1_I2(r, r, rI)
C_O1_I2(r, r, rJ)
C_O1_I2(r, rZ, rN)
C_O1_I2(r, rZ, rZ)
+C_N1_I2(r, r, rM)
C_O1_I4(r, r, rI, rM, rM)
C_O2_I4(r, r, rZ, rZ, rM, rM)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index e9e84be9a5..cff5de5c9e 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -125,8 +125,8 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_eqv_i32 have_zbb
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
-#define TCG_TARGET_HAS_clz_i32 0
-#define TCG_TARGET_HAS_ctz_i32 0
+#define TCG_TARGET_HAS_clz_i32 1
+#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 have_zbb
#define TCG_TARGET_HAS_brcond2 1
#define TCG_TARGET_HAS_setcond2 1
@@ -159,8 +159,8 @@ extern bool have_zbb;
#define TCG_TARGET_HAS_eqv_i64 have_zbb
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
-#define TCG_TARGET_HAS_clz_i64 0
-#define TCG_TARGET_HAS_ctz_i64 0
+#define TCG_TARGET_HAS_clz_i64 1
+#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 have_zbb
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 1c57b64182..a1c92b0603 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1063,6 +1063,22 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
}
}
+static void tcg_out_cltz(TCGContext *s, TCGType type, RISCVInsn insn,
+ TCGReg ret, TCGReg src1, int src2, bool c_src2)
+{
+ tcg_out_opc_imm(s, insn, ret, src1, 0);
+
+ if (!c_src2 || src2 != (type == TCG_TYPE_I32 ? 32 : 64)) {
+ /*
+ * The requested zero result does not match the insn, so adjust.
+ * Note that constraints put 'ret' in a new register, so the
+ * computation above did not clobber either 'src1' or 'src2'.
+ */
+ tcg_out_movcond(s, TCG_COND_EQ, ret, src1, 0, true,
+ src2, c_src2, ret, false);
+ }
+}
+
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
{
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
@@ -1724,6 +1740,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
break;
+ case INDEX_op_clz_i32:
+ tcg_out_cltz(s, TCG_TYPE_I32, OPC_CLZW, a0, a1, a2, c2);
+ break;
+ case INDEX_op_clz_i64:
+ tcg_out_cltz(s, TCG_TYPE_I64, OPC_CLZ, a0, a1, a2, c2);
+ break;
+ case INDEX_op_ctz_i32:
+ tcg_out_cltz(s, TCG_TYPE_I32, OPC_CTZW, a0, a1, a2, c2);
+ break;
+ case INDEX_op_ctz_i64:
+ tcg_out_cltz(s, TCG_TYPE_I64, OPC_CTZ, a0, a1, a2, c2);
+ break;
+
case INDEX_op_add2_i32:
tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
const_args[4], const_args[5], false, true);
@@ -1917,6 +1946,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_rotr_i64:
return C_O1_I2(r, r, ri);
+ case INDEX_op_clz_i32:
+ case INDEX_op_clz_i64:
+ case INDEX_op_ctz_i32:
+ case INDEX_op_ctz_i64:
+ return C_N1_I2(r, r, rM);
+
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return C_O0_I2(rZ, rZ);
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez}
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
@ 2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:33 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:37 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> disas/riscv.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index d6b0fbe5e8..c0a8b1006a 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -935,6 +935,8 @@ typedef enum {
> rv_op_vsetvli = 766,
> rv_op_vsetivli = 767,
> rv_op_vsetvl = 768,
> + rv_op_czero_eqz = 769,
> + rv_op_czero_nez = 770,
> } rv_op;
>
> /* structures */
> @@ -2066,7 +2068,9 @@ const rv_opcode_data opcode_data[] = {
> { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 },
> { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 },
> { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 },
> - { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 }
> + { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 },
> + { "czero.eqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> + { "czero.nez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> };
>
> /* CSR names */
> @@ -2792,6 +2796,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
> case 45: op = rv_op_minu; break;
> case 46: op = rv_op_max; break;
> case 47: op = rv_op_maxu; break;
> + case 075: op = rv_op_czero_eqz; break;
> + case 077: op = rv_op_czero_nez; break;
> case 130: op = rv_op_sh1add; break;
> case 132: op = rv_op_sh2add; break;
> case 134: op = rv_op_sh3add; break;
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
2023-05-03 8:56 ` [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions Richard Henderson
@ 2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:35 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:37 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Define a useful subset of the extensions. Probe for them
> via compiler pre-processor feature macros and SIGILL.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.h | 6 +++
> tcg/riscv/tcg-target.c.inc | 96 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 102 insertions(+)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 494c986b49..863ac8ba2f 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -90,6 +90,12 @@ typedef enum {
> #define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
> #define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
>
> +#if defined(__riscv_arch_test) && defined(__riscv_zbb)
> +# define have_zbb true
> +#else
> +extern bool have_zbb;
> +#endif
> +
> /* optional instructions */
> #define TCG_TARGET_HAS_movcond_i32 0
> #define TCG_TARGET_HAS_div_i32 1
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 4dd33c73e8..49ff9c8b9d 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = {
> TCG_REG_A7,
> };
>
> +#ifndef have_zbb
> +bool have_zbb;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zba)
> +# define have_zba true
> +#else
> +static bool have_zba;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zicond)
> +# define have_zicond true
> +#else
> +static bool have_zicond;
> +#endif
> +
> static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
> {
> tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
> @@ -234,6 +248,34 @@ typedef enum {
>
> OPC_FENCE = 0x0000000f,
> OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */
> +
> + /* Zba: Bit manipulation extension, address generation */
> + OPC_ADD_UW = 0x0800003b,
> +
> + /* Zbb: Bit manipulation extension, basic bit manipulaton */
> + OPC_ANDN = 0x40007033,
> + OPC_CLZ = 0x60001013,
> + OPC_CLZW = 0x6000101b,
> + OPC_CPOP = 0x60201013,
> + OPC_CPOPW = 0x6020101b,
> + OPC_CTZ = 0x60101013,
> + OPC_CTZW = 0x6010101b,
> + OPC_ORN = 0x40006033,
> + OPC_REV8 = 0x6b805013,
> + OPC_ROL = 0x60001033,
> + OPC_ROLW = 0x6000103b,
> + OPC_ROR = 0x60005033,
> + OPC_RORW = 0x6000503b,
> + OPC_RORI = 0x60005013,
> + OPC_RORIW = 0x6000501b,
> + OPC_SEXT_B = 0x60401013,
> + OPC_SEXT_H = 0x60501013,
> + OPC_XNOR = 0x40004033,
> + OPC_ZEXT_H = 0x0800403b,
> +
> + /* Zicond: integer conditional operations */
> + OPC_CZERO_EQZ = 0x0e005033,
> + OPC_CZERO_NEZ = 0x0e007033,
> } RISCVInsn;
>
> /*
> @@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
> }
>
> +static volatile sig_atomic_t got_sigill;
> +
> +static void sigill_handler(int signo, siginfo_t *si, void *data)
> +{
> + /* Skip the faulty instruction */
> + ucontext_t *uc = (ucontext_t *)data;
> + uc->uc_mcontext.__gregs[REG_PC] += 4;
> +
> + got_sigill = 1;
> +}
> +
> +static void tcg_target_detect_isa(void)
> +{
> +#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond)
> + /*
> + * TODO: It is expected that this will be determinable via
> + * linux riscv_hwprobe syscall, not yet merged.
> + * In the meantime, test via sigill.
> + */
> +
> + struct sigaction sa_old, sa_new;
> +
> + memset(&sa_new, 0, sizeof(sa_new));
> + sa_new.sa_flags = SA_SIGINFO;
> + sa_new.sa_sigaction = sigill_handler;
> + sigaction(SIGILL, &sa_new, &sa_old);
> +
> +#ifndef have_zba
> + /* Probe for Zba: add.uw zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory");
> + have_zba = !got_sigill;
> +#endif
> +
> +#ifndef have_zbb
> + /* Probe for Zba: andn zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory");
> + have_zbb = !got_sigill;
> +#endif
> +
> +#ifndef have_zicond
> + /* Probe for Zicond: czero.eqz zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory");
> + have_zicond = !got_sigill;
> +#endif
> +
> + sigaction(SIGILL, &sa_old, NULL);
> +#endif
> +}
> +
> static void tcg_target_init(TCGContext *s)
> {
> + tcg_target_detect_isa();
> +
> tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
> tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb
2023-05-03 8:56 ` [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb Richard Henderson
@ 2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:38 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:37 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target-con-str.h | 1 +
> tcg/riscv/tcg-target.h | 12 +++++-----
> tcg/riscv/tcg-target.c.inc | 41 ++++++++++++++++++++++++++++++++++
> 4 files changed, 49 insertions(+), 6 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index d88888d3ac..1a33ece98f 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -15,6 +15,7 @@ C_O0_I2(rZ, rZ)
> C_O1_I1(r, r)
> C_O1_I2(r, r, ri)
> C_O1_I2(r, r, rI)
> +C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
> index 6f1cfb976c..d5c419dff1 100644
> --- a/tcg/riscv/tcg-target-con-str.h
> +++ b/tcg/riscv/tcg-target-con-str.h
> @@ -15,6 +15,7 @@ REGS('r', ALL_GENERAL_REGS)
> * CONST(letter, TCG_CT_CONST_* bit set)
> */
> CONST('I', TCG_CT_CONST_S12)
> +CONST('J', TCG_CT_CONST_J12)
> CONST('N', TCG_CT_CONST_N12)
> CONST('M', TCG_CT_CONST_M12)
> CONST('Z', TCG_CT_CONST_ZERO)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 863ac8ba2f..9f58d46208 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -120,9 +120,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_bswap32_i32 0
> #define TCG_TARGET_HAS_not_i32 1
> #define TCG_TARGET_HAS_neg_i32 1
> -#define TCG_TARGET_HAS_andc_i32 0
> -#define TCG_TARGET_HAS_orc_i32 0
> -#define TCG_TARGET_HAS_eqv_i32 0
> +#define TCG_TARGET_HAS_andc_i32 have_zbb
> +#define TCG_TARGET_HAS_orc_i32 have_zbb
> +#define TCG_TARGET_HAS_eqv_i32 have_zbb
> #define TCG_TARGET_HAS_nand_i32 0
> #define TCG_TARGET_HAS_nor_i32 0
> #define TCG_TARGET_HAS_clz_i32 0
> @@ -154,9 +154,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_bswap64_i64 0
> #define TCG_TARGET_HAS_not_i64 1
> #define TCG_TARGET_HAS_neg_i64 1
> -#define TCG_TARGET_HAS_andc_i64 0
> -#define TCG_TARGET_HAS_orc_i64 0
> -#define TCG_TARGET_HAS_eqv_i64 0
> +#define TCG_TARGET_HAS_andc_i64 have_zbb
> +#define TCG_TARGET_HAS_orc_i64 have_zbb
> +#define TCG_TARGET_HAS_eqv_i64 have_zbb
> #define TCG_TARGET_HAS_nand_i64 0
> #define TCG_TARGET_HAS_nor_i64 0
> #define TCG_TARGET_HAS_clz_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 49ff9c8b9d..c5b060023f 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -138,6 +138,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
> #define TCG_CT_CONST_S12 0x200
> #define TCG_CT_CONST_N12 0x400
> #define TCG_CT_CONST_M12 0x800
> +#define TCG_CT_CONST_J12 0x1000
>
> #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
>
> @@ -174,6 +175,13 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
> if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
> return 1;
> }
> + /*
> + * Inverse of sign extended from 12 bits: ~[-0x800, 0x7ff].
> + * Used to map ANDN back to ANDI, etc.
> + */
> + if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
> + return 1;
> + }
> return 0;
> }
>
> @@ -1306,6 +1314,31 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_andc_i32:
> + case INDEX_op_andc_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_ANDI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_ANDN, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_orc_i32:
> + case INDEX_op_orc_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_ORI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_ORN, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_eqv_i32:
> + case INDEX_op_eqv_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_XORI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_XNOR, a0, a1, a2);
> + }
> + break;
> +
> case INDEX_op_not_i32:
> case INDEX_op_not_i64:
> tcg_out_opc_imm(s, OPC_XORI, a0, a1, -1);
> @@ -1536,6 +1569,14 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_xor_i64:
> return C_O1_I2(r, r, rI);
>
> + case INDEX_op_andc_i32:
> + case INDEX_op_andc_i64:
> + case INDEX_op_orc_i32:
> + case INDEX_op_orc_i64:
> + case INDEX_op_eqv_i32:
> + case INDEX_op_eqv_i64:
> + return C_O1_I2(r, r, rJ);
> +
> case INDEX_op_sub_i32:
> case INDEX_op_sub_i64:
> return C_O1_I2(r, rZ, rN);
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb
2023-05-03 8:56 ` [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb Richard Henderson
@ 2023-05-08 12:39 ` Daniel Henrique Barboza
2023-05-16 23:40 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:39 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.c.inc | 32 ++++++++++++++++++++++++--------
> 1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index c5b060023f..53a7f97b29 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -593,26 +593,42 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
>
> static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> - tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
> + if (have_zbb) {
> + tcg_out_opc_reg(s, OPC_ZEXT_H, ret, arg, TCG_REG_ZERO);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> + tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
> + }
> }
>
> static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
> - tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
> + if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, ret, arg, TCG_REG_ZERO);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
> + tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
> + }
> }
>
> static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
> - tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
> + if (have_zbb) {
> + tcg_out_opc_imm(s, OPC_SEXT_B, ret, arg, 0);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
> + tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
> + }
> }
>
> static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> - tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
> + if (have_zbb) {
> + tcg_out_opc_imm(s, OPC_SEXT_H, ret, arg, 0);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> + tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
> + }
> }
>
> static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation
2023-05-03 8:56 ` [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation Richard Henderson
@ 2023-05-08 12:43 ` Daniel Henrique Barboza
2023-05-16 23:43 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:43 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
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
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 06/11] tcg/riscv: Support rotates from Zbb
2023-05-03 8:56 ` [PATCH 06/11] tcg/riscv: Support rotates from Zbb Richard Henderson
@ 2023-05-08 12:44 ` Daniel Henrique Barboza
2023-05-16 23:48 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:44 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.h | 4 ++--
> tcg/riscv/tcg-target.c.inc | 34 ++++++++++++++++++++++++++++++++++
> 2 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 9f58d46208..317d385924 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -101,7 +101,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_div_i32 1
> #define TCG_TARGET_HAS_rem_i32 1
> #define TCG_TARGET_HAS_div2_i32 0
> -#define TCG_TARGET_HAS_rot_i32 0
> +#define TCG_TARGET_HAS_rot_i32 have_zbb
> #define TCG_TARGET_HAS_deposit_i32 0
> #define TCG_TARGET_HAS_extract_i32 0
> #define TCG_TARGET_HAS_sextract_i32 0
> @@ -136,7 +136,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_div_i64 1
> #define TCG_TARGET_HAS_rem_i64 1
> #define TCG_TARGET_HAS_div2_i64 0
> -#define TCG_TARGET_HAS_rot_i64 0
> +#define TCG_TARGET_HAS_rot_i64 have_zbb
> #define TCG_TARGET_HAS_deposit_i64 0
> #define TCG_TARGET_HAS_extract_i64 0
> #define TCG_TARGET_HAS_sextract_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index f64eaa8515..58f969b4fe 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1458,6 +1458,36 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_rotl_i32:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORIW, a0, a1, -a2 & 0x1f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROLW, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_rotl_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORI, a0, a1, -a2 & 0x3f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROL, a0, a1, a2);
> + }
> + break;
> +
> + case INDEX_op_rotr_i32:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORIW, a0, a1, a2 & 0x1f);
> + } else {
> + tcg_out_opc_reg(s, OPC_RORW, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_rotr_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORI, a0, a1, a2 & 0x3f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROR, a0, a1, a2);
> + }
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1629,9 +1659,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_shl_i32:
> case INDEX_op_shr_i32:
> case INDEX_op_sar_i32:
> + case INDEX_op_rotl_i32:
> + case INDEX_op_rotr_i32:
> case INDEX_op_shl_i64:
> case INDEX_op_shr_i64:
> case INDEX_op_sar_i64:
> + case INDEX_op_rotl_i64:
> + case INDEX_op_rotr_i64:
> return C_O1_I2(r, r, ri);
>
> case INDEX_op_brcond_i32:
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 07/11] tcg/riscv: Support REV8 from Zbb
2023-05-03 8:56 ` [PATCH 07/11] tcg/riscv: Support REV8 " Richard Henderson
@ 2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:45 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.h | 10 +++++-----
> tcg/riscv/tcg-target.c.inc | 29 +++++++++++++++++++++++++++++
> 2 files changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 317d385924..8e327afc3a 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -116,8 +116,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_ext16s_i32 1
> #define TCG_TARGET_HAS_ext8u_i32 1
> #define TCG_TARGET_HAS_ext16u_i32 1
> -#define TCG_TARGET_HAS_bswap16_i32 0
> -#define TCG_TARGET_HAS_bswap32_i32 0
> +#define TCG_TARGET_HAS_bswap16_i32 have_zbb
> +#define TCG_TARGET_HAS_bswap32_i32 have_zbb
> #define TCG_TARGET_HAS_not_i32 1
> #define TCG_TARGET_HAS_neg_i32 1
> #define TCG_TARGET_HAS_andc_i32 have_zbb
> @@ -149,9 +149,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_ext8u_i64 1
> #define TCG_TARGET_HAS_ext16u_i64 1
> #define TCG_TARGET_HAS_ext32u_i64 1
> -#define TCG_TARGET_HAS_bswap16_i64 0
> -#define TCG_TARGET_HAS_bswap32_i64 0
> -#define TCG_TARGET_HAS_bswap64_i64 0
> +#define TCG_TARGET_HAS_bswap16_i64 have_zbb
> +#define TCG_TARGET_HAS_bswap32_i64 have_zbb
> +#define TCG_TARGET_HAS_bswap64_i64 have_zbb
> #define TCG_TARGET_HAS_not_i64 1
> #define TCG_TARGET_HAS_neg_i64 1
> #define TCG_TARGET_HAS_andc_i64 have_zbb
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 58f969b4fe..9cbefb2833 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1488,6 +1488,30 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_bswap64_i64:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + break;
> + case INDEX_op_bswap32_i32:
> + a2 = 0;
> + /* fall through */
> + case INDEX_op_bswap32_i64:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + if (a2 & TCG_BSWAP_OZ) {
> + tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 32);
> + } else {
> + tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 32);
> + }
> + break;
> + case INDEX_op_bswap16_i64:
> + case INDEX_op_bswap16_i32:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + if (a2 & TCG_BSWAP_OZ) {
> + tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 48);
> + } else {
> + tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 48);
> + }
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1605,6 +1629,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_extrl_i64_i32:
> case INDEX_op_extrh_i64_i32:
> case INDEX_op_ext_i32_i64:
> + case INDEX_op_bswap16_i32:
> + case INDEX_op_bswap32_i32:
> + case INDEX_op_bswap16_i64:
> + case INDEX_op_bswap32_i64:
> + case INDEX_op_bswap64_i64:
> return C_O1_I1(r, r);
>
> case INDEX_op_st8_i32:
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 08/11] tcg/riscv: Support CPOP from Zbb
2023-05-03 8:56 ` [PATCH 08/11] tcg/riscv: Support CPOP " Richard Henderson
@ 2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:45 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.h | 4 ++--
> tcg/riscv/tcg-target.c.inc | 9 +++++++++
> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 8e327afc3a..e0b23006c4 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -127,7 +127,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_nor_i32 0
> #define TCG_TARGET_HAS_clz_i32 0
> #define TCG_TARGET_HAS_ctz_i32 0
> -#define TCG_TARGET_HAS_ctpop_i32 0
> +#define TCG_TARGET_HAS_ctpop_i32 have_zbb
> #define TCG_TARGET_HAS_brcond2 1
> #define TCG_TARGET_HAS_setcond2 1
> #define TCG_TARGET_HAS_qemu_st8_i32 0
> @@ -161,7 +161,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_nor_i64 0
> #define TCG_TARGET_HAS_clz_i64 0
> #define TCG_TARGET_HAS_ctz_i64 0
> -#define TCG_TARGET_HAS_ctpop_i64 0
> +#define TCG_TARGET_HAS_ctpop_i64 have_zbb
> #define TCG_TARGET_HAS_add2_i64 1
> #define TCG_TARGET_HAS_sub2_i64 1
> #define TCG_TARGET_HAS_mulu2_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 9cbefb2833..044ddfb160 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1512,6 +1512,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_ctpop_i32:
> + tcg_out_opc_imm(s, OPC_CPOPW, a0, a1, 0);
> + break;
> + case INDEX_op_ctpop_i64:
> + tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1634,6 +1641,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_bswap16_i64:
> case INDEX_op_bswap32_i64:
> case INDEX_op_bswap64_i64:
> + case INDEX_op_ctpop_i32:
> + case INDEX_op_ctpop_i64:
> return C_O1_I1(r, r);
>
> case INDEX_op_st8_i32:
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 09/11] tcg/riscv: Improve setcond expansion
2023-05-03 8:56 ` [PATCH 09/11] tcg/riscv: Improve setcond expansion Richard Henderson
@ 2023-05-08 12:46 ` Daniel Henrique Barboza
2023-05-17 0:16 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:46 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Split out a helper function, tcg_out_setcond_int, which does not
> always produce the complete boolean result, but returns a set of
> flags to do so.
>
> Based on 21af16198425, the same improvement for loongarch64.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target.c.inc | 164 +++++++++++++++++++++++++++----------
> 1 file changed, 121 insertions(+), 43 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 044ddfb160..84b646105c 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -812,50 +812,128 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
> tcg_out_opc_branch(s, op, arg1, arg2, 0);
> }
>
> -static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> - TCGReg arg1, TCGReg arg2)
> +#define SETCOND_INV TCG_TARGET_NB_REGS
> +#define SETCOND_NEZ (SETCOND_INV << 1)
> +#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
> +
> +static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg arg1, tcg_target_long arg2, bool c2)
> {
> + int flags = 0;
> +
> switch (cond) {
> - case TCG_COND_EQ:
> - tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
> - break;
> - case TCG_COND_NE:
> - tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
> - tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
> - break;
> - case TCG_COND_LT:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> - break;
> - case TCG_COND_GE:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_LE:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_GT:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
> - break;
> - case TCG_COND_LTU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> - break;
> - case TCG_COND_GEU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_LEU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_GTU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
> + case TCG_COND_EQ: /* -> NE */
> + case TCG_COND_GE: /* -> LT */
> + case TCG_COND_GEU: /* -> LTU */
> + case TCG_COND_GT: /* -> LE */
> + case TCG_COND_GTU: /* -> LEU */
> + cond = tcg_invert_cond(cond);
> + flags ^= SETCOND_INV;
> break;
> default:
> - g_assert_not_reached();
> - break;
> - }
> + break;
> + }
> +
> + switch (cond) {
> + case TCG_COND_LE:
> + case TCG_COND_LEU:
> + /*
> + * If we have a constant input, the most efficient way to implement
> + * LE is by adding 1 and using LT. Watch out for wrap around for LEU.
> + * We don't need to care for this for LE because the constant input
> + * is constrained to signed 12-bit, and 0x800 is representable in the
> + * temporary register.
> + */
> + if (c2) {
> + if (cond == TCG_COND_LEU) {
> + /* unsigned <= -1 is true */
> + if (arg2 == -1) {
> + tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
> + return ret;
> + }
> + cond = TCG_COND_LTU;
> + } else {
> + cond = TCG_COND_LT;
> + }
> + tcg_debug_assert(arg2 <= 0x7ff);
> + if (++arg2 == 0x800) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
> + arg2 = TCG_REG_TMP0;
> + c2 = false;
> + }
> + } else {
> + TCGReg tmp = arg2;
> + arg2 = arg1;
> + arg1 = tmp;
> + cond = tcg_swap_cond(cond); /* LE -> GE */
> + cond = tcg_invert_cond(cond); /* GE -> LT */
> + flags ^= SETCOND_INV;
> + }
> + break;
> + default:
> + break;
> + }
> +
> + switch (cond) {
> + case TCG_COND_NE:
> + flags |= SETCOND_NEZ;
> + if (!c2) {
> + tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
> + } else if (arg2 == 0) {
> + ret = arg1;
> + } else {
> + tcg_out_opc_reg(s, OPC_XORI, ret, arg1, arg2);
> + }
> + break;
> +
> + case TCG_COND_LT:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_SLTI, ret, arg1, arg2);
> + } else {
> + tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> + }
> + break;
> +
> + case TCG_COND_LTU:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, arg2);
> + } else {
> + tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> + }
> + break;
> +
> + default:
> + g_assert_not_reached();
> + }
> +
> + return ret | flags;
> +}
> +
> +static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg arg1, tcg_target_long arg2, bool c2)
> +{
> + int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
> +
> + if (tmpflags != ret) {
> + TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
> +
> + switch (tmpflags & SETCOND_FLAGS) {
> + case SETCOND_INV:
> + /* Intermediate result is boolean: simply invert. */
> + tcg_out_opc_imm(s, OPC_XORI, ret, tmp, 1);
> + break;
> + case SETCOND_NEZ:
> + /* Intermediate result is zero/non-zero: test != 0. */
> + tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp);
> + break;
> + case SETCOND_NEZ | SETCOND_INV:
> + /* Intermediate result is zero/non-zero: test == 0. */
> + tcg_out_opc_imm(s, OPC_SLTIU, ret, tmp, 1);
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + }
> }
>
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> @@ -1543,7 +1621,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
>
> case INDEX_op_setcond_i32:
> case INDEX_op_setcond_i64:
> - tcg_out_setcond(s, args[3], a0, a1, a2);
> + tcg_out_setcond(s, args[3], a0, a1, a2, c2);
> break;
>
> case INDEX_op_qemu_ld_i32:
> @@ -1662,6 +1740,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_and_i64:
> case INDEX_op_or_i64:
> case INDEX_op_xor_i64:
> + case INDEX_op_setcond_i32:
> + case INDEX_op_setcond_i64:
> return C_O1_I2(r, r, rI);
>
> case INDEX_op_andc_i32:
> @@ -1683,7 +1763,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_divu_i32:
> case INDEX_op_rem_i32:
> case INDEX_op_remu_i32:
> - case INDEX_op_setcond_i32:
> case INDEX_op_mul_i64:
> case INDEX_op_mulsh_i64:
> case INDEX_op_muluh_i64:
> @@ -1691,7 +1770,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_divu_i64:
> case INDEX_op_rem_i64:
> case INDEX_op_remu_i64:
> - case INDEX_op_setcond_i64:
> return C_O1_I2(r, rZ, rZ);
>
> case INDEX_op_shl_i32:
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 10/11] tcg/riscv: Implement movcond
2023-05-03 8:56 ` [PATCH 10/11] tcg/riscv: Implement movcond Richard Henderson
@ 2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 0:19 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:47 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Implement with and without Zicond. Without Zicond, we were letting
> the middle-end expand to a 5 insn sequence; better to use a branch
> over a single insn.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target.h | 4 +-
> tcg/riscv/tcg-target.c.inc | 139 ++++++++++++++++++++++++++++++++-
> 3 files changed, 141 insertions(+), 3 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index 1a33ece98f..a5cadd303f 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -18,4 +18,5 @@ C_O1_I2(r, r, rI)
> C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> +C_O1_I4(r, r, rI, rM, rM)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index e0b23006c4..e9e84be9a5 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -97,7 +97,7 @@ extern bool have_zbb;
> #endif
>
> /* optional instructions */
> -#define TCG_TARGET_HAS_movcond_i32 0
> +#define TCG_TARGET_HAS_movcond_i32 1
> #define TCG_TARGET_HAS_div_i32 1
> #define TCG_TARGET_HAS_rem_i32 1
> #define TCG_TARGET_HAS_div2_i32 0
> @@ -132,7 +132,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_setcond2 1
> #define TCG_TARGET_HAS_qemu_st8_i32 0
>
> -#define TCG_TARGET_HAS_movcond_i64 0
> +#define TCG_TARGET_HAS_movcond_i64 1
> #define TCG_TARGET_HAS_div_i64 1
> #define TCG_TARGET_HAS_rem_i64 1
> #define TCG_TARGET_HAS_div2_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 84b646105c..1c57b64182 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -169,7 +169,7 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
> }
> /*
> * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
> - * Used by addsub2, which may need the negative operation,
> + * Used by addsub2 and movcond, which may need the negative value,
> * and requires the modified constant to be representable.
> */
> if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
> @@ -936,6 +936,133 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> }
> }
>
> +static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne,
> + int val1, bool c_val1,
> + int val2, bool c_val2)
> +{
> + if (val1 == 0) {
> + if (c_val2) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val2);
> + val2 = TCG_REG_TMP1;
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, val2, test_ne);
> + return;
> + }
> +
> + if (val2 == 0) {
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1);
> + val1 = TCG_REG_TMP1;
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, val1, test_ne);
> + return;
> + }
> +
> + if (c_val2) {
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1 - val2);
> + } else {
> + tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val1, -val2);
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, TCG_REG_TMP1, test_ne);
> + tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val2);
> + return;
> + }
> +
> + if (c_val1) {
> + tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val2, -val1);
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, TCG_REG_TMP1, test_ne);
> + tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val1);
> + return;
> + }
> +
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, TCG_REG_TMP1, val2, test_ne);
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, TCG_REG_TMP0, val1, test_ne);
> + tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_TMP0, TCG_REG_TMP1);
> +}
> +
> +static void tcg_out_movcond_br1(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, TCGReg cmp2,
> + int val, bool c_val)
> +{
> + RISCVInsn op;
> + int disp = 8;
> +
> + tcg_debug_assert((unsigned)cond < ARRAY_SIZE(tcg_brcond_to_riscv));
> + op = tcg_brcond_to_riscv[cond].op;
> + tcg_debug_assert(op != 0);
> +
> + if (tcg_brcond_to_riscv[cond].swap) {
> + tcg_out_opc_branch(s, op, cmp2, cmp1, disp);
> + } else {
> + tcg_out_opc_branch(s, op, cmp1, cmp2, disp);
> + }
> + if (c_val) {
> + tcg_out_opc_imm(s, OPC_ADDI, ret, TCG_REG_ZERO, val);
> + } else {
> + tcg_out_opc_imm(s, OPC_ADDI, ret, val, 0);
> + }
> +}
> +
> +static void tcg_out_movcond_br2(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, TCGReg cmp2,
> + int val1, bool c_val1,
> + int val2, bool c_val2)
> +{
> + TCGReg tmp;
> +
> + /* TCG optimizer reorders to prefer ret matching val2. */
> + if (!c_val2 && ret == val2) {
> + cond = tcg_invert_cond(cond);
> + tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val1, c_val1);
> + return;
> + }
> +
> + if (!c_val1 && ret == val1) {
> + tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val2, c_val2);
> + return;
> + }
> +
> + tmp = (ret == cmp1 || ret == cmp2 ? TCG_REG_TMP1 : ret);
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, tmp, val1);
> + } else {
> + tcg_out_mov(s, TCG_TYPE_REG, tmp, val1);
> + }
> + tcg_out_movcond_br1(s, cond, tmp, cmp1, cmp2, val2, c_val2);
> + tcg_out_mov(s, TCG_TYPE_REG, ret, tmp);
> +}
> +
> +static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, int cmp2, bool c_cmp2,
> + TCGReg val1, bool c_val1,
> + TCGReg val2, bool c_val2)
> +{
> + int tmpflags;
> + TCGReg t;
> +
> + if (!have_zicond && (!c_cmp2 || cmp2 == 0)) {
> + tcg_out_movcond_br2(s, cond, ret, cmp1, cmp2,
> + val1, c_val1, val2, c_val2);
> + return;
> + }
> +
> + tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, cmp1, cmp2, c_cmp2);
> + t = tmpflags & ~SETCOND_FLAGS;
> +
> + if (have_zicond) {
> + if (tmpflags & SETCOND_INV) {
> + tcg_out_movcond_zicond(s, ret, t, val2, c_val2, val1, c_val1);
> + } else {
> + tcg_out_movcond_zicond(s, ret, t, val1, c_val1, val2, c_val2);
> + }
> + } else {
> + cond = tmpflags & SETCOND_INV ? TCG_COND_EQ : TCG_COND_NE;
> + tcg_out_movcond_br2(s, cond, ret, t, TCG_REG_ZERO,
> + val1, c_val1, val2, c_val2);
> + }
> +}
> +
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> {
> TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
> @@ -1624,6 +1751,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> tcg_out_setcond(s, args[3], a0, a1, a2, c2);
> break;
>
> + case INDEX_op_movcond_i32:
> + case INDEX_op_movcond_i64:
> + tcg_out_movcond(s, args[5], a0, a1, a2, c2,
> + args[3], const_args[3], args[4], const_args[4]);
> + break;
> +
> case INDEX_op_qemu_ld_i32:
> tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
> break;
> @@ -1788,6 +1921,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_brcond_i64:
> return C_O0_I2(rZ, rZ);
>
> + case INDEX_op_movcond_i32:
> + case INDEX_op_movcond_i64:
> + return C_O1_I4(r, r, rI, rM, rM);
> +
> case INDEX_op_add2_i32:
> case INDEX_op_add2_i64:
> case INDEX_op_sub2_i32:
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb
2023-05-03 8:56 ` [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb Richard Henderson
@ 2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 1:47 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:47 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target.h | 8 ++++----
> tcg/riscv/tcg-target.c.inc | 35 ++++++++++++++++++++++++++++++++++
> 3 files changed, 40 insertions(+), 4 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index a5cadd303f..aac5ceee2b 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -18,5 +18,6 @@ C_O1_I2(r, r, rI)
> C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> +C_N1_I2(r, r, rM)
> C_O1_I4(r, r, rI, rM, rM)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index e9e84be9a5..cff5de5c9e 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -125,8 +125,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_eqv_i32 have_zbb
> #define TCG_TARGET_HAS_nand_i32 0
> #define TCG_TARGET_HAS_nor_i32 0
> -#define TCG_TARGET_HAS_clz_i32 0
> -#define TCG_TARGET_HAS_ctz_i32 0
> +#define TCG_TARGET_HAS_clz_i32 1
> +#define TCG_TARGET_HAS_ctz_i32 1
> #define TCG_TARGET_HAS_ctpop_i32 have_zbb
> #define TCG_TARGET_HAS_brcond2 1
> #define TCG_TARGET_HAS_setcond2 1
> @@ -159,8 +159,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_eqv_i64 have_zbb
> #define TCG_TARGET_HAS_nand_i64 0
> #define TCG_TARGET_HAS_nor_i64 0
> -#define TCG_TARGET_HAS_clz_i64 0
> -#define TCG_TARGET_HAS_ctz_i64 0
> +#define TCG_TARGET_HAS_clz_i64 1
> +#define TCG_TARGET_HAS_ctz_i64 1
> #define TCG_TARGET_HAS_ctpop_i64 have_zbb
> #define TCG_TARGET_HAS_add2_i64 1
> #define TCG_TARGET_HAS_sub2_i64 1
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 1c57b64182..a1c92b0603 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1063,6 +1063,22 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
> }
> }
>
> +static void tcg_out_cltz(TCGContext *s, TCGType type, RISCVInsn insn,
> + TCGReg ret, TCGReg src1, int src2, bool c_src2)
> +{
> + tcg_out_opc_imm(s, insn, ret, src1, 0);
> +
> + if (!c_src2 || src2 != (type == TCG_TYPE_I32 ? 32 : 64)) {
> + /*
> + * The requested zero result does not match the insn, so adjust.
> + * Note that constraints put 'ret' in a new register, so the
> + * computation above did not clobber either 'src1' or 'src2'.
> + */
> + tcg_out_movcond(s, TCG_COND_EQ, ret, src1, 0, true,
> + src2, c_src2, ret, false);
> + }
> +}
> +
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> {
> TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
> @@ -1724,6 +1740,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
> break;
>
> + case INDEX_op_clz_i32:
> + tcg_out_cltz(s, TCG_TYPE_I32, OPC_CLZW, a0, a1, a2, c2);
> + break;
> + case INDEX_op_clz_i64:
> + tcg_out_cltz(s, TCG_TYPE_I64, OPC_CLZ, a0, a1, a2, c2);
> + break;
> + case INDEX_op_ctz_i32:
> + tcg_out_cltz(s, TCG_TYPE_I32, OPC_CTZW, a0, a1, a2, c2);
> + break;
> + case INDEX_op_ctz_i64:
> + tcg_out_cltz(s, TCG_TYPE_I64, OPC_CTZ, a0, a1, a2, c2);
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1917,6 +1946,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_rotr_i64:
> return C_O1_I2(r, r, ri);
>
> + case INDEX_op_clz_i32:
> + case INDEX_op_clz_i64:
> + case INDEX_op_ctz_i32:
> + case INDEX_op_ctz_i64:
> + return C_N1_I2(r, r, rM);
> +
> case INDEX_op_brcond_i32:
> case INDEX_op_brcond_i64:
> return C_O0_I2(rZ, rZ);
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
` (10 preceding siblings ...)
2023-05-03 8:56 ` [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb Richard Henderson
@ 2023-05-08 12:53 ` Daniel Henrique Barboza
11 siblings, 0 replies; 35+ messages in thread
From: Daniel Henrique Barboza @ 2023-05-08 12:53 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/23 05:56, Richard Henderson wrote:
> Based-on: 20230503070656.1746170-1-richard.henderson@linaro.org
> ("[PATCH v4 00/57] tcg: Improve atomicity support")
>
> I've been vaguely following the __hw_probe syscall progress
> in the upstream kernel. The initial version only handled
> bog standard F+D and C extensions, which everything expects
> to be present anyway, which was disappointing. But at least
> the basis is there for proper extensions.
>
> In the meantime, probe via sigill. Tested with qemu-on-qemu.
> I understand the Ventana core has all of these, if you'd be
> so kind as to test.
I'll run this series with upstream kernel on a real HW as soon as able.
(hopefully this month).
I think this is good to go regardless of HW testing though.
Daniel
>
>
> r~
>
>
> Richard Henderson (11):
> disas/riscv: Decode czero.{eqz,nez}
> tcg/riscv: Probe for Zba, Zbb, Zicond extensions
> tcg/riscv: Support ANDN, ORN, XNOR from Zbb
> tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb
> tcg/riscv: Use ADD.UW for guest address generation
> tcg/riscv: Support rotates from Zbb
> tcg/riscv: Support REV8 from Zbb
> tcg/riscv: Support CPOP from Zbb
> tcg/riscv: Improve setcond expansion
> tcg/riscv: Implement movcond
> tcg/riscv: Support CTZ, CLZ from Zbb
>
> tcg/riscv/tcg-target-con-set.h | 3 +
> tcg/riscv/tcg-target-con-str.h | 1 +
> tcg/riscv/tcg-target.h | 48 +--
> disas/riscv.c | 8 +-
> tcg/riscv/tcg-target.c.inc | 612 +++++++++++++++++++++++++++++----
> 5 files changed, 587 insertions(+), 85 deletions(-)
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez}
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
@ 2023-05-16 23:33 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:33 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> disas/riscv.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index d6b0fbe5e8..c0a8b1006a 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -935,6 +935,8 @@ typedef enum {
> rv_op_vsetvli = 766,
> rv_op_vsetivli = 767,
> rv_op_vsetvl = 768,
> + rv_op_czero_eqz = 769,
> + rv_op_czero_nez = 770,
> } rv_op;
>
> /* structures */
> @@ -2066,7 +2068,9 @@ const rv_opcode_data opcode_data[] = {
> { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 },
> { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 },
> { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 },
> - { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 }
> + { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 },
> + { "czero.eqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> + { "czero.nez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> };
>
> /* CSR names */
> @@ -2792,6 +2796,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
> case 45: op = rv_op_minu; break;
> case 46: op = rv_op_max; break;
> case 47: op = rv_op_maxu; break;
> + case 075: op = rv_op_czero_eqz; break;
> + case 077: op = rv_op_czero_nez; break;
> case 130: op = rv_op_sh1add; break;
> case 132: op = rv_op_sh2add; break;
> case 134: op = rv_op_sh3add; break;
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
2023-05-03 8:56 ` [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
@ 2023-05-16 23:35 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:35 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Define a useful subset of the extensions. Probe for them
> via compiler pre-processor feature macros and SIGILL.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.h | 6 +++
> tcg/riscv/tcg-target.c.inc | 96 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 102 insertions(+)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 494c986b49..863ac8ba2f 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -90,6 +90,12 @@ typedef enum {
> #define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
> #define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
>
> +#if defined(__riscv_arch_test) && defined(__riscv_zbb)
> +# define have_zbb true
> +#else
> +extern bool have_zbb;
> +#endif
> +
> /* optional instructions */
> #define TCG_TARGET_HAS_movcond_i32 0
> #define TCG_TARGET_HAS_div_i32 1
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 4dd33c73e8..49ff9c8b9d 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = {
> TCG_REG_A7,
> };
>
> +#ifndef have_zbb
> +bool have_zbb;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zba)
> +# define have_zba true
> +#else
> +static bool have_zba;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zicond)
> +# define have_zicond true
> +#else
> +static bool have_zicond;
> +#endif
> +
> static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
> {
> tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
> @@ -234,6 +248,34 @@ typedef enum {
>
> OPC_FENCE = 0x0000000f,
> OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */
> +
> + /* Zba: Bit manipulation extension, address generation */
> + OPC_ADD_UW = 0x0800003b,
> +
> + /* Zbb: Bit manipulation extension, basic bit manipulaton */
> + OPC_ANDN = 0x40007033,
> + OPC_CLZ = 0x60001013,
> + OPC_CLZW = 0x6000101b,
> + OPC_CPOP = 0x60201013,
> + OPC_CPOPW = 0x6020101b,
> + OPC_CTZ = 0x60101013,
> + OPC_CTZW = 0x6010101b,
> + OPC_ORN = 0x40006033,
> + OPC_REV8 = 0x6b805013,
> + OPC_ROL = 0x60001033,
> + OPC_ROLW = 0x6000103b,
> + OPC_ROR = 0x60005033,
> + OPC_RORW = 0x6000503b,
> + OPC_RORI = 0x60005013,
> + OPC_RORIW = 0x6000501b,
> + OPC_SEXT_B = 0x60401013,
> + OPC_SEXT_H = 0x60501013,
> + OPC_XNOR = 0x40004033,
> + OPC_ZEXT_H = 0x0800403b,
> +
> + /* Zicond: integer conditional operations */
> + OPC_CZERO_EQZ = 0x0e005033,
> + OPC_CZERO_NEZ = 0x0e007033,
> } RISCVInsn;
>
> /*
> @@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s)
> tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
> }
>
> +static volatile sig_atomic_t got_sigill;
> +
> +static void sigill_handler(int signo, siginfo_t *si, void *data)
> +{
> + /* Skip the faulty instruction */
> + ucontext_t *uc = (ucontext_t *)data;
> + uc->uc_mcontext.__gregs[REG_PC] += 4;
> +
> + got_sigill = 1;
> +}
> +
> +static void tcg_target_detect_isa(void)
> +{
> +#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond)
> + /*
> + * TODO: It is expected that this will be determinable via
> + * linux riscv_hwprobe syscall, not yet merged.
> + * In the meantime, test via sigill.
> + */
> +
> + struct sigaction sa_old, sa_new;
> +
> + memset(&sa_new, 0, sizeof(sa_new));
> + sa_new.sa_flags = SA_SIGINFO;
> + sa_new.sa_sigaction = sigill_handler;
> + sigaction(SIGILL, &sa_new, &sa_old);
> +
> +#ifndef have_zba
> + /* Probe for Zba: add.uw zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory");
> + have_zba = !got_sigill;
> +#endif
> +
> +#ifndef have_zbb
> + /* Probe for Zba: andn zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory");
> + have_zbb = !got_sigill;
> +#endif
> +
> +#ifndef have_zicond
> + /* Probe for Zicond: czero.eqz zero,zero,zero. */
> + got_sigill = 0;
> + asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory");
> + have_zicond = !got_sigill;
> +#endif
> +
> + sigaction(SIGILL, &sa_old, NULL);
> +#endif
> +}
> +
> static void tcg_target_init(TCGContext *s)
> {
> + tcg_target_detect_isa();
> +
> tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
> tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb
2023-05-03 8:56 ` [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
@ 2023-05-16 23:38 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:38 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:58 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target-con-str.h | 1 +
> tcg/riscv/tcg-target.h | 12 +++++-----
> tcg/riscv/tcg-target.c.inc | 41 ++++++++++++++++++++++++++++++++++
> 4 files changed, 49 insertions(+), 6 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index d88888d3ac..1a33ece98f 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -15,6 +15,7 @@ C_O0_I2(rZ, rZ)
> C_O1_I1(r, r)
> C_O1_I2(r, r, ri)
> C_O1_I2(r, r, rI)
> +C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
> index 6f1cfb976c..d5c419dff1 100644
> --- a/tcg/riscv/tcg-target-con-str.h
> +++ b/tcg/riscv/tcg-target-con-str.h
> @@ -15,6 +15,7 @@ REGS('r', ALL_GENERAL_REGS)
> * CONST(letter, TCG_CT_CONST_* bit set)
> */
> CONST('I', TCG_CT_CONST_S12)
> +CONST('J', TCG_CT_CONST_J12)
> CONST('N', TCG_CT_CONST_N12)
> CONST('M', TCG_CT_CONST_M12)
> CONST('Z', TCG_CT_CONST_ZERO)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 863ac8ba2f..9f58d46208 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -120,9 +120,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_bswap32_i32 0
> #define TCG_TARGET_HAS_not_i32 1
> #define TCG_TARGET_HAS_neg_i32 1
> -#define TCG_TARGET_HAS_andc_i32 0
> -#define TCG_TARGET_HAS_orc_i32 0
> -#define TCG_TARGET_HAS_eqv_i32 0
> +#define TCG_TARGET_HAS_andc_i32 have_zbb
> +#define TCG_TARGET_HAS_orc_i32 have_zbb
> +#define TCG_TARGET_HAS_eqv_i32 have_zbb
> #define TCG_TARGET_HAS_nand_i32 0
> #define TCG_TARGET_HAS_nor_i32 0
> #define TCG_TARGET_HAS_clz_i32 0
> @@ -154,9 +154,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_bswap64_i64 0
> #define TCG_TARGET_HAS_not_i64 1
> #define TCG_TARGET_HAS_neg_i64 1
> -#define TCG_TARGET_HAS_andc_i64 0
> -#define TCG_TARGET_HAS_orc_i64 0
> -#define TCG_TARGET_HAS_eqv_i64 0
> +#define TCG_TARGET_HAS_andc_i64 have_zbb
> +#define TCG_TARGET_HAS_orc_i64 have_zbb
> +#define TCG_TARGET_HAS_eqv_i64 have_zbb
> #define TCG_TARGET_HAS_nand_i64 0
> #define TCG_TARGET_HAS_nor_i64 0
> #define TCG_TARGET_HAS_clz_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 49ff9c8b9d..c5b060023f 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -138,6 +138,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
> #define TCG_CT_CONST_S12 0x200
> #define TCG_CT_CONST_N12 0x400
> #define TCG_CT_CONST_M12 0x800
> +#define TCG_CT_CONST_J12 0x1000
>
> #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
>
> @@ -174,6 +175,13 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
> if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
> return 1;
> }
> + /*
> + * Inverse of sign extended from 12 bits: ~[-0x800, 0x7ff].
> + * Used to map ANDN back to ANDI, etc.
> + */
> + if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
> + return 1;
> + }
> return 0;
> }
>
> @@ -1306,6 +1314,31 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_andc_i32:
> + case INDEX_op_andc_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_ANDI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_ANDN, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_orc_i32:
> + case INDEX_op_orc_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_ORI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_ORN, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_eqv_i32:
> + case INDEX_op_eqv_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_XORI, a0, a1, ~a2);
> + } else {
> + tcg_out_opc_reg(s, OPC_XNOR, a0, a1, a2);
> + }
> + break;
> +
> case INDEX_op_not_i32:
> case INDEX_op_not_i64:
> tcg_out_opc_imm(s, OPC_XORI, a0, a1, -1);
> @@ -1536,6 +1569,14 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_xor_i64:
> return C_O1_I2(r, r, rI);
>
> + case INDEX_op_andc_i32:
> + case INDEX_op_andc_i64:
> + case INDEX_op_orc_i32:
> + case INDEX_op_orc_i64:
> + case INDEX_op_eqv_i32:
> + case INDEX_op_eqv_i64:
> + return C_O1_I2(r, r, rJ);
> +
> case INDEX_op_sub_i32:
> case INDEX_op_sub_i64:
> return C_O1_I2(r, rZ, rN);
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb
2023-05-03 8:56 ` [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb Richard Henderson
2023-05-08 12:39 ` Daniel Henrique Barboza
@ 2023-05-16 23:40 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:40 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.c.inc | 32 ++++++++++++++++++++++++--------
> 1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index c5b060023f..53a7f97b29 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -593,26 +593,42 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
>
> static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> - tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
> + if (have_zbb) {
> + tcg_out_opc_reg(s, OPC_ZEXT_H, ret, arg, TCG_REG_ZERO);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> + tcg_out_opc_imm(s, OPC_SRLIW, ret, ret, 16);
> + }
> }
>
> static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
> - tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
> + if (have_zba) {
> + tcg_out_opc_reg(s, OPC_ADD_UW, ret, arg, TCG_REG_ZERO);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
> + tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
> + }
> }
>
> static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
> - tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
> + if (have_zbb) {
> + tcg_out_opc_imm(s, OPC_SEXT_B, ret, arg, 0);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
> + tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
> + }
> }
>
> static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> - tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> - tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
> + if (have_zbb) {
> + tcg_out_opc_imm(s, OPC_SEXT_H, ret, arg, 0);
> + } else {
> + tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
> + tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
> + }
> }
>
> static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation
2023-05-03 8:56 ` [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation Richard Henderson
2023-05-08 12:43 ` Daniel Henrique Barboza
@ 2023-05-16 23:43 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:43 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
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
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 06/11] tcg/riscv: Support rotates from Zbb
2023-05-03 8:56 ` [PATCH 06/11] tcg/riscv: Support rotates from Zbb Richard Henderson
2023-05-08 12:44 ` Daniel Henrique Barboza
@ 2023-05-16 23:48 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:48 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:57 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.h | 4 ++--
> tcg/riscv/tcg-target.c.inc | 34 ++++++++++++++++++++++++++++++++++
> 2 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 9f58d46208..317d385924 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -101,7 +101,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_div_i32 1
> #define TCG_TARGET_HAS_rem_i32 1
> #define TCG_TARGET_HAS_div2_i32 0
> -#define TCG_TARGET_HAS_rot_i32 0
> +#define TCG_TARGET_HAS_rot_i32 have_zbb
> #define TCG_TARGET_HAS_deposit_i32 0
> #define TCG_TARGET_HAS_extract_i32 0
> #define TCG_TARGET_HAS_sextract_i32 0
> @@ -136,7 +136,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_div_i64 1
> #define TCG_TARGET_HAS_rem_i64 1
> #define TCG_TARGET_HAS_div2_i64 0
> -#define TCG_TARGET_HAS_rot_i64 0
> +#define TCG_TARGET_HAS_rot_i64 have_zbb
> #define TCG_TARGET_HAS_deposit_i64 0
> #define TCG_TARGET_HAS_extract_i64 0
> #define TCG_TARGET_HAS_sextract_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index f64eaa8515..58f969b4fe 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1458,6 +1458,36 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_rotl_i32:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORIW, a0, a1, -a2 & 0x1f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROLW, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_rotl_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORI, a0, a1, -a2 & 0x3f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROL, a0, a1, a2);
> + }
> + break;
> +
> + case INDEX_op_rotr_i32:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORIW, a0, a1, a2 & 0x1f);
> + } else {
> + tcg_out_opc_reg(s, OPC_RORW, a0, a1, a2);
> + }
> + break;
> + case INDEX_op_rotr_i64:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_RORI, a0, a1, a2 & 0x3f);
> + } else {
> + tcg_out_opc_reg(s, OPC_ROR, a0, a1, a2);
> + }
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1629,9 +1659,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_shl_i32:
> case INDEX_op_shr_i32:
> case INDEX_op_sar_i32:
> + case INDEX_op_rotl_i32:
> + case INDEX_op_rotr_i32:
> case INDEX_op_shl_i64:
> case INDEX_op_shr_i64:
> case INDEX_op_sar_i64:
> + case INDEX_op_rotl_i64:
> + case INDEX_op_rotr_i64:
> return C_O1_I2(r, r, ri);
>
> case INDEX_op_brcond_i32:
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 07/11] tcg/riscv: Support REV8 from Zbb
2023-05-03 8:56 ` [PATCH 07/11] tcg/riscv: Support REV8 " Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
@ 2023-05-16 23:50 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:50 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.h | 10 +++++-----
> tcg/riscv/tcg-target.c.inc | 29 +++++++++++++++++++++++++++++
> 2 files changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 317d385924..8e327afc3a 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -116,8 +116,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_ext16s_i32 1
> #define TCG_TARGET_HAS_ext8u_i32 1
> #define TCG_TARGET_HAS_ext16u_i32 1
> -#define TCG_TARGET_HAS_bswap16_i32 0
> -#define TCG_TARGET_HAS_bswap32_i32 0
> +#define TCG_TARGET_HAS_bswap16_i32 have_zbb
> +#define TCG_TARGET_HAS_bswap32_i32 have_zbb
> #define TCG_TARGET_HAS_not_i32 1
> #define TCG_TARGET_HAS_neg_i32 1
> #define TCG_TARGET_HAS_andc_i32 have_zbb
> @@ -149,9 +149,9 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_ext8u_i64 1
> #define TCG_TARGET_HAS_ext16u_i64 1
> #define TCG_TARGET_HAS_ext32u_i64 1
> -#define TCG_TARGET_HAS_bswap16_i64 0
> -#define TCG_TARGET_HAS_bswap32_i64 0
> -#define TCG_TARGET_HAS_bswap64_i64 0
> +#define TCG_TARGET_HAS_bswap16_i64 have_zbb
> +#define TCG_TARGET_HAS_bswap32_i64 have_zbb
> +#define TCG_TARGET_HAS_bswap64_i64 have_zbb
> #define TCG_TARGET_HAS_not_i64 1
> #define TCG_TARGET_HAS_neg_i64 1
> #define TCG_TARGET_HAS_andc_i64 have_zbb
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 58f969b4fe..9cbefb2833 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1488,6 +1488,30 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_bswap64_i64:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + break;
> + case INDEX_op_bswap32_i32:
> + a2 = 0;
> + /* fall through */
> + case INDEX_op_bswap32_i64:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + if (a2 & TCG_BSWAP_OZ) {
> + tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 32);
> + } else {
> + tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 32);
> + }
> + break;
> + case INDEX_op_bswap16_i64:
> + case INDEX_op_bswap16_i32:
> + tcg_out_opc_imm(s, OPC_REV8, a0, a1, 0);
> + if (a2 & TCG_BSWAP_OZ) {
> + tcg_out_opc_imm(s, OPC_SRLI, a0, a0, 48);
> + } else {
> + tcg_out_opc_imm(s, OPC_SRAI, a0, a0, 48);
> + }
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1605,6 +1629,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_extrl_i64_i32:
> case INDEX_op_extrh_i64_i32:
> case INDEX_op_ext_i32_i64:
> + case INDEX_op_bswap16_i32:
> + case INDEX_op_bswap32_i32:
> + case INDEX_op_bswap16_i64:
> + case INDEX_op_bswap32_i64:
> + case INDEX_op_bswap64_i64:
> return C_O1_I1(r, r);
>
> case INDEX_op_st8_i32:
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 08/11] tcg/riscv: Support CPOP from Zbb
2023-05-03 8:56 ` [PATCH 08/11] tcg/riscv: Support CPOP " Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
@ 2023-05-16 23:50 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-16 23:50 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:58 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.h | 4 ++--
> tcg/riscv/tcg-target.c.inc | 9 +++++++++
> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index 8e327afc3a..e0b23006c4 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -127,7 +127,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_nor_i32 0
> #define TCG_TARGET_HAS_clz_i32 0
> #define TCG_TARGET_HAS_ctz_i32 0
> -#define TCG_TARGET_HAS_ctpop_i32 0
> +#define TCG_TARGET_HAS_ctpop_i32 have_zbb
> #define TCG_TARGET_HAS_brcond2 1
> #define TCG_TARGET_HAS_setcond2 1
> #define TCG_TARGET_HAS_qemu_st8_i32 0
> @@ -161,7 +161,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_nor_i64 0
> #define TCG_TARGET_HAS_clz_i64 0
> #define TCG_TARGET_HAS_ctz_i64 0
> -#define TCG_TARGET_HAS_ctpop_i64 0
> +#define TCG_TARGET_HAS_ctpop_i64 have_zbb
> #define TCG_TARGET_HAS_add2_i64 1
> #define TCG_TARGET_HAS_sub2_i64 1
> #define TCG_TARGET_HAS_mulu2_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 9cbefb2833..044ddfb160 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1512,6 +1512,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> }
> break;
>
> + case INDEX_op_ctpop_i32:
> + tcg_out_opc_imm(s, OPC_CPOPW, a0, a1, 0);
> + break;
> + case INDEX_op_ctpop_i64:
> + tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1634,6 +1641,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_bswap16_i64:
> case INDEX_op_bswap32_i64:
> case INDEX_op_bswap64_i64:
> + case INDEX_op_ctpop_i32:
> + case INDEX_op_ctpop_i64:
> return C_O1_I1(r, r);
>
> case INDEX_op_st8_i32:
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 09/11] tcg/riscv: Improve setcond expansion
2023-05-03 8:56 ` [PATCH 09/11] tcg/riscv: Improve setcond expansion Richard Henderson
2023-05-08 12:46 ` Daniel Henrique Barboza
@ 2023-05-17 0:16 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-17 0:16 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Split out a helper function, tcg_out_setcond_int, which does not
> always produce the complete boolean result, but returns a set of
> flags to do so.
>
> Based on 21af16198425, the same improvement for loongarch64.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target.c.inc | 164 +++++++++++++++++++++++++++----------
> 1 file changed, 121 insertions(+), 43 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 044ddfb160..84b646105c 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -812,50 +812,128 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
> tcg_out_opc_branch(s, op, arg1, arg2, 0);
> }
>
> -static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> - TCGReg arg1, TCGReg arg2)
> +#define SETCOND_INV TCG_TARGET_NB_REGS
> +#define SETCOND_NEZ (SETCOND_INV << 1)
> +#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
> +
> +static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg arg1, tcg_target_long arg2, bool c2)
> {
> + int flags = 0;
> +
> switch (cond) {
> - case TCG_COND_EQ:
> - tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
> - break;
> - case TCG_COND_NE:
> - tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
> - tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
> - break;
> - case TCG_COND_LT:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> - break;
> - case TCG_COND_GE:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_LE:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_GT:
> - tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
> - break;
> - case TCG_COND_LTU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> - break;
> - case TCG_COND_GEU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_LEU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
> - tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
> - break;
> - case TCG_COND_GTU:
> - tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
> + case TCG_COND_EQ: /* -> NE */
> + case TCG_COND_GE: /* -> LT */
> + case TCG_COND_GEU: /* -> LTU */
> + case TCG_COND_GT: /* -> LE */
> + case TCG_COND_GTU: /* -> LEU */
> + cond = tcg_invert_cond(cond);
> + flags ^= SETCOND_INV;
> break;
> default:
> - g_assert_not_reached();
> - break;
> - }
> + break;
> + }
> +
> + switch (cond) {
> + case TCG_COND_LE:
> + case TCG_COND_LEU:
> + /*
> + * If we have a constant input, the most efficient way to implement
> + * LE is by adding 1 and using LT. Watch out for wrap around for LEU.
> + * We don't need to care for this for LE because the constant input
> + * is constrained to signed 12-bit, and 0x800 is representable in the
> + * temporary register.
> + */
> + if (c2) {
> + if (cond == TCG_COND_LEU) {
> + /* unsigned <= -1 is true */
> + if (arg2 == -1) {
> + tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
> + return ret;
> + }
> + cond = TCG_COND_LTU;
> + } else {
> + cond = TCG_COND_LT;
> + }
> + tcg_debug_assert(arg2 <= 0x7ff);
> + if (++arg2 == 0x800) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
> + arg2 = TCG_REG_TMP0;
> + c2 = false;
> + }
> + } else {
> + TCGReg tmp = arg2;
> + arg2 = arg1;
> + arg1 = tmp;
> + cond = tcg_swap_cond(cond); /* LE -> GE */
> + cond = tcg_invert_cond(cond); /* GE -> LT */
> + flags ^= SETCOND_INV;
> + }
> + break;
> + default:
> + break;
> + }
> +
> + switch (cond) {
> + case TCG_COND_NE:
> + flags |= SETCOND_NEZ;
> + if (!c2) {
> + tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
> + } else if (arg2 == 0) {
> + ret = arg1;
> + } else {
> + tcg_out_opc_reg(s, OPC_XORI, ret, arg1, arg2);
> + }
> + break;
> +
> + case TCG_COND_LT:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_SLTI, ret, arg1, arg2);
> + } else {
> + tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
> + }
> + break;
> +
> + case TCG_COND_LTU:
> + if (c2) {
> + tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, arg2);
> + } else {
> + tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
> + }
> + break;
> +
> + default:
> + g_assert_not_reached();
> + }
> +
> + return ret | flags;
> +}
> +
> +static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg arg1, tcg_target_long arg2, bool c2)
> +{
> + int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
> +
> + if (tmpflags != ret) {
> + TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
> +
> + switch (tmpflags & SETCOND_FLAGS) {
> + case SETCOND_INV:
> + /* Intermediate result is boolean: simply invert. */
> + tcg_out_opc_imm(s, OPC_XORI, ret, tmp, 1);
> + break;
> + case SETCOND_NEZ:
> + /* Intermediate result is zero/non-zero: test != 0. */
> + tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp);
> + break;
> + case SETCOND_NEZ | SETCOND_INV:
> + /* Intermediate result is zero/non-zero: test == 0. */
> + tcg_out_opc_imm(s, OPC_SLTIU, ret, tmp, 1);
> + break;
> + default:
> + g_assert_not_reached();
> + }
> + }
> }
>
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> @@ -1543,7 +1621,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
>
> case INDEX_op_setcond_i32:
> case INDEX_op_setcond_i64:
> - tcg_out_setcond(s, args[3], a0, a1, a2);
> + tcg_out_setcond(s, args[3], a0, a1, a2, c2);
> break;
>
> case INDEX_op_qemu_ld_i32:
> @@ -1662,6 +1740,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_and_i64:
> case INDEX_op_or_i64:
> case INDEX_op_xor_i64:
> + case INDEX_op_setcond_i32:
> + case INDEX_op_setcond_i64:
> return C_O1_I2(r, r, rI);
>
> case INDEX_op_andc_i32:
> @@ -1683,7 +1763,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_divu_i32:
> case INDEX_op_rem_i32:
> case INDEX_op_remu_i32:
> - case INDEX_op_setcond_i32:
> case INDEX_op_mul_i64:
> case INDEX_op_mulsh_i64:
> case INDEX_op_muluh_i64:
> @@ -1691,7 +1770,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_divu_i64:
> case INDEX_op_rem_i64:
> case INDEX_op_remu_i64:
> - case INDEX_op_setcond_i64:
> return C_O1_I2(r, rZ, rZ);
>
> case INDEX_op_shl_i32:
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 10/11] tcg/riscv: Implement movcond
2023-05-03 8:56 ` [PATCH 10/11] tcg/riscv: Implement movcond Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
@ 2023-05-17 0:19 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-17 0:19 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:59 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Implement with and without Zicond. Without Zicond, we were letting
> the middle-end expand to a 5 insn sequence; better to use a branch
> over a single insn.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target.h | 4 +-
> tcg/riscv/tcg-target.c.inc | 139 ++++++++++++++++++++++++++++++++-
> 3 files changed, 141 insertions(+), 3 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index 1a33ece98f..a5cadd303f 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -18,4 +18,5 @@ C_O1_I2(r, r, rI)
> C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> +C_O1_I4(r, r, rI, rM, rM)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index e0b23006c4..e9e84be9a5 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -97,7 +97,7 @@ extern bool have_zbb;
> #endif
>
> /* optional instructions */
> -#define TCG_TARGET_HAS_movcond_i32 0
> +#define TCG_TARGET_HAS_movcond_i32 1
> #define TCG_TARGET_HAS_div_i32 1
> #define TCG_TARGET_HAS_rem_i32 1
> #define TCG_TARGET_HAS_div2_i32 0
> @@ -132,7 +132,7 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_setcond2 1
> #define TCG_TARGET_HAS_qemu_st8_i32 0
>
> -#define TCG_TARGET_HAS_movcond_i64 0
> +#define TCG_TARGET_HAS_movcond_i64 1
> #define TCG_TARGET_HAS_div_i64 1
> #define TCG_TARGET_HAS_rem_i64 1
> #define TCG_TARGET_HAS_div2_i64 0
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 84b646105c..1c57b64182 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -169,7 +169,7 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
> }
> /*
> * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
> - * Used by addsub2, which may need the negative operation,
> + * Used by addsub2 and movcond, which may need the negative value,
> * and requires the modified constant to be representable.
> */
> if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
> @@ -936,6 +936,133 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> }
> }
>
> +static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne,
> + int val1, bool c_val1,
> + int val2, bool c_val2)
> +{
> + if (val1 == 0) {
> + if (c_val2) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val2);
> + val2 = TCG_REG_TMP1;
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, val2, test_ne);
> + return;
> + }
> +
> + if (val2 == 0) {
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1);
> + val1 = TCG_REG_TMP1;
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, val1, test_ne);
> + return;
> + }
> +
> + if (c_val2) {
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP1, val1 - val2);
> + } else {
> + tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val1, -val2);
> + }
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, ret, TCG_REG_TMP1, test_ne);
> + tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val2);
> + return;
> + }
> +
> + if (c_val1) {
> + tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP1, val2, -val1);
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, ret, TCG_REG_TMP1, test_ne);
> + tcg_out_opc_imm(s, OPC_ADDI, ret, ret, val1);
> + return;
> + }
> +
> + tcg_out_opc_reg(s, OPC_CZERO_NEZ, TCG_REG_TMP1, val2, test_ne);
> + tcg_out_opc_reg(s, OPC_CZERO_EQZ, TCG_REG_TMP0, val1, test_ne);
> + tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_TMP0, TCG_REG_TMP1);
> +}
> +
> +static void tcg_out_movcond_br1(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, TCGReg cmp2,
> + int val, bool c_val)
> +{
> + RISCVInsn op;
> + int disp = 8;
> +
> + tcg_debug_assert((unsigned)cond < ARRAY_SIZE(tcg_brcond_to_riscv));
> + op = tcg_brcond_to_riscv[cond].op;
> + tcg_debug_assert(op != 0);
> +
> + if (tcg_brcond_to_riscv[cond].swap) {
> + tcg_out_opc_branch(s, op, cmp2, cmp1, disp);
> + } else {
> + tcg_out_opc_branch(s, op, cmp1, cmp2, disp);
> + }
> + if (c_val) {
> + tcg_out_opc_imm(s, OPC_ADDI, ret, TCG_REG_ZERO, val);
> + } else {
> + tcg_out_opc_imm(s, OPC_ADDI, ret, val, 0);
> + }
> +}
> +
> +static void tcg_out_movcond_br2(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, TCGReg cmp2,
> + int val1, bool c_val1,
> + int val2, bool c_val2)
> +{
> + TCGReg tmp;
> +
> + /* TCG optimizer reorders to prefer ret matching val2. */
> + if (!c_val2 && ret == val2) {
> + cond = tcg_invert_cond(cond);
> + tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val1, c_val1);
> + return;
> + }
> +
> + if (!c_val1 && ret == val1) {
> + tcg_out_movcond_br1(s, cond, ret, cmp1, cmp2, val2, c_val2);
> + return;
> + }
> +
> + tmp = (ret == cmp1 || ret == cmp2 ? TCG_REG_TMP1 : ret);
> + if (c_val1) {
> + tcg_out_movi(s, TCG_TYPE_REG, tmp, val1);
> + } else {
> + tcg_out_mov(s, TCG_TYPE_REG, tmp, val1);
> + }
> + tcg_out_movcond_br1(s, cond, tmp, cmp1, cmp2, val2, c_val2);
> + tcg_out_mov(s, TCG_TYPE_REG, ret, tmp);
> +}
> +
> +static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
> + TCGReg cmp1, int cmp2, bool c_cmp2,
> + TCGReg val1, bool c_val1,
> + TCGReg val2, bool c_val2)
> +{
> + int tmpflags;
> + TCGReg t;
> +
> + if (!have_zicond && (!c_cmp2 || cmp2 == 0)) {
> + tcg_out_movcond_br2(s, cond, ret, cmp1, cmp2,
> + val1, c_val1, val2, c_val2);
> + return;
> + }
> +
> + tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, cmp1, cmp2, c_cmp2);
> + t = tmpflags & ~SETCOND_FLAGS;
> +
> + if (have_zicond) {
> + if (tmpflags & SETCOND_INV) {
> + tcg_out_movcond_zicond(s, ret, t, val2, c_val2, val1, c_val1);
> + } else {
> + tcg_out_movcond_zicond(s, ret, t, val1, c_val1, val2, c_val2);
> + }
> + } else {
> + cond = tmpflags & SETCOND_INV ? TCG_COND_EQ : TCG_COND_NE;
> + tcg_out_movcond_br2(s, cond, ret, t, TCG_REG_ZERO,
> + val1, c_val1, val2, c_val2);
> + }
> +}
> +
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> {
> TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
> @@ -1624,6 +1751,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> tcg_out_setcond(s, args[3], a0, a1, a2, c2);
> break;
>
> + case INDEX_op_movcond_i32:
> + case INDEX_op_movcond_i64:
> + tcg_out_movcond(s, args[5], a0, a1, a2, c2,
> + args[3], const_args[3], args[4], const_args[4]);
> + break;
> +
> case INDEX_op_qemu_ld_i32:
> tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
> break;
> @@ -1788,6 +1921,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_brcond_i64:
> return C_O0_I2(rZ, rZ);
>
> + case INDEX_op_movcond_i32:
> + case INDEX_op_movcond_i64:
> + return C_O1_I4(r, r, rI, rM, rM);
> +
> case INDEX_op_add2_i32:
> case INDEX_op_add2_i64:
> case INDEX_op_sub2_i32:
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb
2023-05-03 8:56 ` [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
@ 2023-05-17 1:47 ` Alistair Francis
1 sibling, 0 replies; 35+ messages in thread
From: Alistair Francis @ 2023-05-17 1:47 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, dbarboza
On Wed, May 3, 2023 at 6:57 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tcg/riscv/tcg-target-con-set.h | 1 +
> tcg/riscv/tcg-target.h | 8 ++++----
> tcg/riscv/tcg-target.c.inc | 35 ++++++++++++++++++++++++++++++++++
> 3 files changed, 40 insertions(+), 4 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index a5cadd303f..aac5ceee2b 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -18,5 +18,6 @@ C_O1_I2(r, r, rI)
> C_O1_I2(r, r, rJ)
> C_O1_I2(r, rZ, rN)
> C_O1_I2(r, rZ, rZ)
> +C_N1_I2(r, r, rM)
> C_O1_I4(r, r, rI, rM, rM)
> C_O2_I4(r, r, rZ, rZ, rM, rM)
> diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
> index e9e84be9a5..cff5de5c9e 100644
> --- a/tcg/riscv/tcg-target.h
> +++ b/tcg/riscv/tcg-target.h
> @@ -125,8 +125,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_eqv_i32 have_zbb
> #define TCG_TARGET_HAS_nand_i32 0
> #define TCG_TARGET_HAS_nor_i32 0
> -#define TCG_TARGET_HAS_clz_i32 0
> -#define TCG_TARGET_HAS_ctz_i32 0
> +#define TCG_TARGET_HAS_clz_i32 1
> +#define TCG_TARGET_HAS_ctz_i32 1
> #define TCG_TARGET_HAS_ctpop_i32 have_zbb
> #define TCG_TARGET_HAS_brcond2 1
> #define TCG_TARGET_HAS_setcond2 1
> @@ -159,8 +159,8 @@ extern bool have_zbb;
> #define TCG_TARGET_HAS_eqv_i64 have_zbb
> #define TCG_TARGET_HAS_nand_i64 0
> #define TCG_TARGET_HAS_nor_i64 0
> -#define TCG_TARGET_HAS_clz_i64 0
> -#define TCG_TARGET_HAS_ctz_i64 0
> +#define TCG_TARGET_HAS_clz_i64 1
> +#define TCG_TARGET_HAS_ctz_i64 1
> #define TCG_TARGET_HAS_ctpop_i64 have_zbb
> #define TCG_TARGET_HAS_add2_i64 1
> #define TCG_TARGET_HAS_sub2_i64 1
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index 1c57b64182..a1c92b0603 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -1063,6 +1063,22 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
> }
> }
>
> +static void tcg_out_cltz(TCGContext *s, TCGType type, RISCVInsn insn,
> + TCGReg ret, TCGReg src1, int src2, bool c_src2)
> +{
> + tcg_out_opc_imm(s, insn, ret, src1, 0);
> +
> + if (!c_src2 || src2 != (type == TCG_TYPE_I32 ? 32 : 64)) {
> + /*
> + * The requested zero result does not match the insn, so adjust.
> + * Note that constraints put 'ret' in a new register, so the
> + * computation above did not clobber either 'src1' or 'src2'.
> + */
> + tcg_out_movcond(s, TCG_COND_EQ, ret, src1, 0, true,
> + src2, c_src2, ret, false);
> + }
> +}
> +
> static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
> {
> TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
> @@ -1724,6 +1740,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
> tcg_out_opc_imm(s, OPC_CPOP, a0, a1, 0);
> break;
>
> + case INDEX_op_clz_i32:
> + tcg_out_cltz(s, TCG_TYPE_I32, OPC_CLZW, a0, a1, a2, c2);
> + break;
> + case INDEX_op_clz_i64:
> + tcg_out_cltz(s, TCG_TYPE_I64, OPC_CLZ, a0, a1, a2, c2);
> + break;
> + case INDEX_op_ctz_i32:
> + tcg_out_cltz(s, TCG_TYPE_I32, OPC_CTZW, a0, a1, a2, c2);
> + break;
> + case INDEX_op_ctz_i64:
> + tcg_out_cltz(s, TCG_TYPE_I64, OPC_CTZ, a0, a1, a2, c2);
> + break;
> +
> case INDEX_op_add2_i32:
> tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
> const_args[4], const_args[5], false, true);
> @@ -1917,6 +1946,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
> case INDEX_op_rotr_i64:
> return C_O1_I2(r, r, ri);
>
> + case INDEX_op_clz_i32:
> + case INDEX_op_clz_i64:
> + case INDEX_op_ctz_i32:
> + case INDEX_op_ctz_i64:
> + return C_N1_I2(r, r, rM);
> +
> case INDEX_op_brcond_i32:
> case INDEX_op_brcond_i64:
> return C_O0_I2(rZ, rZ);
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2023-05-17 1:49 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-03 8:56 [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Richard Henderson
2023-05-03 8:56 ` [PATCH 01/11] disas/riscv: Decode czero.{eqz,nez} Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:33 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:35 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 03/11] tcg/riscv: Support ANDN, ORN, XNOR from Zbb Richard Henderson
2023-05-08 12:37 ` Daniel Henrique Barboza
2023-05-16 23:38 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 04/11] tcg/riscv: Support ADD.UW, SEXT.B, SEXT.H, ZEXT.H from Zba+Zbb Richard Henderson
2023-05-08 12:39 ` Daniel Henrique Barboza
2023-05-16 23:40 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 05/11] tcg/riscv: Use ADD.UW for guest address generation Richard Henderson
2023-05-08 12:43 ` Daniel Henrique Barboza
2023-05-16 23:43 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 06/11] tcg/riscv: Support rotates from Zbb Richard Henderson
2023-05-08 12:44 ` Daniel Henrique Barboza
2023-05-16 23:48 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 07/11] tcg/riscv: Support REV8 " Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 08/11] tcg/riscv: Support CPOP " Richard Henderson
2023-05-08 12:45 ` Daniel Henrique Barboza
2023-05-16 23:50 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 09/11] tcg/riscv: Improve setcond expansion Richard Henderson
2023-05-08 12:46 ` Daniel Henrique Barboza
2023-05-17 0:16 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 10/11] tcg/riscv: Implement movcond Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 0:19 ` Alistair Francis
2023-05-03 8:56 ` [PATCH 11/11] tcg/riscv: Support CTZ, CLZ from Zbb Richard Henderson
2023-05-08 12:47 ` Daniel Henrique Barboza
2023-05-17 1:47 ` Alistair Francis
2023-05-08 12:53 ` [PATCH 00/11] tcg/riscv: Support for Zba, Zbb, Zicond extensions Daniel Henrique Barboza
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.