* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).