1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
The following changes since commit d52dff5d8048d4982437db9606c27bb4127cf9d0:
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
5
Merge remote-tracking branch 'remotes/marcandre/tags/clip-pull-request' into staging (2021-08-31 14:38:15 +0100)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210901-2
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
10
8
11
for you to fetch changes up to 8e034ae44dba6291beb07f7f2a932c1e5ab83e98:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
12
10
13
target/riscv: Use {get,dest}_gpr for RVV (2021-09-01 11:59:12 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
First RISC-V PR for QEMU 6.2
14
First RISC-V PR for 8.2
17
15
18
- Add a config for Shakti UART
16
* Remove 'host' CPU from TCG
19
- Fixup virt flash node
17
* riscv_htif Fixup printing on big endian hosts
20
- Don't override users supplied ISA version
18
* Add zmmul isa string
21
- Fixup some CSR accesses
19
* Add smepmp isa string
22
- Use g_strjoinv() for virt machine PLIC string config
20
* Fix page_check_range use in fault-only-first
23
- Fix an overflow in the SiFive CLINT
21
* Use existing lookup tables for MixColumns
24
- Add 64-bit register access helpers
22
* Add RISC-V vector cryptographic instruction set support
25
- Replace tcg_const_* with direct constant usage
23
* Implement WARL behaviour for mcountinhibit/mcounteren
24
* Add Zihintntl extension ISA string to DTS
25
* Fix zfa fleq.d and fltq.d
26
* Fix upper/lower mtime write calculation
27
* Make rtc variable names consistent
28
* Use abi type for linux-user target_ucontext
29
* Add RISC-V KVM AIA Support
30
* Fix riscv,pmu DT node path in the virt machine
31
* Update CSR bits name for svadu extension
32
* Mark zicond non-experimental
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Fix non-KVM --enable-debug build
35
* Add new extensions to hwprobe
36
* Use accelerated helper for AES64KS1I
37
* Allocate itrigger timers only once
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Align the AIA model to v1.0 ratified spec
40
* Don't read the CSR in riscv_csrrw_do64
26
41
27
----------------------------------------------------------------
42
----------------------------------------------------------------
28
Bin Meng (2):
43
Akihiko Odaki (1):
29
hw/riscv: virt: Move flash node to root
44
target/riscv: Allocate itrigger timers only once
30
target/riscv: Correct a comment in riscv_csrrw()
31
45
32
David Hoppenbrouwers (1):
46
Ard Biesheuvel (2):
33
hw/intc/sifive_clint: Fix muldiv64 overflow in sifive_clint_write_timecmp()
47
target/riscv: Use existing lookup tables for MixColumns
48
target/riscv: Use accelerated helper for AES64KS1I
34
49
35
Joe Komlodi (2):
50
Conor Dooley (1):
36
hw/core/register: Add more 64-bit utilities
51
hw/riscv: virt: Fix riscv,pmu DT node path
37
hw/registerfields: Use 64-bit bitfield for FIELD_DP64
38
52
39
LIU Zhiwei (2):
53
Daniel Henrique Barboza (6):
40
target/riscv: Don't wrongly override isa version
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
41
target/riscv: Add User CSRs read-only check
55
target/riscv/cpu.c: add zmmul isa string
56
target/riscv/cpu.c: add smepmp isa string
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
42
60
43
Peter Maydell (1):
61
Dickon Hood (2):
44
hw/riscv/virt.c: Assemble plic_hart_config string with g_strjoinv()
62
target/riscv: Refactor translation of vector-widening instruction
63
target/riscv: Add Zvbb ISA extension support
45
64
46
Richard Henderson (24):
65
Jason Chien (3):
47
target/riscv: Use tcg_constant_*
66
target/riscv: Add Zihintntl extension ISA string to DTS
48
tests/tcg/riscv64: Add test for division
67
hw/intc: Fix upper/lower mtime write calculation
49
target/riscv: Clean up division helpers
68
hw/intc: Make rtc variable names consistent
50
target/riscv: Add DisasContext to gen_get_gpr, gen_set_gpr
51
target/riscv: Introduce DisasExtend and new helpers
52
target/riscv: Add DisasExtend to gen_arith*
53
target/riscv: Remove gen_arith_div*
54
target/riscv: Use gen_arith for mulh and mulhu
55
target/riscv: Move gen_* helpers for RVM
56
target/riscv: Move gen_* helpers for RVB
57
target/riscv: Add DisasExtend to gen_unary
58
target/riscv: Use DisasExtend in shift operations
59
target/riscv: Use extracts for sraiw and srliw
60
target/riscv: Use get_gpr in branches
61
target/riscv: Use {get, dest}_gpr for integer load/store
62
target/riscv: Fix rmw_sip, rmw_vsip, rmw_hsip vs write-only operation
63
target/riscv: Fix hgeie, hgeip
64
target/riscv: Reorg csr instructions
65
target/riscv: Use {get,dest}_gpr for RVA
66
target/riscv: Use gen_shift_imm_fn for slli_uw
67
target/riscv: Use {get,dest}_gpr for RVF
68
target/riscv: Use {get,dest}_gpr for RVD
69
target/riscv: Tidy trans_rvh.c.inc
70
target/riscv: Use {get,dest}_gpr for RVV
71
69
72
Vijai Kumar K (1):
70
Kiran Ostrolenk (4):
73
hw/char: Add config for shakti uart
71
target/riscv: Refactor some of the generic vector functionality
72
target/riscv: Refactor vector-vector translation macro
73
target/riscv: Refactor some of the generic vector functionality
74
target/riscv: Add Zvknh ISA extension support
74
75
75
include/hw/register.h | 8 +
76
LIU Zhiwei (3):
76
include/hw/registerfields.h | 10 +-
77
target/riscv: Fix page_check_range use in fault-only-first
77
target/riscv/helper.h | 6 +-
78
target/riscv: Fix zfa fleq.d and fltq.d
78
target/riscv/insn32.decode | 1 +
79
linux-user/riscv: Use abi type for target_ucontext
79
hw/core/register.c | 12 +
80
hw/intc/sifive_clint.c | 25 +-
81
hw/riscv/virt.c | 35 +-
82
target/riscv/cpu.c | 14 +-
83
target/riscv/csr.c | 59 ++-
84
target/riscv/op_helper.c | 18 +-
85
target/riscv/translate.c | 689 +++++++-------------------------
86
tests/tcg/riscv64/test-div.c | 58 +++
87
target/riscv/insn_trans/trans_rva.c.inc | 49 +--
88
target/riscv/insn_trans/trans_rvb.c.inc | 366 +++++++++++++----
89
target/riscv/insn_trans/trans_rvd.c.inc | 127 +++---
90
target/riscv/insn_trans/trans_rvf.c.inc | 149 ++++---
91
target/riscv/insn_trans/trans_rvh.c.inc | 266 +++---------
92
target/riscv/insn_trans/trans_rvi.c.inc | 372 +++++++++--------
93
target/riscv/insn_trans/trans_rvm.c.inc | 193 +++++++--
94
target/riscv/insn_trans/trans_rvv.c.inc | 149 +++----
95
hw/char/Kconfig | 3 +
96
hw/char/meson.build | 2 +-
97
hw/riscv/Kconfig | 5 +-
98
tests/tcg/riscv64/Makefile.target | 5 +
99
24 files changed, 1240 insertions(+), 1381 deletions(-)
100
create mode 100644 tests/tcg/riscv64/test-div.c
101
create mode 100644 tests/tcg/riscv64/Makefile.target
102
80
81
Lawrence Hunter (2):
82
target/riscv: Add Zvbc ISA extension support
83
target/riscv: Add Zvksh ISA extension support
84
85
Leon Schuermann (1):
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
87
88
Max Chou (3):
89
crypto: Create sm4_subword
90
crypto: Add SM4 constant parameter CK
91
target/riscv: Add Zvksed ISA extension support
92
93
Nazar Kazakov (4):
94
target/riscv: Remove redundant "cpu_vl == 0" checks
95
target/riscv: Move vector translation checks
96
target/riscv: Add Zvkned ISA extension support
97
target/riscv: Add Zvkg ISA extension support
98
99
Nikita Shubin (1):
100
target/riscv: don't read CSR in riscv_csrrw_do64
101
102
Rob Bradford (1):
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
104
105
Robbin Ehn (1):
106
linux-user/riscv: Add new extensions to hwprobe
107
108
Thomas Huth (2):
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
111
112
Tommy Wu (1):
113
target/riscv: Align the AIA model to v1.0 ratified spec
114
115
Vineet Gupta (1):
116
riscv: zicond: make non-experimental
117
118
Weiwei Li (1):
119
target/riscv: Update CSR bits name for svadu extension
120
121
Yong-Xuan Wang (5):
122
target/riscv: support the AIA device emulation with KVM enabled
123
target/riscv: check the in-kernel irqchip support
124
target/riscv: Create an KVM AIA irqchip
125
target/riscv: update APLIC and IMSIC to support KVM AIA
126
target/riscv: select KVM AIA in riscv virt machine
127
128
include/crypto/aes.h | 7 +
129
include/crypto/sm4.h | 9 +
130
target/riscv/cpu_bits.h | 8 +-
131
target/riscv/cpu_cfg.h | 9 +
132
target/riscv/debug.h | 3 +-
133
target/riscv/helper.h | 98 +++
134
target/riscv/kvm_riscv.h | 5 +
135
target/riscv/vector_internals.h | 228 +++++++
136
target/riscv/insn32.decode | 58 ++
137
crypto/aes.c | 4 +-
138
crypto/sm4.c | 10 +
139
hw/char/riscv_htif.c | 12 +-
140
hw/intc/riscv_aclint.c | 11 +-
141
hw/intc/riscv_aplic.c | 52 +-
142
hw/intc/riscv_imsic.c | 25 +-
143
hw/riscv/virt.c | 374 ++++++------
144
linux-user/riscv/signal.c | 4 +-
145
linux-user/syscall.c | 14 +-
146
target/arm/tcg/crypto_helper.c | 10 +-
147
target/riscv/cpu.c | 83 ++-
148
target/riscv/cpu_helper.c | 6 +-
149
target/riscv/crypto_helper.c | 51 +-
150
target/riscv/csr.c | 54 +-
151
target/riscv/debug.c | 15 +-
152
target/riscv/kvm.c | 201 ++++++-
153
target/riscv/pmp.c | 4 +
154
target/riscv/translate.c | 1 +
155
target/riscv/vcrypto_helper.c | 970 ++++++++++++++++++++++++++++++
156
target/riscv/vector_helper.c | 245 +-------
157
target/riscv/vector_internals.c | 81 +++
158
target/riscv/insn_trans/trans_rvv.c.inc | 171 +++---
159
target/riscv/insn_trans/trans_rvvk.c.inc | 606 +++++++++++++++++++
160
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 +-
161
target/riscv/meson.build | 4 +-
162
34 files changed, 2785 insertions(+), 652 deletions(-)
163
create mode 100644 target/riscv/vector_internals.h
164
create mode 100644 target/riscv/vcrypto_helper.c
165
create mode 100644 target/riscv/vector_internals.c
166
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
For some cpu, the isa version has already been set in cpu init function.
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
Thus only override the isa version when isa version is not set, or
4
available for all accels, but is a KVM only CPU. This means that in a
5
users set different isa version explicitly by cpu parameters.
5
RISC-V KVM capable host we can do things like this:
6
6
7
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
9
Message-id: 20210811144612.68674-1-zhiwei_liu@c-sky.com
9
10
This CPU does not have a priv spec because we don't filter its extensions
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
12
with the 'host' CPU.
13
14
We don't have a way to filter the 'host' CPU out of the available CPU
15
options (-cpu help) if the build includes both KVM and TCG. What we can
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
17
the 'host' CPU with accel=tcg:
18
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
27
---
12
target/riscv/cpu.c | 14 ++++++++------
28
target/riscv/cpu.c | 5 +++++
13
1 file changed, 8 insertions(+), 6 deletions(-)
29
1 file changed, 5 insertions(+)
14
30
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
20
RISCVCPU *cpu = RISCV_CPU(dev);
21
CPURISCVState *env = &cpu->env;
36
CPURISCVState *env = &cpu->env;
22
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
23
- int priv_version = PRIV_VERSION_1_11_0;
24
- int bext_version = BEXT_VERSION_0_93_0;
25
- int vext_version = VEXT_VERSION_0_07_1;
26
+ int priv_version = 0;
27
target_ulong target_misa = env->misa;
28
Error *local_err = NULL;
37
Error *local_err = NULL;
29
38
30
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
31
}
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
32
}
41
+ return;
33
34
- set_priv_version(env, priv_version);
35
- set_bext_version(env, bext_version);
36
- set_vext_version(env, vext_version);
37
+ if (priv_version) {
38
+ set_priv_version(env, priv_version);
39
+ } else if (!env->priv_ver) {
40
+ set_priv_version(env, PRIV_VERSION_1_11_0);
41
+ }
42
+ }
42
43
+
43
if (cpu->cfg.mmu) {
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
44
set_feature(env, RISCV_FEATURE_MMU);
45
if (local_err != NULL) {
45
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
46
error_propagate(errp, local_err);
46
target_misa |= RVH;
47
}
48
if (cpu->cfg.ext_b) {
49
+ int bext_version = BEXT_VERSION_0_93_0;
50
target_misa |= RVB;
51
52
if (cpu->cfg.bext_spec) {
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
54
set_bext_version(env, bext_version);
55
}
56
if (cpu->cfg.ext_v) {
57
+ int vext_version = VEXT_VERSION_0_07_1;
58
target_misa |= RVV;
59
if (!is_power_of_2(cpu->cfg.vlen)) {
60
error_setg(errp,
61
--
47
--
62
2.31.1
48
2.41.0
63
49
64
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
3
The character that should be printed is stored in the 64 bit "payload"
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
variable. The code currently tries to print it by taking the address
5
of the variable and passing this pointer to qemu_chr_fe_write(). However,
6
this only works on little endian hosts where the least significant bits
7
are stored on the lowest address. To do this in a portable way, we have
8
to store the value in an uint8_t variable instead.
9
10
Fixes: 5033606780 ("RISC-V HTIF Console")
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20210823195529.560295-20-richard.henderson@linaro.org
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-Id: <20230721094720.902454-2-thuth@redhat.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
18
---
9
target/riscv/insn_trans/trans_rva.c.inc | 47 ++++++++++---------------
19
hw/char/riscv_htif.c | 3 ++-
10
1 file changed, 19 insertions(+), 28 deletions(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
11
21
12
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/insn_trans/trans_rva.c.inc
24
--- a/hw/char/riscv_htif.c
15
+++ b/target/riscv/insn_trans/trans_rva.c.inc
25
+++ b/hw/char/riscv_htif.c
16
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
17
* this program. If not, see <http://www.gnu.org/licenses/>.
27
s->tohost = 0; /* clear to indicate we read */
18
*/
28
return;
19
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
20
-static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
30
- qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
21
+static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
31
+ uint8_t ch = (uint8_t)payload;
22
{
32
+ qemu_chr_fe_write(&s->chr, &ch, 1);
23
- TCGv src1 = tcg_temp_new();
33
resp = 0x100 | (uint8_t)payload;
24
- /* Put addr in load_res, data in load_val. */
34
} else {
25
- gen_get_gpr(ctx, src1, a->rs1);
35
qemu_log("HTIF device %d: unknown command\n", device);
26
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
27
+
28
if (a->rl) {
29
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
30
}
31
@@ -XXX,XX +XXX,XX @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
32
if (a->aq) {
33
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
34
}
35
+
36
+ /* Put addr in load_res, data in load_val. */
37
tcg_gen_mov_tl(load_res, src1);
38
gen_set_gpr(ctx, a->rd, load_val);
39
40
- tcg_temp_free(src1);
41
return true;
42
}
43
44
-static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
45
+static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
46
{
47
- TCGv src1 = tcg_temp_new();
48
- TCGv src2 = tcg_temp_new();
49
- TCGv dat = tcg_temp_new();
50
+ TCGv dest, src1, src2;
51
TCGLabel *l1 = gen_new_label();
52
TCGLabel *l2 = gen_new_label();
53
54
- gen_get_gpr(ctx, src1, a->rs1);
55
+ src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
56
tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
57
58
- gen_get_gpr(ctx, src2, a->rs2);
59
/*
60
* Note that the TCG atomic primitives are SC,
61
* so we can ignore AQ/RL along this path.
62
*/
63
- tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
64
+ dest = dest_gpr(ctx, a->rd);
65
+ src2 = get_gpr(ctx, a->rs2, EXT_NONE);
66
+ tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
67
ctx->mem_idx, mop);
68
- tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
69
- gen_set_gpr(ctx, a->rd, dat);
70
+ tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
71
+ gen_set_gpr(ctx, a->rd, dest);
72
tcg_gen_br(l2);
73
74
gen_set_label(l1);
75
@@ -XXX,XX +XXX,XX @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
76
* provide the memory barrier implied by AQ/RL.
77
*/
78
tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
79
- tcg_gen_movi_tl(dat, 1);
80
- gen_set_gpr(ctx, a->rd, dat);
81
+ gen_set_gpr(ctx, a->rd, tcg_constant_tl(1));
82
83
gen_set_label(l2);
84
/*
85
@@ -XXX,XX +XXX,XX @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
86
*/
87
tcg_gen_movi_tl(load_res, -1);
88
89
- tcg_temp_free(dat);
90
- tcg_temp_free(src1);
91
- tcg_temp_free(src2);
92
return true;
93
}
94
95
@@ -XXX,XX +XXX,XX @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
96
void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
97
MemOp mop)
98
{
99
- TCGv src1 = tcg_temp_new();
100
- TCGv src2 = tcg_temp_new();
101
-
102
- gen_get_gpr(ctx, src1, a->rs1);
103
- gen_get_gpr(ctx, src2, a->rs2);
104
+ TCGv dest = dest_gpr(ctx, a->rd);
105
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
106
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
107
108
- (*func)(src2, src1, src2, ctx->mem_idx, mop);
109
+ func(dest, src1, src2, ctx->mem_idx, mop);
110
111
- gen_set_gpr(ctx, a->rd, src2);
112
- tcg_temp_free(src1);
113
- tcg_temp_free(src2);
114
+ gen_set_gpr(ctx, a->rd, dest);
115
return true;
116
}
117
118
--
36
--
119
2.31.1
37
2.41.0
120
38
121
39
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
Values that have been read via cpu_physical_memory_read() from the
4
guest's memory have to be swapped in case the host endianess differs
5
from the guest.
6
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-Id: <20230721094720.902454-3-thuth@redhat.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
hw/char/riscv_htif.c | 9 +++++----
16
1 file changed, 5 insertions(+), 4 deletions(-)
17
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/char/riscv_htif.c
21
+++ b/hw/char/riscv_htif.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "qemu/timer.h"
24
#include "qemu/error-report.h"
25
#include "exec/address-spaces.h"
26
+#include "exec/tswap.h"
27
#include "sysemu/dma.h"
28
29
#define RISCV_DEBUG_HTIF 0
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
31
} else {
32
uint64_t syscall[8];
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- if (syscall[0] == PK_SYS_WRITE &&
35
- syscall[1] == HTIF_DEV_CONSOLE &&
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
40
uint8_t ch;
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
43
qemu_chr_fe_write(&s->chr, &ch, 1);
44
resp = 0x100 | (uint8_t)payload;
45
} else {
46
--
47
2.41.0
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
Add a riscv,isa string for it.
5
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.c | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
28
--
29
2.41.0
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
'smepmp' riscv,isa string. Add it.
5
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
27
--
28
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
4
integer return value to bool type. However, it wrongly converted the use
5
of the API in riscv fault-only-first, where page_check_range < = 0, should
6
be converted to !page_check_range.
7
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/vector_helper.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/vector_helper.c
19
+++ b/target/riscv/vector_helper.c
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
21
cpu_mmu_index(env, false));
22
if (host) {
23
#ifdef CONFIG_USER_ONLY
24
- if (page_check_range(addr, offset, PAGE_READ)) {
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
26
vl = i;
27
goto ProbeSuccess;
28
}
29
--
30
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Most arithmetic does not require extending the inputs.
3
The AES MixColumns and InvMixColumns operations are relatively
4
Exceptions include division, comparison and minmax.
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
implementations usually rely on precomputed lookup tables rather than
6
performing the calculations on demand.
5
7
6
Begin using ctx->w, which allows elimination of gen_addw,
8
Given that we already carry those tables in QEMU, we can just grab the
7
gen_subw, gen_mulw.
9
right value in the implementation of the RISC-V AES32 instructions. Note
10
that the tables in question are permuted according to the respective
11
Sbox, so we can omit the Sbox lookup as well in this case.
8
12
9
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
13
Cc: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Cc: Zewen Ye <lustrew@foxmail.com>
12
Message-id: 20210823195529.560295-7-richard.henderson@linaro.org
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
17
Cc: Junqiang Wang <wangjunqiang@iscas.ac.cn>
18
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-ID: <20230731084043.1791984-1-ardb@kernel.org>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
22
---
15
target/riscv/translate.c | 69 +++++++------------------
23
include/crypto/aes.h | 7 +++++++
16
target/riscv/insn_trans/trans_rvb.c.inc | 30 +++++------
24
crypto/aes.c | 4 ++--
17
target/riscv/insn_trans/trans_rvi.c.inc | 39 ++++++++------
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
18
target/riscv/insn_trans/trans_rvm.c.inc | 16 +++---
26
3 files changed, 13 insertions(+), 32 deletions(-)
19
4 files changed, 64 insertions(+), 90 deletions(-)
20
27
21
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
22
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/translate.c
30
--- a/include/crypto/aes.h
24
+++ b/target/riscv/translate.c
31
+++ b/include/crypto/aes.h
25
@@ -XXX,XX +XXX,XX @@ static void gen_get_gpr(DisasContext *ctx, TCGv t, int reg_num)
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
26
tcg_gen_mov_tl(t, get_gpr(ctx, reg_num, EXT_NONE));
33
extern const uint8_t AES_sbox[256];
27
}
34
extern const uint8_t AES_isbox[256];
28
35
29
-static TCGv __attribute__((unused)) dest_gpr(DisasContext *ctx, int reg_num)
36
+/*
30
+static TCGv dest_gpr(DisasContext *ctx, int reg_num)
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
31
{
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
32
if (reg_num == 0 || ctx->w) {
39
+*/
33
return temp_new(ctx);
40
+
34
@@ -XXX,XX +XXX,XX @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
35
/* Include the auto-generated decoder for 32 bit insn */
42
+
36
#include "decode-insn32.c.inc"
43
#endif
37
44
diff --git a/crypto/aes.c b/crypto/aes.c
38
-static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
45
index XXXXXXX..XXXXXXX 100644
39
+static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext,
46
--- a/crypto/aes.c
40
void (*func)(TCGv, TCGv, target_long))
47
+++ b/crypto/aes.c
41
{
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
42
- TCGv source1;
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
43
- source1 = tcg_temp_new();
50
*/
51
52
-static const uint32_t AES_Te0[256] = {
53
+const uint32_t AES_Te0[256] = {
54
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
55
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
56
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
57
@@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = {
58
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
59
};
60
61
-static const uint32_t AES_Td0[256] = {
62
+const uint32_t AES_Td0[256] = {
63
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
64
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
65
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
66
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/crypto_helper.c
69
+++ b/target/riscv/crypto_helper.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "crypto/aes-round.h"
72
#include "crypto/sm4.h"
73
74
-#define AES_XTIME(a) \
75
- ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
44
-
76
-
45
- gen_get_gpr(ctx, source1, a->rs1);
77
-#define AES_GFMUL(a, b) (( \
46
+ TCGv dest = dest_gpr(ctx, a->rd);
78
- (((b) & 0x1) ? (a) : 0) ^ \
47
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
48
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
49
- (*func)(source1, source1, a->imm);
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
50
+ func(dest, src1, a->imm);
51
52
- gen_set_gpr(ctx, a->rd, source1);
53
- tcg_temp_free(source1);
54
+ gen_set_gpr(ctx, a->rd, dest);
55
return true;
56
}
57
58
-static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
59
+static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
60
void (*func)(TCGv, TCGv, TCGv))
61
{
62
- TCGv source1, source2;
63
- source1 = tcg_temp_new();
64
- source2 = tcg_temp_new();
65
+ TCGv dest = dest_gpr(ctx, a->rd);
66
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
67
+ TCGv src2 = tcg_constant_tl(a->imm);
68
69
- gen_get_gpr(ctx, source1, a->rs1);
70
- tcg_gen_movi_tl(source2, a->imm);
71
+ func(dest, src1, src2);
72
73
- (*func)(source1, source1, source2);
74
-
82
-
75
- gen_set_gpr(ctx, a->rd, source1);
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
76
- tcg_temp_free(source1);
77
- tcg_temp_free(source2);
78
+ gen_set_gpr(ctx, a->rd, dest);
79
return true;
80
}
81
82
-static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2)
83
-{
84
-{
84
- tcg_gen_add_tl(ret, arg1, arg2);
85
- uint32_t u;
85
- tcg_gen_ext32s_tl(ret, ret);
86
-
87
- if (fwd) {
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
89
- (AES_GFMUL(x, 2) << 0);
90
- } else {
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
92
- (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
93
- }
94
- return u;
86
-}
95
-}
87
-
96
-
88
-static void gen_subw(TCGv ret, TCGv arg1, TCGv arg2)
97
#define sext32_xlen(x) (target_ulong)(int32_t)(x)
89
-{
98
90
- tcg_gen_sub_tl(ret, arg1, arg2);
99
static inline target_ulong aes32_operation(target_ulong shamt,
91
- tcg_gen_ext32s_tl(ret, ret);
100
@@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt,
92
-}
101
bool enc, bool mix)
93
-
94
-static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
95
-{
96
- tcg_gen_mul_tl(ret, arg1, arg2);
97
- tcg_gen_ext32s_tl(ret, ret);
98
-}
99
-
100
static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
101
void(*func)(TCGv, TCGv, TCGv))
102
{
102
{
103
@@ -XXX,XX +XXX,XX @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
103
uint8_t si = rs2 >> shamt;
104
tcg_gen_add_tl(ret, arg1, arg2);
104
- uint8_t so;
105
}
105
uint32_t mixed;
106
106
target_ulong res;
107
-static bool gen_arith(DisasContext *ctx, arg_r *a,
107
108
- void(*func)(TCGv, TCGv, TCGv))
108
if (enc) {
109
+static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
109
- so = AES_sbox[si];
110
+ void (*func)(TCGv, TCGv, TCGv))
110
if (mix) {
111
{
111
- mixed = aes_mixcolumn_byte(so, true);
112
- TCGv source1, source2;
112
+ mixed = be32_to_cpu(AES_Te0[si]);
113
- source1 = tcg_temp_new();
113
} else {
114
- source2 = tcg_temp_new();
114
- mixed = so;
115
+ TCGv dest = dest_gpr(ctx, a->rd);
115
+ mixed = AES_sbox[si];
116
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
116
}
117
+ TCGv src2 = get_gpr(ctx, a->rs2, ext);
117
} else {
118
118
- so = AES_isbox[si];
119
- gen_get_gpr(ctx, source1, a->rs1);
119
if (mix) {
120
- gen_get_gpr(ctx, source2, a->rs2);
120
- mixed = aes_mixcolumn_byte(so, false);
121
+ func(dest, src1, src2);
121
+ mixed = be32_to_cpu(AES_Td0[si]);
122
122
} else {
123
- (*func)(source1, source1, source2);
123
- mixed = so;
124
-
124
+ mixed = AES_isbox[si];
125
- gen_set_gpr(ctx, a->rd, source1);
125
}
126
- tcg_temp_free(source1);
126
}
127
- tcg_temp_free(source2);
127
mixed = rol32(mixed, shamt);
128
+ gen_set_gpr(ctx, a->rd, dest);
129
return true;
130
}
131
132
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/riscv/insn_trans/trans_rvb.c.inc
135
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
136
@@ -XXX,XX +XXX,XX @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
137
static bool trans_andn(DisasContext *ctx, arg_andn *a)
138
{
139
REQUIRE_EXT(ctx, RVB);
140
- return gen_arith(ctx, a, tcg_gen_andc_tl);
141
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_andc_tl);
142
}
143
144
static bool trans_orn(DisasContext *ctx, arg_orn *a)
145
{
146
REQUIRE_EXT(ctx, RVB);
147
- return gen_arith(ctx, a, tcg_gen_orc_tl);
148
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_orc_tl);
149
}
150
151
static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
152
{
153
REQUIRE_EXT(ctx, RVB);
154
- return gen_arith(ctx, a, tcg_gen_eqv_tl);
155
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl);
156
}
157
158
static bool trans_pack(DisasContext *ctx, arg_pack *a)
159
{
160
REQUIRE_EXT(ctx, RVB);
161
- return gen_arith(ctx, a, gen_pack);
162
+ return gen_arith(ctx, a, EXT_NONE, gen_pack);
163
}
164
165
static bool trans_packu(DisasContext *ctx, arg_packu *a)
166
{
167
REQUIRE_EXT(ctx, RVB);
168
- return gen_arith(ctx, a, gen_packu);
169
+ return gen_arith(ctx, a, EXT_NONE, gen_packu);
170
}
171
172
static bool trans_packh(DisasContext *ctx, arg_packh *a)
173
{
174
REQUIRE_EXT(ctx, RVB);
175
- return gen_arith(ctx, a, gen_packh);
176
+ return gen_arith(ctx, a, EXT_NONE, gen_packh);
177
}
178
179
static bool trans_min(DisasContext *ctx, arg_min *a)
180
{
181
REQUIRE_EXT(ctx, RVB);
182
- return gen_arith(ctx, a, tcg_gen_smin_tl);
183
+ return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl);
184
}
185
186
static bool trans_max(DisasContext *ctx, arg_max *a)
187
{
188
REQUIRE_EXT(ctx, RVB);
189
- return gen_arith(ctx, a, tcg_gen_smax_tl);
190
+ return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl);
191
}
192
193
static bool trans_minu(DisasContext *ctx, arg_minu *a)
194
{
195
REQUIRE_EXT(ctx, RVB);
196
- return gen_arith(ctx, a, tcg_gen_umin_tl);
197
+ return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl);
198
}
199
200
static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
201
{
202
REQUIRE_EXT(ctx, RVB);
203
- return gen_arith(ctx, a, tcg_gen_umax_tl);
204
+ return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl);
205
}
206
207
static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
208
@@ -XXX,XX +XXX,XX @@ static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
209
static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
210
{ \
211
REQUIRE_EXT(ctx, RVB); \
212
- return gen_arith(ctx, a, gen_sh##SHAMT##add); \
213
+ return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add); \
214
}
215
216
GEN_TRANS_SHADD(1)
217
@@ -XXX,XX +XXX,XX @@ static bool trans_packw(DisasContext *ctx, arg_packw *a)
218
{
219
REQUIRE_64BIT(ctx);
220
REQUIRE_EXT(ctx, RVB);
221
- return gen_arith(ctx, a, gen_packw);
222
+ return gen_arith(ctx, a, EXT_NONE, gen_packw);
223
}
224
225
static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
226
{
227
REQUIRE_64BIT(ctx);
228
REQUIRE_EXT(ctx, RVB);
229
- return gen_arith(ctx, a, gen_packuw);
230
+ return gen_arith(ctx, a, EXT_NONE, gen_packuw);
231
}
232
233
static bool trans_bsetw(DisasContext *ctx, arg_bsetw *a)
234
@@ -XXX,XX +XXX,XX @@ static bool trans_sh##SHAMT##add_uw(DisasContext *ctx, \
235
{ \
236
REQUIRE_64BIT(ctx); \
237
REQUIRE_EXT(ctx, RVB); \
238
- return gen_arith(ctx, a, gen_sh##SHAMT##add_uw); \
239
+ return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw); \
240
}
241
242
GEN_TRANS_SHADD_UW(1)
243
@@ -XXX,XX +XXX,XX @@ static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
244
{
245
REQUIRE_64BIT(ctx);
246
REQUIRE_EXT(ctx, RVB);
247
- return gen_arith(ctx, a, gen_add_uw);
248
+ return gen_arith(ctx, a, EXT_NONE, gen_add_uw);
249
}
250
251
static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
252
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/riscv/insn_trans/trans_rvi.c.inc
255
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
256
@@ -XXX,XX +XXX,XX @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
257
258
static bool trans_addi(DisasContext *ctx, arg_addi *a)
259
{
260
- return gen_arith_imm_fn(ctx, a, &tcg_gen_addi_tl);
261
+ return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl);
262
}
263
264
static void gen_slt(TCGv ret, TCGv s1, TCGv s2)
265
@@ -XXX,XX +XXX,XX @@ static void gen_sltu(TCGv ret, TCGv s1, TCGv s2)
266
tcg_gen_setcond_tl(TCG_COND_LTU, ret, s1, s2);
267
}
268
269
-
270
static bool trans_slti(DisasContext *ctx, arg_slti *a)
271
{
272
- return gen_arith_imm_tl(ctx, a, &gen_slt);
273
+ return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_slt);
274
}
275
276
static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
277
{
278
- return gen_arith_imm_tl(ctx, a, &gen_sltu);
279
+ return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_sltu);
280
}
281
282
static bool trans_xori(DisasContext *ctx, arg_xori *a)
283
{
284
- return gen_arith_imm_fn(ctx, a, &tcg_gen_xori_tl);
285
+ return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_xori_tl);
286
}
287
+
288
static bool trans_ori(DisasContext *ctx, arg_ori *a)
289
{
290
- return gen_arith_imm_fn(ctx, a, &tcg_gen_ori_tl);
291
+ return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_ori_tl);
292
}
293
+
294
static bool trans_andi(DisasContext *ctx, arg_andi *a)
295
{
296
- return gen_arith_imm_fn(ctx, a, &tcg_gen_andi_tl);
297
+ return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_andi_tl);
298
}
299
+
300
static bool trans_slli(DisasContext *ctx, arg_slli *a)
301
{
302
return gen_shifti(ctx, a, tcg_gen_shl_tl);
303
@@ -XXX,XX +XXX,XX @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
304
305
static bool trans_add(DisasContext *ctx, arg_add *a)
306
{
307
- return gen_arith(ctx, a, &tcg_gen_add_tl);
308
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl);
309
}
310
311
static bool trans_sub(DisasContext *ctx, arg_sub *a)
312
{
313
- return gen_arith(ctx, a, &tcg_gen_sub_tl);
314
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl);
315
}
316
317
static bool trans_sll(DisasContext *ctx, arg_sll *a)
318
@@ -XXX,XX +XXX,XX @@ static bool trans_sll(DisasContext *ctx, arg_sll *a)
319
320
static bool trans_slt(DisasContext *ctx, arg_slt *a)
321
{
322
- return gen_arith(ctx, a, &gen_slt);
323
+ return gen_arith(ctx, a, EXT_SIGN, gen_slt);
324
}
325
326
static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
327
{
328
- return gen_arith(ctx, a, &gen_sltu);
329
+ return gen_arith(ctx, a, EXT_SIGN, gen_sltu);
330
}
331
332
static bool trans_xor(DisasContext *ctx, arg_xor *a)
333
{
334
- return gen_arith(ctx, a, &tcg_gen_xor_tl);
335
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_xor_tl);
336
}
337
338
static bool trans_srl(DisasContext *ctx, arg_srl *a)
339
@@ -XXX,XX +XXX,XX @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
340
341
static bool trans_or(DisasContext *ctx, arg_or *a)
342
{
343
- return gen_arith(ctx, a, &tcg_gen_or_tl);
344
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_or_tl);
345
}
346
347
static bool trans_and(DisasContext *ctx, arg_and *a)
348
{
349
- return gen_arith(ctx, a, &tcg_gen_and_tl);
350
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_and_tl);
351
}
352
353
static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
354
{
355
REQUIRE_64BIT(ctx);
356
- return gen_arith_imm_tl(ctx, a, &gen_addw);
357
+ ctx->w = true;
358
+ return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl);
359
}
360
361
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
362
@@ -XXX,XX +XXX,XX @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
363
static bool trans_addw(DisasContext *ctx, arg_addw *a)
364
{
365
REQUIRE_64BIT(ctx);
366
- return gen_arith(ctx, a, &gen_addw);
367
+ ctx->w = true;
368
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl);
369
}
370
371
static bool trans_subw(DisasContext *ctx, arg_subw *a)
372
{
373
REQUIRE_64BIT(ctx);
374
- return gen_arith(ctx, a, &gen_subw);
375
+ ctx->w = true;
376
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl);
377
}
378
379
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
380
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
381
index XXXXXXX..XXXXXXX 100644
382
--- a/target/riscv/insn_trans/trans_rvm.c.inc
383
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
384
@@ -XXX,XX +XXX,XX @@
385
static bool trans_mul(DisasContext *ctx, arg_mul *a)
386
{
387
REQUIRE_EXT(ctx, RVM);
388
- return gen_arith(ctx, a, &tcg_gen_mul_tl);
389
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl);
390
}
391
392
static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
393
@@ -XXX,XX +XXX,XX @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
394
static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
395
{
396
REQUIRE_EXT(ctx, RVM);
397
- return gen_arith(ctx, a, &gen_mulhsu);
398
+ return gen_arith(ctx, a, EXT_NONE, gen_mulhsu);
399
}
400
401
static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
402
@@ -XXX,XX +XXX,XX @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
403
static bool trans_div(DisasContext *ctx, arg_div *a)
404
{
405
REQUIRE_EXT(ctx, RVM);
406
- return gen_arith(ctx, a, &gen_div);
407
+ return gen_arith(ctx, a, EXT_SIGN, gen_div);
408
}
409
410
static bool trans_divu(DisasContext *ctx, arg_divu *a)
411
{
412
REQUIRE_EXT(ctx, RVM);
413
- return gen_arith(ctx, a, &gen_divu);
414
+ return gen_arith(ctx, a, EXT_ZERO, gen_divu);
415
}
416
417
static bool trans_rem(DisasContext *ctx, arg_rem *a)
418
{
419
REQUIRE_EXT(ctx, RVM);
420
- return gen_arith(ctx, a, &gen_rem);
421
+ return gen_arith(ctx, a, EXT_SIGN, gen_rem);
422
}
423
424
static bool trans_remu(DisasContext *ctx, arg_remu *a)
425
{
426
REQUIRE_EXT(ctx, RVM);
427
- return gen_arith(ctx, a, &gen_remu);
428
+ return gen_arith(ctx, a, EXT_ZERO, gen_remu);
429
}
430
431
static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
432
{
433
REQUIRE_64BIT(ctx);
434
REQUIRE_EXT(ctx, RVM);
435
-
436
- return gen_arith(ctx, a, &gen_mulw);
437
+ ctx->w = true;
438
+ return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl);
439
}
440
441
static bool trans_divw(DisasContext *ctx, arg_divw *a)
442
--
128
--
443
2.31.1
129
2.41.0
444
130
445
131
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
These operations can be done in one instruction on some hosts.
3
Take some functions/macros out of `vector_helper` and put them in a new
4
module called `vector_internals`. This ensures they can be used by both
5
vector and vector-crypto helpers (latter implemented in proceeding
6
commits).
4
7
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-id: 20210823195529.560295-14-richard.henderson@linaro.org
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
14
---
11
target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++++++++--
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
12
1 file changed, 12 insertions(+), 2 deletions(-)
16
target/riscv/vector_helper.c | 201 +-------------------------------
17
target/riscv/vector_internals.c | 81 +++++++++++++
18
target/riscv/meson.build | 1 +
19
4 files changed, 265 insertions(+), 200 deletions(-)
20
create mode 100644 target/riscv/vector_internals.h
21
create mode 100644 target/riscv/vector_internals.c
13
22
14
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/target/riscv/vector_internals.h
28
@@ -XXX,XX +XXX,XX @@
29
+/*
30
+ * RISC-V Vector Extension Internals
31
+ *
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
33
+ *
34
+ * This program is free software; you can redistribute it and/or modify it
35
+ * under the terms and conditions of the GNU General Public License,
36
+ * version 2 or later, as published by the Free Software Foundation.
37
+ *
38
+ * This program is distributed in the hope it will be useful, but WITHOUT
39
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
41
+ * more details.
42
+ *
43
+ * You should have received a copy of the GNU General Public License along with
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
45
+ */
46
+
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
49
+
50
+#include "qemu/osdep.h"
51
+#include "qemu/bitops.h"
52
+#include "cpu.h"
53
+#include "tcg/tcg-gvec-desc.h"
54
+#include "internals.h"
55
+
56
+static inline uint32_t vext_nf(uint32_t desc)
57
+{
58
+ return FIELD_EX32(simd_data(desc), VDATA, NF);
59
+}
60
+
61
+/*
62
+ * Note that vector data is stored in host-endian 64-bit chunks,
63
+ * so addressing units smaller than that needs a host-endian fixup.
64
+ */
65
+#if HOST_BIG_ENDIAN
66
+#define H1(x) ((x) ^ 7)
67
+#define H1_2(x) ((x) ^ 6)
68
+#define H1_4(x) ((x) ^ 4)
69
+#define H2(x) ((x) ^ 3)
70
+#define H4(x) ((x) ^ 1)
71
+#define H8(x) ((x))
72
+#else
73
+#define H1(x) (x)
74
+#define H1_2(x) (x)
75
+#define H1_4(x) (x)
76
+#define H2(x) (x)
77
+#define H4(x) (x)
78
+#define H8(x) (x)
79
+#endif
80
+
81
+/*
82
+ * Encode LMUL to lmul as following:
83
+ * LMUL vlmul lmul
84
+ * 1 000 0
85
+ * 2 001 1
86
+ * 4 010 2
87
+ * 8 011 3
88
+ * - 100 -
89
+ * 1/8 101 -3
90
+ * 1/4 110 -2
91
+ * 1/2 111 -1
92
+ */
93
+static inline int32_t vext_lmul(uint32_t desc)
94
+{
95
+ return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
96
+}
97
+
98
+static inline uint32_t vext_vm(uint32_t desc)
99
+{
100
+ return FIELD_EX32(simd_data(desc), VDATA, VM);
101
+}
102
+
103
+static inline uint32_t vext_vma(uint32_t desc)
104
+{
105
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
106
+}
107
+
108
+static inline uint32_t vext_vta(uint32_t desc)
109
+{
110
+ return FIELD_EX32(simd_data(desc), VDATA, VTA);
111
+}
112
+
113
+static inline uint32_t vext_vta_all_1s(uint32_t desc)
114
+{
115
+ return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
116
+}
117
+
118
+/*
119
+ * Earlier designs (pre-0.9) had a varying number of bits
120
+ * per mask value (MLEN). In the 0.9 design, MLEN=1.
121
+ * (Section 4.5)
122
+ */
123
+static inline int vext_elem_mask(void *v0, int index)
124
+{
125
+ int idx = index / 64;
126
+ int pos = index % 64;
127
+ return (((uint64_t *)v0)[idx] >> pos) & 1;
128
+}
129
+
130
+/*
131
+ * Get number of total elements, including prestart, body and tail elements.
132
+ * Note that when LMUL < 1, the tail includes the elements past VLMAX that
133
+ * are held in the same vector register.
134
+ */
135
+static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
136
+ uint32_t esz)
137
+{
138
+ uint32_t vlenb = simd_maxsz(desc);
139
+ uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
140
+ int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
141
+ ctzl(esz) - ctzl(sew) + vext_lmul(desc);
142
+ return (vlenb << emul) / esz;
143
+}
144
+
145
+/* set agnostic elements to 1s */
146
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
147
+ uint32_t tot);
148
+
149
+/* expand macro args before macro */
150
+#define RVVCALL(macro, ...) macro(__VA_ARGS__)
151
+
152
+/* (TD, T1, T2, TX1, TX2) */
153
+#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
154
+#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
155
+#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
156
+#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
157
+
158
+/* operation of two vector elements */
159
+typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
160
+
161
+#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
162
+static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
163
+{ \
164
+ TX1 s1 = *((T1 *)vs1 + HS1(i)); \
165
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
166
+ *((TD *)vd + HD(i)) = OP(s2, s1); \
167
+}
168
+
169
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
170
+ CPURISCVState *env, uint32_t desc,
171
+ opivv2_fn *fn, uint32_t esz);
172
+
173
+/* generate the helpers for OPIVV */
174
+#define GEN_VEXT_VV(NAME, ESZ) \
175
+void HELPER(NAME)(void *vd, void *v0, void *vs1, \
176
+ void *vs2, CPURISCVState *env, \
177
+ uint32_t desc) \
178
+{ \
179
+ do_vext_vv(vd, v0, vs1, vs2, env, desc, \
180
+ do_##NAME, ESZ); \
181
+}
182
+
183
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
184
+
185
+/*
186
+ * (T1)s1 gives the real operator type.
187
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
188
+ */
189
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
190
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
191
+{ \
192
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
193
+ *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
194
+}
195
+
196
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
197
+ CPURISCVState *env, uint32_t desc,
198
+ opivx2_fn fn, uint32_t esz);
199
+
200
+/* generate the helpers for OPIVX */
201
+#define GEN_VEXT_VX(NAME, ESZ) \
202
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
203
+ void *vs2, CPURISCVState *env, \
204
+ uint32_t desc) \
205
+{ \
206
+ do_vext_vx(vd, v0, s1, vs2, env, desc, \
207
+ do_##NAME, ESZ); \
208
+}
209
+
210
+#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
211
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvi.c.inc
213
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
214
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
215
@@ -XXX,XX +XXX,XX @@
19
return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
216
#include "fpu/softfloat.h"
217
#include "tcg/tcg-gvec-desc.h"
218
#include "internals.h"
219
+#include "vector_internals.h"
220
#include <math.h>
221
222
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
223
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
224
return vl;
20
}
225
}
21
226
22
+static void gen_srliw(TCGv dst, TCGv src, target_long shamt)
227
-/*
23
+{
228
- * Note that vector data is stored in host-endian 64-bit chunks,
24
+ tcg_gen_extract_tl(dst, src, shamt, 32 - shamt);
229
- * so addressing units smaller than that needs a host-endian fixup.
25
+}
230
- */
26
+
231
-#if HOST_BIG_ENDIAN
27
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
232
-#define H1(x) ((x) ^ 7)
233
-#define H1_2(x) ((x) ^ 6)
234
-#define H1_4(x) ((x) ^ 4)
235
-#define H2(x) ((x) ^ 3)
236
-#define H4(x) ((x) ^ 1)
237
-#define H8(x) ((x))
238
-#else
239
-#define H1(x) (x)
240
-#define H1_2(x) (x)
241
-#define H1_4(x) (x)
242
-#define H2(x) (x)
243
-#define H4(x) (x)
244
-#define H8(x) (x)
245
-#endif
246
-
247
-static inline uint32_t vext_nf(uint32_t desc)
248
-{
249
- return FIELD_EX32(simd_data(desc), VDATA, NF);
250
-}
251
-
252
-static inline uint32_t vext_vm(uint32_t desc)
253
-{
254
- return FIELD_EX32(simd_data(desc), VDATA, VM);
255
-}
256
-
257
-/*
258
- * Encode LMUL to lmul as following:
259
- * LMUL vlmul lmul
260
- * 1 000 0
261
- * 2 001 1
262
- * 4 010 2
263
- * 8 011 3
264
- * - 100 -
265
- * 1/8 101 -3
266
- * 1/4 110 -2
267
- * 1/2 111 -1
268
- */
269
-static inline int32_t vext_lmul(uint32_t desc)
270
-{
271
- return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
272
-}
273
-
274
-static inline uint32_t vext_vta(uint32_t desc)
275
-{
276
- return FIELD_EX32(simd_data(desc), VDATA, VTA);
277
-}
278
-
279
-static inline uint32_t vext_vma(uint32_t desc)
280
-{
281
- return FIELD_EX32(simd_data(desc), VDATA, VMA);
282
-}
283
-
284
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
285
-{
286
- return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
287
-}
288
-
289
/*
290
* Get the maximum number of elements can be operated.
291
*
292
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
293
return scale < 0 ? vlenb >> -scale : vlenb << scale;
294
}
295
296
-/*
297
- * Get number of total elements, including prestart, body and tail elements.
298
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
299
- * are held in the same vector register.
300
- */
301
-static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
302
- uint32_t esz)
303
-{
304
- uint32_t vlenb = simd_maxsz(desc);
305
- uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
306
- int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
307
- ctzl(esz) - ctzl(sew) + vext_lmul(desc);
308
- return (vlenb << emul) / esz;
309
-}
310
-
311
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
28
{
312
{
29
REQUIRE_64BIT(ctx);
313
return (addr & ~env->cur_pmmask) | env->cur_pmbase;
30
ctx->w = true;
314
@@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
31
- return gen_shift_imm_fn(ctx, a, EXT_ZERO, tcg_gen_shri_tl);
315
}
32
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw);
33
+}
34
+
35
+static void gen_sraiw(TCGv dst, TCGv src, target_long shamt)
36
+{
37
+ tcg_gen_sextract_tl(dst, src, shamt, 32 - shamt);
38
}
316
}
39
317
40
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
318
-/* set agnostic elements to 1s */
319
-static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
320
- uint32_t tot)
321
-{
322
- if (is_agnostic == 0) {
323
- /* policy undisturbed */
324
- return;
325
- }
326
- if (tot - cnt == 0) {
327
- return;
328
- }
329
- memset(base + cnt, -1, tot - cnt);
330
-}
331
-
332
static inline void vext_set_elem_mask(void *v0, int index,
333
uint8_t value)
41
{
334
{
42
REQUIRE_64BIT(ctx);
335
@@ -XXX,XX +XXX,XX @@ static inline void vext_set_elem_mask(void *v0, int index,
43
ctx->w = true;
336
((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
44
- return gen_shift_imm_fn(ctx, a, EXT_SIGN, tcg_gen_sari_tl);
45
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw);
46
}
337
}
47
338
48
static bool trans_addw(DisasContext *ctx, arg_addw *a)
339
-/*
340
- * Earlier designs (pre-0.9) had a varying number of bits
341
- * per mask value (MLEN). In the 0.9 design, MLEN=1.
342
- * (Section 4.5)
343
- */
344
-static inline int vext_elem_mask(void *v0, int index)
345
-{
346
- int idx = index / 64;
347
- int pos = index % 64;
348
- return (((uint64_t *)v0)[idx] >> pos) & 1;
349
-}
350
-
351
/* elements operations for load and store */
352
typedef void vext_ldst_elem_fn(CPURISCVState *env, abi_ptr addr,
353
uint32_t idx, void *vd, uintptr_t retaddr);
354
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
355
* Vector Integer Arithmetic Instructions
356
*/
357
358
-/* expand macro args before macro */
359
-#define RVVCALL(macro, ...) macro(__VA_ARGS__)
360
-
361
/* (TD, T1, T2, TX1, TX2) */
362
#define OP_SSS_B int8_t, int8_t, int8_t, int8_t, int8_t
363
#define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t
364
#define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t
365
#define OP_SSS_D int64_t, int64_t, int64_t, int64_t, int64_t
366
-#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
367
-#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
368
-#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
369
-#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
370
#define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t
371
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
372
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
373
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
374
#define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t
375
#define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t
376
377
-/* operation of two vector elements */
378
-typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
379
-
380
-#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
381
-static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
382
-{ \
383
- TX1 s1 = *((T1 *)vs1 + HS1(i)); \
384
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
385
- *((TD *)vd + HD(i)) = OP(s2, s1); \
386
-}
387
#define DO_SUB(N, M) (N - M)
388
#define DO_RSUB(N, M) (M - N)
389
390
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vsub_vv_h, OP_SSS_H, H2, H2, H2, DO_SUB)
391
RVVCALL(OPIVV2, vsub_vv_w, OP_SSS_W, H4, H4, H4, DO_SUB)
392
RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB)
393
394
-static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
395
- CPURISCVState *env, uint32_t desc,
396
- opivv2_fn *fn, uint32_t esz)
397
-{
398
- uint32_t vm = vext_vm(desc);
399
- uint32_t vl = env->vl;
400
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
401
- uint32_t vta = vext_vta(desc);
402
- uint32_t vma = vext_vma(desc);
403
- uint32_t i;
404
-
405
- for (i = env->vstart; i < vl; i++) {
406
- if (!vm && !vext_elem_mask(v0, i)) {
407
- /* set masked-off elements to 1s */
408
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
409
- continue;
410
- }
411
- fn(vd, vs1, vs2, i);
412
- }
413
- env->vstart = 0;
414
- /* set tail elements to 1s */
415
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
416
-}
417
-
418
-/* generate the helpers for OPIVV */
419
-#define GEN_VEXT_VV(NAME, ESZ) \
420
-void HELPER(NAME)(void *vd, void *v0, void *vs1, \
421
- void *vs2, CPURISCVState *env, \
422
- uint32_t desc) \
423
-{ \
424
- do_vext_vv(vd, v0, vs1, vs2, env, desc, \
425
- do_##NAME, ESZ); \
426
-}
427
-
428
GEN_VEXT_VV(vadd_vv_b, 1)
429
GEN_VEXT_VV(vadd_vv_h, 2)
430
GEN_VEXT_VV(vadd_vv_w, 4)
431
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VV(vsub_vv_h, 2)
432
GEN_VEXT_VV(vsub_vv_w, 4)
433
GEN_VEXT_VV(vsub_vv_d, 8)
434
435
-typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
436
-
437
-/*
438
- * (T1)s1 gives the real operator type.
439
- * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
440
- */
441
-#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
442
-static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
443
-{ \
444
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
445
- *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
446
-}
447
448
RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD)
449
RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD)
450
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB)
451
RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB)
452
RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
453
454
-static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
455
- CPURISCVState *env, uint32_t desc,
456
- opivx2_fn fn, uint32_t esz)
457
-{
458
- uint32_t vm = vext_vm(desc);
459
- uint32_t vl = env->vl;
460
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
461
- uint32_t vta = vext_vta(desc);
462
- uint32_t vma = vext_vma(desc);
463
- uint32_t i;
464
-
465
- for (i = env->vstart; i < vl; i++) {
466
- if (!vm && !vext_elem_mask(v0, i)) {
467
- /* set masked-off elements to 1s */
468
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
469
- continue;
470
- }
471
- fn(vd, s1, vs2, i);
472
- }
473
- env->vstart = 0;
474
- /* set tail elements to 1s */
475
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
476
-}
477
-
478
-/* generate the helpers for OPIVX */
479
-#define GEN_VEXT_VX(NAME, ESZ) \
480
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
481
- void *vs2, CPURISCVState *env, \
482
- uint32_t desc) \
483
-{ \
484
- do_vext_vx(vd, v0, s1, vs2, env, desc, \
485
- do_##NAME, ESZ); \
486
-}
487
-
488
GEN_VEXT_VX(vadd_vx_b, 1)
489
GEN_VEXT_VX(vadd_vx_h, 2)
490
GEN_VEXT_VX(vadd_vx_w, 4)
491
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
492
new file mode 100644
493
index XXXXXXX..XXXXXXX
494
--- /dev/null
495
+++ b/target/riscv/vector_internals.c
496
@@ -XXX,XX +XXX,XX @@
497
+/*
498
+ * RISC-V Vector Extension Internals
499
+ *
500
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
501
+ *
502
+ * This program is free software; you can redistribute it and/or modify it
503
+ * under the terms and conditions of the GNU General Public License,
504
+ * version 2 or later, as published by the Free Software Foundation.
505
+ *
506
+ * This program is distributed in the hope it will be useful, but WITHOUT
507
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
508
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
509
+ * more details.
510
+ *
511
+ * You should have received a copy of the GNU General Public License along with
512
+ * this program. If not, see <http://www.gnu.org/licenses/>.
513
+ */
514
+
515
+#include "vector_internals.h"
516
+
517
+/* set agnostic elements to 1s */
518
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
519
+ uint32_t tot)
520
+{
521
+ if (is_agnostic == 0) {
522
+ /* policy undisturbed */
523
+ return;
524
+ }
525
+ if (tot - cnt == 0) {
526
+ return ;
527
+ }
528
+ memset(base + cnt, -1, tot - cnt);
529
+}
530
+
531
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
532
+ CPURISCVState *env, uint32_t desc,
533
+ opivv2_fn *fn, uint32_t esz)
534
+{
535
+ uint32_t vm = vext_vm(desc);
536
+ uint32_t vl = env->vl;
537
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
538
+ uint32_t vta = vext_vta(desc);
539
+ uint32_t vma = vext_vma(desc);
540
+ uint32_t i;
541
+
542
+ for (i = env->vstart; i < vl; i++) {
543
+ if (!vm && !vext_elem_mask(v0, i)) {
544
+ /* set masked-off elements to 1s */
545
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
546
+ continue;
547
+ }
548
+ fn(vd, vs1, vs2, i);
549
+ }
550
+ env->vstart = 0;
551
+ /* set tail elements to 1s */
552
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
553
+}
554
+
555
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
556
+ CPURISCVState *env, uint32_t desc,
557
+ opivx2_fn fn, uint32_t esz)
558
+{
559
+ uint32_t vm = vext_vm(desc);
560
+ uint32_t vl = env->vl;
561
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
562
+ uint32_t vta = vext_vta(desc);
563
+ uint32_t vma = vext_vma(desc);
564
+ uint32_t i;
565
+
566
+ for (i = env->vstart; i < vl; i++) {
567
+ if (!vm && !vext_elem_mask(v0, i)) {
568
+ /* set masked-off elements to 1s */
569
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
570
+ continue;
571
+ }
572
+ fn(vd, s1, vs2, i);
573
+ }
574
+ env->vstart = 0;
575
+ /* set tail elements to 1s */
576
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
577
+}
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
579
index XXXXXXX..XXXXXXX 100644
580
--- a/target/riscv/meson.build
581
+++ b/target/riscv/meson.build
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
583
'gdbstub.c',
584
'op_helper.c',
585
'vector_helper.c',
586
+ 'vector_internals.c',
587
'bitmanip_helper.c',
588
'translate.c',
589
'm128_helper.c',
49
--
590
--
50
2.31.1
591
2.41.0
51
52
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Remove gen_get_gpr, as the function becomes unused.
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
used in proceeding vector-crypto commits.
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20210823195529.560295-25-richard.henderson@linaro.org
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
14
---
10
target/riscv/translate.c | 13 ++---
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
11
target/riscv/insn_trans/trans_rvv.c.inc | 74 +++++++------------------
16
1 file changed, 32 insertions(+), 30 deletions(-)
12
2 files changed, 26 insertions(+), 61 deletions(-)
13
17
14
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/translate.c
17
+++ b/target/riscv/translate.c
18
@@ -XXX,XX +XXX,XX @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
19
g_assert_not_reached();
20
}
21
22
-static void gen_get_gpr(DisasContext *ctx, TCGv t, int reg_num)
23
-{
24
- tcg_gen_mov_tl(t, get_gpr(ctx, reg_num, EXT_NONE));
25
-}
26
-
27
static TCGv dest_gpr(DisasContext *ctx, int reg_num)
28
{
29
if (reg_num == 0 || ctx->w) {
30
@@ -XXX,XX +XXX,XX @@ void riscv_translate_init(void)
31
{
32
int i;
33
34
- /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
35
- /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
36
- /* registers, unless you specifically block reads/writes to reg 0 */
37
+ /*
38
+ * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
39
+ * Use the gen_set_gpr and get_gpr helper functions when accessing regs,
40
+ * unless you specifically block reads/writes to reg 0.
41
+ */
42
cpu_gpr[0] = NULL;
43
44
for (i = 1; i < 32; i++) {
45
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
46
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
47
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
48
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
49
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
50
return false;
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
51
}
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
52
25
53
- s2 = tcg_temp_new();
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
54
- dst = tcg_temp_new();
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
55
+ s2 = get_gpr(ctx, a->rs2, EXT_ZERO);
28
+{
56
+ dst = dest_gpr(ctx, a->rd);
29
+ uint32_t data = 0;
57
30
+ TCGLabel *over = gen_new_label();
58
/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
31
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
59
if (a->rs1 == 0) {
32
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
60
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
61
s1 = tcg_constant_tl(RV_VLEN_MAX);
62
} else {
63
- s1 = tcg_temp_new();
64
- gen_get_gpr(ctx, s1, a->rs1);
65
+ s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
66
}
67
- gen_get_gpr(ctx, s2, a->rs2);
68
gen_helper_vsetvl(dst, cpu_env, s1, s2);
69
gen_set_gpr(ctx, a->rd, dst);
70
+
33
+
71
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
34
+ data = FIELD_DP32(data, VDATA, VM, vm);
72
lookup_and_goto_ptr(ctx);
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
73
ctx->base.is_jmp = DISAS_NORETURN;
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
74
-
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
75
- tcg_temp_free(s1);
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
76
- tcg_temp_free(s2);
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
77
- tcg_temp_free(dst);
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
78
return true;
41
+ s->cfg_ptr->vlen / 8, data, fn);
42
+ mark_vs_dirty(s);
43
+ gen_set_label(over);
44
+ return true;
45
+}
46
+
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
48
/* OPIVV without GVEC IR */
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
51
-{ \
52
- if (CHECK(s, a)) { \
53
- uint32_t data = 0; \
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
57
- }; \
58
- TCGLabel *over = gen_new_label(); \
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
61
- \
62
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
63
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
64
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
65
- data = \
66
- FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
67
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
68
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
69
- vreg_ofs(s, a->rs1), \
70
- vreg_ofs(s, a->rs2), cpu_env, \
71
- s->cfg_ptr->vlen / 8, \
72
- s->cfg_ptr->vlen / 8, data, \
73
- fns[s->sew]); \
74
- mark_vs_dirty(s); \
75
- gen_set_label(over); \
76
- return true; \
77
- } \
78
- return false; \
79
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
80
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
81
+{ \
82
+ if (CHECK(s, a)) { \
83
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
84
+ gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
85
+ gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
86
+ }; \
87
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
88
+ } \
89
+ return false; \
79
}
90
}
80
91
81
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
92
/*
82
}
83
84
s2 = tcg_constant_tl(a->zimm);
85
- dst = tcg_temp_new();
86
+ dst = dest_gpr(ctx, a->rd);
87
88
/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
89
if (a->rs1 == 0) {
90
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
91
s1 = tcg_constant_tl(RV_VLEN_MAX);
92
} else {
93
- s1 = tcg_temp_new();
94
- gen_get_gpr(ctx, s1, a->rs1);
95
+ s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
96
}
97
gen_helper_vsetvl(dst, cpu_env, s1, s2);
98
gen_set_gpr(ctx, a->rd, dst);
99
+
100
gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
101
ctx->base.is_jmp = DISAS_NORETURN;
102
-
103
- tcg_temp_free(s1);
104
- tcg_temp_free(dst);
105
return true;
106
}
107
108
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
109
110
dest = tcg_temp_new_ptr();
111
mask = tcg_temp_new_ptr();
112
- base = tcg_temp_new();
113
+ base = get_gpr(s, rs1, EXT_NONE);
114
115
/*
116
* As simd_desc supports at most 256 bytes, and in this implementation,
117
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
118
*/
119
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
120
121
- gen_get_gpr(s, base, rs1);
122
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
123
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
124
125
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
126
127
tcg_temp_free_ptr(dest);
128
tcg_temp_free_ptr(mask);
129
- tcg_temp_free(base);
130
gen_set_label(over);
131
return true;
132
}
133
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
134
135
dest = tcg_temp_new_ptr();
136
mask = tcg_temp_new_ptr();
137
- base = tcg_temp_new();
138
- stride = tcg_temp_new();
139
+ base = get_gpr(s, rs1, EXT_NONE);
140
+ stride = get_gpr(s, rs2, EXT_NONE);
141
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
142
143
- gen_get_gpr(s, base, rs1);
144
- gen_get_gpr(s, stride, rs2);
145
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
146
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
147
148
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
149
150
tcg_temp_free_ptr(dest);
151
tcg_temp_free_ptr(mask);
152
- tcg_temp_free(base);
153
- tcg_temp_free(stride);
154
gen_set_label(over);
155
return true;
156
}
157
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
158
dest = tcg_temp_new_ptr();
159
mask = tcg_temp_new_ptr();
160
index = tcg_temp_new_ptr();
161
- base = tcg_temp_new();
162
+ base = get_gpr(s, rs1, EXT_NONE);
163
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
164
165
- gen_get_gpr(s, base, rs1);
166
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
167
tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
168
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
169
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
170
tcg_temp_free_ptr(dest);
171
tcg_temp_free_ptr(mask);
172
tcg_temp_free_ptr(index);
173
- tcg_temp_free(base);
174
gen_set_label(over);
175
return true;
176
}
177
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
178
179
dest = tcg_temp_new_ptr();
180
mask = tcg_temp_new_ptr();
181
- base = tcg_temp_new();
182
+ base = get_gpr(s, rs1, EXT_NONE);
183
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
184
185
- gen_get_gpr(s, base, rs1);
186
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
187
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
188
189
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
190
191
tcg_temp_free_ptr(dest);
192
tcg_temp_free_ptr(mask);
193
- tcg_temp_free(base);
194
gen_set_label(over);
195
return true;
196
}
197
@@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
198
dest = tcg_temp_new_ptr();
199
mask = tcg_temp_new_ptr();
200
index = tcg_temp_new_ptr();
201
- base = tcg_temp_new();
202
+ base = get_gpr(s, rs1, EXT_NONE);
203
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
204
205
- gen_get_gpr(s, base, rs1);
206
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
207
tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
208
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
209
@@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
210
tcg_temp_free_ptr(dest);
211
tcg_temp_free_ptr(mask);
212
tcg_temp_free_ptr(index);
213
- tcg_temp_free(base);
214
gen_set_label(over);
215
return true;
216
}
217
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
218
dest = tcg_temp_new_ptr();
219
mask = tcg_temp_new_ptr();
220
src2 = tcg_temp_new_ptr();
221
- src1 = tcg_temp_new();
222
- gen_get_gpr(s, src1, rs1);
223
+ src1 = get_gpr(s, rs1, EXT_NONE);
224
225
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
226
data = FIELD_DP32(data, VDATA, VM, vm);
227
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
228
tcg_temp_free_ptr(dest);
229
tcg_temp_free_ptr(mask);
230
tcg_temp_free_ptr(src2);
231
- tcg_temp_free(src1);
232
gen_set_label(over);
233
return true;
234
}
235
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
236
237
if (a->vm && s->vl_eq_vlmax) {
238
TCGv_i64 src1 = tcg_temp_new_i64();
239
- TCGv tmp = tcg_temp_new();
240
241
- gen_get_gpr(s, tmp, a->rs1);
242
- tcg_gen_ext_tl_i64(src1, tmp);
243
+ tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN));
244
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
245
src1, MAXSZ(s), MAXSZ(s));
246
247
tcg_temp_free_i64(src1);
248
- tcg_temp_free(tmp);
249
return true;
250
}
251
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
252
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
253
254
if (a->vm && s->vl_eq_vlmax) {
255
TCGv_i32 src1 = tcg_temp_new_i32();
256
- TCGv tmp = tcg_temp_new();
257
258
- gen_get_gpr(s, tmp, a->rs1);
259
- tcg_gen_trunc_tl_i32(src1, tmp);
260
+ tcg_gen_trunc_tl_i32(src1, get_gpr(s, a->rs1, EXT_NONE));
261
tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
262
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
263
src1, MAXSZ(s), MAXSZ(s));
264
265
tcg_temp_free_i32(src1);
266
- tcg_temp_free(tmp);
267
return true;
268
}
269
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
270
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
271
TCGLabel *over = gen_new_label();
272
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
273
274
- s1 = tcg_temp_new();
275
- gen_get_gpr(s, s1, a->rs1);
276
+ s1 = get_gpr(s, a->rs1, EXT_SIGN);
277
278
if (s->vl_eq_vlmax) {
279
tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
280
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
281
tcg_temp_free_i64(s1_i64);
282
}
283
284
- tcg_temp_free(s1);
285
gen_set_label(over);
286
return true;
287
}
288
@@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
289
290
mask = tcg_temp_new_ptr();
291
src2 = tcg_temp_new_ptr();
292
- dst = tcg_temp_new();
293
+ dst = dest_gpr(s, a->rd);
294
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
295
296
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
297
@@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
298
299
tcg_temp_free_ptr(mask);
300
tcg_temp_free_ptr(src2);
301
- tcg_temp_free(dst);
302
return true;
303
}
304
return false;
305
@@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
306
307
mask = tcg_temp_new_ptr();
308
src2 = tcg_temp_new_ptr();
309
- dst = tcg_temp_new();
310
+ dst = dest_gpr(s, a->rd);
311
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
312
313
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
314
@@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
315
316
tcg_temp_free_ptr(mask);
317
tcg_temp_free_ptr(src2);
318
- tcg_temp_free(dst);
319
return true;
320
}
321
return false;
322
@@ -XXX,XX +XXX,XX @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
323
static bool trans_vext_x_v(DisasContext *s, arg_r *a)
324
{
325
TCGv_i64 tmp = tcg_temp_new_i64();
326
- TCGv dest = tcg_temp_new();
327
+ TCGv dest = dest_gpr(s, a->rd);
328
329
if (a->rs1 == 0) {
330
/* Special case vmv.x.s rd, vs2. */
331
@@ -XXX,XX +XXX,XX @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
332
int vlmax = s->vlen >> (3 + s->sew);
333
vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
334
}
335
+
336
tcg_gen_trunc_i64_tl(dest, tmp);
337
gen_set_gpr(s, a->rd, dest);
338
339
- tcg_temp_free(dest);
340
tcg_temp_free_i64(tmp);
341
return true;
342
}
343
--
93
--
344
2.31.1
94
2.41.0
345
346
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Replace uses of tcg_const_* with the allocate and free close together.
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
4
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210823195529.560295-2-richard.henderson@linaro.org
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/translate.c | 36 ++++----------
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
13
target/riscv/insn_trans/trans_rvf.c.inc | 3 +-
13
1 file changed, 1 insertion(+), 30 deletions(-)
14
target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
15
3 files changed, 34 insertions(+), 70 deletions(-)
16
14
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/translate.c
20
+++ b/target/riscv/translate.c
21
@@ -XXX,XX +XXX,XX @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
22
*/
23
static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
24
{
25
- TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
26
- TCGv_i64 t_nan = tcg_const_i64(0xffffffff7fc00000ull);
27
+ TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
28
+ TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
29
30
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
31
- tcg_temp_free_i64(t_max);
32
- tcg_temp_free_i64(t_nan);
33
}
34
35
static void generate_exception(DisasContext *ctx, int excp)
36
{
37
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
38
- TCGv_i32 helper_tmp = tcg_const_i32(excp);
39
- gen_helper_raise_exception(cpu_env, helper_tmp);
40
- tcg_temp_free_i32(helper_tmp);
41
+ gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
42
ctx->base.is_jmp = DISAS_NORETURN;
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
46
{
47
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
48
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
49
- TCGv_i32 helper_tmp = tcg_const_i32(excp);
50
- gen_helper_raise_exception(cpu_env, helper_tmp);
51
- tcg_temp_free_i32(helper_tmp);
52
+ gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
53
ctx->base.is_jmp = DISAS_NORETURN;
54
}
55
56
static void gen_exception_debug(void)
57
{
58
- TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
59
- gen_helper_raise_exception(cpu_env, helper_tmp);
60
- tcg_temp_free_i32(helper_tmp);
61
+ gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
62
}
63
64
/* Wrapper around tcg_gen_exit_tb that handles single stepping */
65
@@ -XXX,XX +XXX,XX @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
66
*/
67
cond1 = tcg_temp_new();
68
cond2 = tcg_temp_new();
69
- zeroreg = tcg_const_tl(0);
70
+ zeroreg = tcg_constant_tl(0);
71
resultopt1 = tcg_temp_new();
72
73
tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
74
@@ -XXX,XX +XXX,XX @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
75
76
tcg_temp_free(cond1);
77
tcg_temp_free(cond2);
78
- tcg_temp_free(zeroreg);
79
tcg_temp_free(resultopt1);
80
}
81
82
@@ -XXX,XX +XXX,XX @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
83
TCGv cond1, zeroreg, resultopt1;
84
cond1 = tcg_temp_new();
85
86
- zeroreg = tcg_const_tl(0);
87
+ zeroreg = tcg_constant_tl(0);
88
resultopt1 = tcg_temp_new();
89
90
tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
91
@@ -XXX,XX +XXX,XX @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
92
tcg_gen_divu_tl(ret, source1, source2);
93
94
tcg_temp_free(cond1);
95
- tcg_temp_free(zeroreg);
96
tcg_temp_free(resultopt1);
97
}
98
99
@@ -XXX,XX +XXX,XX @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
100
101
cond1 = tcg_temp_new();
102
cond2 = tcg_temp_new();
103
- zeroreg = tcg_const_tl(0);
104
+ zeroreg = tcg_constant_tl(0);
105
resultopt1 = tcg_temp_new();
106
107
tcg_gen_movi_tl(resultopt1, 1L);
108
@@ -XXX,XX +XXX,XX @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
109
110
tcg_temp_free(cond1);
111
tcg_temp_free(cond2);
112
- tcg_temp_free(zeroreg);
113
tcg_temp_free(resultopt1);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
117
{
118
TCGv cond1, zeroreg, resultopt1;
119
cond1 = tcg_temp_new();
120
- zeroreg = tcg_const_tl(0);
121
+ zeroreg = tcg_constant_tl(0);
122
resultopt1 = tcg_temp_new();
123
124
tcg_gen_movi_tl(resultopt1, (target_ulong)1);
125
@@ -XXX,XX +XXX,XX @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
126
source1);
127
128
tcg_temp_free(cond1);
129
- tcg_temp_free(zeroreg);
130
tcg_temp_free(resultopt1);
131
}
132
133
@@ -XXX,XX +XXX,XX @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
134
135
static void gen_set_rm(DisasContext *ctx, int rm)
136
{
137
- TCGv_i32 t0;
138
-
139
if (ctx->frm == rm) {
140
return;
141
}
142
ctx->frm = rm;
143
- t0 = tcg_const_i32(rm);
144
- gen_helper_set_rounding_mode(cpu_env, t0);
145
- tcg_temp_free_i32(t0);
146
+ gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
147
}
148
149
static int ex_plus_1(DisasContext *ctx, int nf)
150
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/riscv/insn_trans/trans_rvf.c.inc
153
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
154
@@ -XXX,XX +XXX,XX @@ static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
155
* Replace bit 31 in rs1 with inverse in rs2.
156
* This formulation retains the nanboxing of rs1.
157
*/
158
- mask = tcg_const_i64(~MAKE_64BIT_MASK(31, 1));
159
+ mask = tcg_constant_i64(~MAKE_64BIT_MASK(31, 1));
160
tcg_gen_nor_i64(rs2, rs2, mask);
161
tcg_gen_and_i64(rs1, mask, rs1);
162
tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
163
164
- tcg_temp_free_i64(mask);
165
tcg_temp_free_i64(rs2);
166
}
167
tcg_temp_free_i64(rs1);
168
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
169
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
170
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
171
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
172
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
173
/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
20
TCGv_i32 desc;
174
if (a->rs1 == 0) {
21
175
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
22
TCGLabel *over = gen_new_label();
176
- s1 = tcg_const_tl(RV_VLEN_MAX);
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
177
+ s1 = tcg_constant_tl(RV_VLEN_MAX);
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
178
} else {
25
179
s1 = tcg_temp_new();
26
dest = tcg_temp_new_ptr();
180
gen_get_gpr(s1, a->rs1);
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
181
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
28
TCGv_i32 desc;
29
30
TCGLabel *over = gen_new_label();
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
34
dest = tcg_temp_new_ptr();
35
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
36
TCGv_i32 desc;
37
38
TCGLabel *over = gen_new_label();
39
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
42
dest = tcg_temp_new_ptr();
43
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
44
TCGv_i32 desc;
45
46
TCGLabel *over = gen_new_label();
47
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
48
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
49
50
dest = tcg_temp_new_ptr();
51
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
182
return false;
52
return false;
183
}
53
}
184
54
185
- s2 = tcg_const_tl(a->zimm);
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
186
+ s2 = tcg_constant_tl(a->zimm);
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
187
dst = tcg_temp_new();
57
188
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
189
/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
190
if (a->rs1 == 0) {
191
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
192
- s1 = tcg_const_tl(RV_VLEN_MAX);
193
+ s1 = tcg_constant_tl(RV_VLEN_MAX);
194
} else {
195
s1 = tcg_temp_new();
196
gen_get_gpr(s1, a->rs1);
197
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
198
ctx->base.is_jmp = DISAS_NORETURN;
199
200
tcg_temp_free(s1);
201
- tcg_temp_free(s2);
202
tcg_temp_free(dst);
203
return true;
204
}
205
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
206
* The first part is vlen in bytes, encoded in maxsz of simd_desc.
207
* The second part is lmul, encoded in data of simd_desc.
208
*/
209
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
210
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
211
212
gen_get_gpr(base, rs1);
213
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
214
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
215
tcg_temp_free_ptr(dest);
216
tcg_temp_free_ptr(mask);
217
tcg_temp_free(base);
218
- tcg_temp_free_i32(desc);
219
gen_set_label(over);
220
return true;
221
}
222
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
223
mask = tcg_temp_new_ptr();
224
base = tcg_temp_new();
225
stride = tcg_temp_new();
226
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
227
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
228
229
gen_get_gpr(base, rs1);
230
gen_get_gpr(stride, rs2);
231
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
232
tcg_temp_free_ptr(mask);
233
tcg_temp_free(base);
234
tcg_temp_free(stride);
235
- tcg_temp_free_i32(desc);
236
gen_set_label(over);
237
return true;
238
}
239
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
240
mask = tcg_temp_new_ptr();
241
index = tcg_temp_new_ptr();
242
base = tcg_temp_new();
243
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
244
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
245
246
gen_get_gpr(base, rs1);
247
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
248
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
249
tcg_temp_free_ptr(mask);
250
tcg_temp_free_ptr(index);
251
tcg_temp_free(base);
252
- tcg_temp_free_i32(desc);
253
gen_set_label(over);
254
return true;
255
}
256
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
257
dest = tcg_temp_new_ptr();
258
mask = tcg_temp_new_ptr();
259
base = tcg_temp_new();
260
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
261
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
262
263
gen_get_gpr(base, rs1);
264
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
265
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
266
tcg_temp_free_ptr(dest);
267
tcg_temp_free_ptr(mask);
268
tcg_temp_free(base);
269
- tcg_temp_free_i32(desc);
270
gen_set_label(over);
271
return true;
272
}
273
@@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
274
mask = tcg_temp_new_ptr();
275
index = tcg_temp_new_ptr();
276
base = tcg_temp_new();
277
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
278
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
279
280
gen_get_gpr(base, rs1);
281
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
282
@@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
283
tcg_temp_free_ptr(mask);
284
tcg_temp_free_ptr(index);
285
tcg_temp_free(base);
286
- tcg_temp_free_i32(desc);
287
gen_set_label(over);
288
return true;
289
}
290
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
291
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
60
uint32_t data = 0;
61
62
TCGLabel *over = gen_new_label();
63
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
64
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
65
66
dest = tcg_temp_new_ptr();
67
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
68
uint32_t data = 0;
69
70
TCGLabel *over = gen_new_label();
71
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
72
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
73
74
dest = tcg_temp_new_ptr();
75
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
76
if (checkfn(s, a)) {
77
uint32_t data = 0;
78
TCGLabel *over = gen_new_label();
79
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
80
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
81
82
data = FIELD_DP32(data, VDATA, VM, a->vm);
83
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
84
if (opiwv_widen_check(s, a)) {
85
uint32_t data = 0;
86
TCGLabel *over = gen_new_label();
87
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
88
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
89
90
data = FIELD_DP32(data, VDATA, VM, a->vm);
91
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
92
{
93
uint32_t data = 0;
94
TCGLabel *over = gen_new_label();
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
97
292
data = FIELD_DP32(data, VDATA, VM, vm);
98
data = FIELD_DP32(data, VDATA, VM, vm);
293
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
294
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
100
gen_helper_##NAME##_w, \
295
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
101
}; \
296
102
TCGLabel *over = gen_new_label(); \
297
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
298
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
299
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
105
\
300
tcg_temp_free_ptr(mask);
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
301
tcg_temp_free_ptr(src2);
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
302
tcg_temp_free(src1);
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
303
- tcg_temp_free_i32(desc);
109
};
304
gen_set_label(over);
110
TCGLabel *over = gen_new_label();
305
return true;
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
306
}
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
307
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
113
308
mask = tcg_temp_new_ptr();
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
309
src2 = tcg_temp_new_ptr();
310
if (zx) {
311
- src1 = tcg_const_tl(imm);
312
+ src1 = tcg_constant_tl(imm);
313
} else {
314
- src1 = tcg_const_tl(sextract64(imm, 0, 5));
315
+ src1 = tcg_constant_tl(sextract64(imm, 0, 5));
316
}
317
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
318
data = FIELD_DP32(data, VDATA, VM, vm);
319
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
320
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
321
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
322
323
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
324
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
325
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
326
tcg_temp_free_ptr(dest);
327
tcg_temp_free_ptr(mask);
328
tcg_temp_free_ptr(src2);
329
- tcg_temp_free(src1);
330
- tcg_temp_free_i32(desc);
331
gen_set_label(over);
332
return true;
333
}
334
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
335
static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
336
int64_t c, uint32_t oprsz, uint32_t maxsz)
337
{
338
- TCGv_i64 tmp = tcg_const_i64(c);
339
+ TCGv_i64 tmp = tcg_constant_i64(c);
340
tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
341
- tcg_temp_free_i64(tmp);
342
}
343
344
GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
345
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
346
tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
116
vext_check_ss(s, a->rd, 0, 1)) {
347
MAXSZ(s), MAXSZ(s), s1);
117
TCGv s1;
348
} else {
118
TCGLabel *over = gen_new_label();
349
- TCGv_i32 desc ;
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
350
+ TCGv_i32 desc;
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
351
TCGv_i64 s1_i64 = tcg_temp_new_i64();
121
352
TCGv_ptr dest = tcg_temp_new_ptr();
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
353
uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
354
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
355
};
125
};
356
357
tcg_gen_ext_tl_i64(s1_i64, s1);
358
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
359
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
360
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
361
fns[s->sew](dest, s1_i64, cpu_env, desc);
362
363
tcg_temp_free_ptr(dest);
364
- tcg_temp_free_i32(desc);
365
tcg_temp_free_i64(s1_i64);
366
}
367
368
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
369
TCGLabel *over = gen_new_label();
126
TCGLabel *over = gen_new_label();
370
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
371
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
372
- s1 = tcg_const_i64(simm);
129
373
+ s1 = tcg_constant_i64(simm);
130
s1 = tcg_constant_i64(simm);
374
dest = tcg_temp_new_ptr();
131
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
375
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
132
}; \
376
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
133
TCGLabel *over = gen_new_label(); \
377
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
134
gen_set_rm(s, RISCV_FRM_DYN); \
378
fns[s->sew](dest, s1, cpu_env, desc);
135
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
379
136
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
380
tcg_temp_free_ptr(dest);
137
\
381
- tcg_temp_free_i32(desc);
138
data = FIELD_DP32(data, VDATA, VM, a->vm); \
382
- tcg_temp_free_i64(s1);
383
gen_set_label(over);
384
}
385
return true;
386
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
139
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
387
dest = tcg_temp_new_ptr();
140
TCGv_i64 t1;
388
mask = tcg_temp_new_ptr();
141
389
src2 = tcg_temp_new_ptr();
142
TCGLabel *over = gen_new_label();
390
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
143
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
391
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
144
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
392
145
393
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
146
dest = tcg_temp_new_ptr();
394
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
147
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
395
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
148
}; \
396
tcg_temp_free_ptr(dest);
149
TCGLabel *over = gen_new_label(); \
397
tcg_temp_free_ptr(mask);
150
gen_set_rm(s, RISCV_FRM_DYN); \
398
tcg_temp_free_ptr(src2);
151
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
399
- tcg_temp_free_i32(desc);
152
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
400
gen_set_label(over);
153
\
401
return true;
154
data = FIELD_DP32(data, VDATA, VM, a->vm); \
402
}
155
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
156
}; \
157
TCGLabel *over = gen_new_label(); \
158
gen_set_rm(s, RISCV_FRM_DYN); \
159
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
160
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
161
\
162
data = FIELD_DP32(data, VDATA, VM, a->vm); \
163
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
164
uint32_t data = 0;
165
TCGLabel *over = gen_new_label();
166
gen_set_rm_chkfrm(s, rm);
167
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
168
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
169
170
data = FIELD_DP32(data, VDATA, VM, a->vm);
403
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
171
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
404
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
172
gen_helper_vmv_v_x_d,
405
173
};
406
dest = tcg_temp_new_ptr();
174
TCGLabel *over = gen_new_label();
407
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
175
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
408
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
176
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
409
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
177
410
fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
178
t1 = tcg_temp_new_i64();
411
179
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
412
tcg_temp_free_ptr(dest);
180
}; \
413
- tcg_temp_free_i32(desc);
181
TCGLabel *over = gen_new_label(); \
414
gen_set_label(over);
182
gen_set_rm_chkfrm(s, FRM); \
415
}
183
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
416
return true;
184
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
417
@@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
185
\
418
mask = tcg_temp_new_ptr();
186
data = FIELD_DP32(data, VDATA, VM, a->vm); \
419
src2 = tcg_temp_new_ptr();
187
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
420
dst = tcg_temp_new();
188
}; \
421
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
189
TCGLabel *over = gen_new_label(); \
422
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
190
gen_set_rm(s, RISCV_FRM_DYN); \
423
191
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
424
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
192
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
425
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
193
\
426
@@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
194
data = FIELD_DP32(data, VDATA, VM, a->vm); \
427
tcg_temp_free_ptr(mask);
195
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
428
tcg_temp_free_ptr(src2);
196
}; \
429
tcg_temp_free(dst);
197
TCGLabel *over = gen_new_label(); \
430
- tcg_temp_free_i32(desc);
198
gen_set_rm_chkfrm(s, FRM); \
431
return true;
199
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
432
}
200
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
433
return false;
201
\
434
@@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
202
data = FIELD_DP32(data, VDATA, VM, a->vm); \
435
mask = tcg_temp_new_ptr();
203
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
436
src2 = tcg_temp_new_ptr();
204
}; \
437
dst = tcg_temp_new();
205
TCGLabel *over = gen_new_label(); \
438
- desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
206
gen_set_rm_chkfrm(s, FRM); \
439
+ desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
207
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
440
208
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
441
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
209
\
442
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
210
data = FIELD_DP32(data, VDATA, VM, a->vm); \
443
@@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
211
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
444
tcg_temp_free_ptr(mask);
212
uint32_t data = 0; \
445
tcg_temp_free_ptr(src2);
213
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
446
tcg_temp_free(dst);
214
TCGLabel *over = gen_new_label(); \
447
- tcg_temp_free_i32(desc);
215
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
448
return true;
216
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
449
}
217
\
450
return false;
218
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
451
@@ -XXX,XX +XXX,XX @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
219
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
452
tcg_temp_free_i32(ofs);
220
require_vm(a->vm, a->rd)) {
453
221
uint32_t data = 0;
454
/* Flush out-of-range indexing to zero. */
222
TCGLabel *over = gen_new_label();
455
- t_vlmax = tcg_const_i64(vlmax);
223
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
456
- t_zero = tcg_const_i64(0);
224
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
457
+ t_vlmax = tcg_constant_i64(vlmax);
225
458
+ t_zero = tcg_constant_i64(0);
226
data = FIELD_DP32(data, VDATA, VM, a->vm);
459
tcg_gen_extu_tl_i64(t_idx, idx);
227
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
460
228
TCGv s1;
461
tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
229
TCGLabel *over = gen_new_label();
462
t_vlmax, dest, t_zero);
230
463
231
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
464
- tcg_temp_free_i64(t_vlmax);
232
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
465
- tcg_temp_free_i64(t_zero);
233
466
tcg_temp_free_i64(t_idx);
234
t1 = tcg_temp_new_i64();
467
}
235
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
468
236
TCGv_i64 t1;
237
TCGLabel *over = gen_new_label();
238
239
- /* if vl == 0 or vstart >= vl, skip vector register write back */
240
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
241
+ /* if vstart >= vl, skip vector register write back */
242
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
243
244
/* NaN-box f[rs1] */
245
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
246
uint32_t data = 0;
247
gen_helper_gvec_3_ptr *fn;
248
TCGLabel *over = gen_new_label();
249
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
250
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
251
252
static gen_helper_gvec_3_ptr * const fns[6][4] = {
469
--
253
--
470
2.31.1
254
2.41.0
471
472
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
Tested-by: Bin Meng <bmeng.cn@gmail.com>
3
This commit adds support for the Zvbc vector-crypto extension, which
4
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
4
consists of the following instructions:
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
* vclmulh.[vx,vv]
7
Message-id: 20210823195529.560295-3-richard.henderson@linaro.org
7
* vclmul.[vx,vv]
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
21
---
10
tests/tcg/riscv64/test-div.c | 58 +++++++++++++++++++++++++++++++
22
target/riscv/cpu_cfg.h | 1 +
11
tests/tcg/riscv64/Makefile.target | 5 +++
23
target/riscv/helper.h | 6 +++
12
2 files changed, 63 insertions(+)
24
target/riscv/insn32.decode | 6 +++
13
create mode 100644 tests/tcg/riscv64/test-div.c
25
target/riscv/cpu.c | 9 ++++
14
create mode 100644 tests/tcg/riscv64/Makefile.target
26
target/riscv/translate.c | 1 +
15
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
16
diff --git a/tests/tcg/riscv64/test-div.c b/tests/tcg/riscv64/test-div.c
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
29
target/riscv/meson.build | 3 +-
30
8 files changed, 146 insertions(+), 1 deletion(-)
31
create mode 100644 target/riscv/vcrypto_helper.c
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
33
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
bool ext_zve32f;
40
bool ext_zve64f;
41
bool ext_zve64d;
42
+ bool ext_zvbc;
43
bool ext_zmmul;
44
bool ext_zvfbfmin;
45
bool ext_zvfbfwma;
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/helper.h
49
+++ b/target/riscv/helper.h
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
51
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
54
+
55
+/* Vector crypto functions */
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
60
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/insn32.decode
63
+++ b/target/riscv/insn32.decode
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
65
# *** Zvfbfwma Standard Extension ***
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
68
+
69
+# *** Zvbc vector crypto extension ***
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
74
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
78
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
87
return;
88
}
89
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
92
+ return;
93
+ }
94
+
95
if (cpu->cfg.ext_zk) {
96
cpu->cfg.ext_zkn = true;
97
cpu->cfg.ext_zkr = true;
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
101
102
+ /* Vector cryptography extensions */
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
104
+
105
DEFINE_PROP_END_OF_LIST(),
106
};
107
108
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
113
#include "insn_trans/trans_rvzfa.c.inc"
114
#include "insn_trans/trans_rvzfh.c.inc"
115
#include "insn_trans/trans_rvk.c.inc"
116
+#include "insn_trans/trans_rvvk.c.inc"
117
#include "insn_trans/trans_privileged.c.inc"
118
#include "insn_trans/trans_svinval.c.inc"
119
#include "insn_trans/trans_rvbf16.c.inc"
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
17
new file mode 100644
121
new file mode 100644
18
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
19
--- /dev/null
123
--- /dev/null
20
+++ b/tests/tcg/riscv64/test-div.c
124
+++ b/target/riscv/vcrypto_helper.c
21
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
22
+#include <assert.h>
126
+/*
23
+#include <limits.h>
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
24
+
128
+ *
25
+struct TestS {
129
+ * Copyright (C) 2023 SiFive, Inc.
26
+ long x, y, q, r;
130
+ * Written by Codethink Ltd and SiFive.
27
+};
131
+ *
28
+
132
+ * This program is free software; you can redistribute it and/or modify it
29
+static struct TestS test_s[] = {
133
+ * under the terms and conditions of the GNU General Public License,
30
+ { 4, 2, 2, 0 }, /* normal cases */
134
+ * version 2 or later, as published by the Free Software Foundation.
31
+ { 9, 7, 1, 2 },
135
+ *
32
+ { 0, 0, -1, 0 }, /* div by zero cases */
136
+ * This program is distributed in the hope it will be useful, but WITHOUT
33
+ { 9, 0, -1, 9 },
137
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34
+ { LONG_MIN, -1, LONG_MIN, 0 }, /* overflow case */
138
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
35
+};
139
+ * more details.
36
+
140
+ *
37
+struct TestU {
141
+ * You should have received a copy of the GNU General Public License along with
38
+ unsigned long x, y, q, r;
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
39
+};
143
+ */
40
+
144
+
41
+static struct TestU test_u[] = {
145
+#include "qemu/osdep.h"
42
+ { 4, 2, 2, 0 }, /* normal cases */
146
+#include "qemu/host-utils.h"
43
+ { 9, 7, 1, 2 },
147
+#include "qemu/bitops.h"
44
+ { 0, 0, ULONG_MAX, 0 }, /* div by zero cases */
148
+#include "cpu.h"
45
+ { 9, 0, ULONG_MAX, 9 },
149
+#include "exec/memop.h"
46
+};
150
+#include "exec/exec-all.h"
47
+
151
+#include "exec/helper-proto.h"
48
+#define ARRAY_SIZE(X) (sizeof(X) / sizeof(*(X)))
152
+#include "internals.h"
49
+
153
+#include "vector_internals.h"
50
+int main (void)
154
+
51
+{
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
52
+ int i;
156
+{
53
+
157
+ uint64_t result = 0;
54
+ for (i = 0; i < ARRAY_SIZE(test_s); i++) {
158
+ for (int j = 63; j >= 0; j--) {
55
+ long q, r;
159
+ if ((y >> j) & 1) {
56
+
160
+ result ^= (x << j);
57
+ asm("div %0, %2, %3\n\t"
161
+ }
58
+ "rem %1, %2, %3"
162
+ }
59
+ : "=&r" (q), "=r" (r)
163
+ return result;
60
+ : "r" (test_s[i].x), "r" (test_s[i].y));
164
+}
61
+
165
+
62
+ assert(q == test_s[i].q);
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
63
+ assert(r == test_s[i].r);
167
+{
64
+ }
168
+ uint64_t result = 0;
65
+
169
+ for (int j = 63; j >= 1; j--) {
66
+ for (i = 0; i < ARRAY_SIZE(test_u); i++) {
170
+ if ((y >> j) & 1) {
67
+ unsigned long q, r;
171
+ result ^= (x >> (64 - j));
68
+
172
+ }
69
+ asm("divu %0, %2, %3\n\t"
173
+ }
70
+ "remu %1, %2, %3"
174
+ return result;
71
+ : "=&r" (q), "=r" (r)
175
+}
72
+ : "r" (test_u[i].x), "r" (test_u[i].y));
176
+
73
+
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
74
+ assert(q == test_u[i].q);
178
+GEN_VEXT_VV(vclmul_vv, 8)
75
+ assert(r == test_u[i].r);
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
76
+ }
180
+GEN_VEXT_VX(vclmul_vx, 8)
77
+
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
78
+ return 0;
182
+GEN_VEXT_VV(vclmulh_vv, 8)
79
+}
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
80
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
184
+GEN_VEXT_VX(vclmulh_vx, 8)
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
81
new file mode 100644
186
new file mode 100644
82
index XXXXXXX..XXXXXXX
187
index XXXXXXX..XXXXXXX
83
--- /dev/null
188
--- /dev/null
84
+++ b/tests/tcg/riscv64/Makefile.target
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
85
@@ -XXX,XX +XXX,XX @@
190
@@ -XXX,XX +XXX,XX @@
86
+# -*- Mode: makefile -*-
191
+/*
87
+# RISC-V specific tweaks
192
+ * RISC-V translation routines for the vector crypto extension.
88
+
193
+ *
89
+VPATH += $(SRC_PATH)/tests/tcg/riscv64
194
+ * Copyright (C) 2023 SiFive, Inc.
90
+TESTS += test-div
195
+ * Written by Codethink Ltd and SiFive.
196
+ *
197
+ * This program is free software; you can redistribute it and/or modify it
198
+ * under the terms and conditions of the GNU General Public License,
199
+ * version 2 or later, as published by the Free Software Foundation.
200
+ *
201
+ * This program is distributed in the hope it will be useful, but WITHOUT
202
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
203
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
204
+ * more details.
205
+ *
206
+ * You should have received a copy of the GNU General Public License along with
207
+ * this program. If not, see <http://www.gnu.org/licenses/>.
208
+ */
209
+
210
+/*
211
+ * Zvbc
212
+ */
213
+
214
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
215
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
216
+ { \
217
+ if (CHECK(s, a)) { \
218
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
219
+ gen_helper_##NAME, s); \
220
+ } \
221
+ return false; \
222
+ }
223
+
224
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
225
+{
226
+ return opivv_check(s, a) &&
227
+ s->cfg_ptr->ext_zvbc == true &&
228
+ s->sew == MO_64;
229
+}
230
+
231
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
232
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
233
+
234
+#define GEN_VX_MASKED_TRANS(NAME, CHECK) \
235
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
236
+ { \
237
+ if (CHECK(s, a)) { \
238
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
239
+ gen_helper_##NAME, s); \
240
+ } \
241
+ return false; \
242
+ }
243
+
244
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
245
+{
246
+ return opivx_check(s, a) &&
247
+ s->cfg_ptr->ext_zvbc == true &&
248
+ s->sew == MO_64;
249
+}
250
+
251
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
252
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
254
index XXXXXXX..XXXXXXX 100644
255
--- a/target/riscv/meson.build
256
+++ b/target/riscv/meson.build
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
258
'translate.c',
259
'm128_helper.c',
260
'crypto_helper.c',
261
- 'zce_helper.c'
262
+ 'zce_helper.c',
263
+ 'vcrypto_helper.c'
264
))
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
266
91
--
267
--
92
2.31.1
268
2.41.0
93
94
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
and into the corresponding macros. This enables the functions to be
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
reused in proceeding commits without check duplication.
6
Message-id: 20210823195529.560295-23-richard.henderson@linaro.org
6
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
13
---
9
target/riscv/insn_trans/trans_rvd.c.inc | 125 ++++++++++++------------
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
10
1 file changed, 60 insertions(+), 65 deletions(-)
15
1 file changed, 12 insertions(+), 16 deletions(-)
11
16
12
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
17
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/insn_trans/trans_rvd.c.inc
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
15
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
17
22
gen_helper_gvec_4_ptr *fn)
18
static bool trans_fld(DisasContext *ctx, arg_fld *a)
19
{
23
{
20
+ TCGv addr;
24
TCGLabel *over = gen_new_label();
21
+
25
- if (!opivv_check(s, a)) {
22
REQUIRE_FPU;
26
- return false;
23
REQUIRE_EXT(ctx, RVD);
27
- }
24
- TCGv t0 = tcg_temp_new();
28
25
- gen_get_gpr(ctx, t0, a->rs1);
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
26
- tcg_gen_addi_tl(t0, t0, a->imm);
30
27
31
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
28
- tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
32
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
29
+ addr = get_gpr(ctx, a->rs1, EXT_NONE);
33
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
30
+ if (a->imm) {
34
}; \
31
+ TCGv temp = temp_new(ctx);
35
+ if (!opivv_check(s, a)) { \
32
+ tcg_gen_addi_tl(temp, addr, a->imm);
36
+ return false; \
33
+ addr = temp;
37
+ } \
34
+ }
38
return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
35
+
36
+ tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
37
38
mark_fs_dirty(ctx);
39
- tcg_temp_free(t0);
40
return true;
41
}
39
}
42
40
43
static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
41
@@ -XXX,XX +XXX,XX @@ static inline bool
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
43
gen_helper_opivx *fn)
44
{
44
{
45
+ TCGv addr;
45
- if (!opivx_check(s, a)) {
46
+
46
- return false;
47
REQUIRE_FPU;
47
- }
48
REQUIRE_EXT(ctx, RVD);
48
-
49
- TCGv t0 = tcg_temp_new();
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
50
- gen_get_gpr(ctx, t0, a->rs1);
50
TCGv_i64 src1 = tcg_temp_new_i64();
51
- tcg_gen_addi_tl(t0, t0, a->imm);
51
52
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
53
- tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
54
+ addr = get_gpr(ctx, a->rs1, EXT_NONE);
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
55
+ if (a->imm) {
55
}; \
56
+ TCGv temp = temp_new(ctx);
56
+ if (!opivx_check(s, a)) { \
57
+ tcg_gen_addi_tl(temp, addr, a->imm);
57
+ return false; \
58
+ addr = temp;
58
+ } \
59
+ }
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
60
+
61
+ tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
62
63
- tcg_temp_free(t0);
64
return true;
65
}
60
}
66
61
67
@@ -XXX,XX +XXX,XX @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
62
@@ -XXX,XX +XXX,XX @@ static inline bool
68
REQUIRE_FPU;
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
69
REQUIRE_EXT(ctx, RVD);
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
70
65
{
71
- TCGv t0 = tcg_temp_new();
66
- if (!opivx_check(s, a)) {
72
- gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
67
- return false;
73
- gen_set_gpr(ctx, a->rd, t0);
68
- }
74
- tcg_temp_free(t0);
69
-
75
+ TCGv dest = dest_gpr(ctx, a->rd);
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
76
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
77
+ gen_helper_feq_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
78
+ gen_set_gpr(ctx, a->rd, dest);
73
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
79
return true;
74
gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \
75
gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \
76
}; \
77
+ if (!opivx_check(s, a)) { \
78
+ return false; \
79
+ } \
80
return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
81
fns[s->sew], IMM_MODE); \
80
}
82
}
81
83
@@ -XXX,XX +XXX,XX @@ static inline bool
82
@@ -XXX,XX +XXX,XX @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
83
REQUIRE_FPU;
85
gen_helper_opivx *fn)
84
REQUIRE_EXT(ctx, RVD);
86
{
85
87
- if (!opivx_check(s, a)) {
86
- TCGv t0 = tcg_temp_new();
88
- return false;
87
- gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
89
- }
88
- gen_set_gpr(ctx, a->rd, t0);
90
-
89
- tcg_temp_free(t0);
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
90
+ TCGv dest = dest_gpr(ctx, a->rd);
92
TCGv_i32 src1 = tcg_temp_new_i32();
91
93
92
+ gen_helper_flt_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
93
+ gen_set_gpr(ctx, a->rd, dest);
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
94
return true;
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
97
}; \
98
- \
99
+ if (!opivx_check(s, a)) { \
100
+ return false; \
101
+ } \
102
return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
95
}
103
}
96
104
97
@@ -XXX,XX +XXX,XX @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
98
REQUIRE_FPU;
99
REQUIRE_EXT(ctx, RVD);
100
101
- TCGv t0 = tcg_temp_new();
102
- gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
103
- gen_set_gpr(ctx, a->rd, t0);
104
- tcg_temp_free(t0);
105
+ TCGv dest = dest_gpr(ctx, a->rd);
106
107
+ gen_helper_fle_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
108
+ gen_set_gpr(ctx, a->rd, dest);
109
return true;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
113
REQUIRE_FPU;
114
REQUIRE_EXT(ctx, RVD);
115
116
- TCGv t0 = tcg_temp_new();
117
- gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
118
- gen_set_gpr(ctx, a->rd, t0);
119
- tcg_temp_free(t0);
120
+ TCGv dest = dest_gpr(ctx, a->rd);
121
+
122
+ gen_helper_fclass_d(dest, cpu_fpr[a->rs1]);
123
+ gen_set_gpr(ctx, a->rd, dest);
124
return true;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
128
REQUIRE_FPU;
129
REQUIRE_EXT(ctx, RVD);
130
131
- TCGv t0 = tcg_temp_new();
132
- gen_set_rm(ctx, a->rm);
133
- gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
134
- gen_set_gpr(ctx, a->rd, t0);
135
- tcg_temp_free(t0);
136
+ TCGv dest = dest_gpr(ctx, a->rd);
137
138
+ gen_set_rm(ctx, a->rm);
139
+ gen_helper_fcvt_w_d(dest, cpu_env, cpu_fpr[a->rs1]);
140
+ gen_set_gpr(ctx, a->rd, dest);
141
return true;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
145
REQUIRE_FPU;
146
REQUIRE_EXT(ctx, RVD);
147
148
- TCGv t0 = tcg_temp_new();
149
- gen_set_rm(ctx, a->rm);
150
- gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
151
- gen_set_gpr(ctx, a->rd, t0);
152
- tcg_temp_free(t0);
153
+ TCGv dest = dest_gpr(ctx, a->rd);
154
155
+ gen_set_rm(ctx, a->rm);
156
+ gen_helper_fcvt_wu_d(dest, cpu_env, cpu_fpr[a->rs1]);
157
+ gen_set_gpr(ctx, a->rd, dest);
158
return true;
159
}
160
161
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
162
REQUIRE_FPU;
163
REQUIRE_EXT(ctx, RVD);
164
165
- TCGv t0 = tcg_temp_new();
166
- gen_get_gpr(ctx, t0, a->rs1);
167
+ TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
168
169
gen_set_rm(ctx, a->rm);
170
- gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
171
- tcg_temp_free(t0);
172
+ gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, src);
173
174
mark_fs_dirty(ctx);
175
return true;
176
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
177
REQUIRE_FPU;
178
REQUIRE_EXT(ctx, RVD);
179
180
- TCGv t0 = tcg_temp_new();
181
- gen_get_gpr(ctx, t0, a->rs1);
182
+ TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
183
184
gen_set_rm(ctx, a->rm);
185
- gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
186
- tcg_temp_free(t0);
187
+ gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, src);
188
189
mark_fs_dirty(ctx);
190
return true;
191
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
192
REQUIRE_FPU;
193
REQUIRE_EXT(ctx, RVD);
194
195
- TCGv t0 = tcg_temp_new();
196
+ TCGv dest = dest_gpr(ctx, a->rd);
197
+
198
gen_set_rm(ctx, a->rm);
199
- gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
200
- gen_set_gpr(ctx, a->rd, t0);
201
- tcg_temp_free(t0);
202
+ gen_helper_fcvt_l_d(dest, cpu_env, cpu_fpr[a->rs1]);
203
+ gen_set_gpr(ctx, a->rd, dest);
204
return true;
205
}
206
207
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
208
REQUIRE_FPU;
209
REQUIRE_EXT(ctx, RVD);
210
211
- TCGv t0 = tcg_temp_new();
212
+ TCGv dest = dest_gpr(ctx, a->rd);
213
+
214
gen_set_rm(ctx, a->rm);
215
- gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
216
- gen_set_gpr(ctx, a->rd, t0);
217
- tcg_temp_free(t0);
218
+ gen_helper_fcvt_lu_d(dest, cpu_env, cpu_fpr[a->rs1]);
219
+ gen_set_gpr(ctx, a->rd, dest);
220
return true;
221
}
222
223
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
224
REQUIRE_FPU;
225
REQUIRE_EXT(ctx, RVD);
226
227
- TCGv t0 = tcg_temp_new();
228
- gen_get_gpr(ctx, t0, a->rs1);
229
+ TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
230
231
gen_set_rm(ctx, a->rm);
232
- gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
233
- tcg_temp_free(t0);
234
+ gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, src);
235
+
236
mark_fs_dirty(ctx);
237
return true;
238
}
239
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
240
REQUIRE_FPU;
241
REQUIRE_EXT(ctx, RVD);
242
243
- TCGv t0 = tcg_temp_new();
244
- gen_get_gpr(ctx, t0, a->rs1);
245
+ TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
246
247
gen_set_rm(ctx, a->rm);
248
- gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
249
- tcg_temp_free(t0);
250
+ gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, src);
251
+
252
mark_fs_dirty(ctx);
253
return true;
254
}
255
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
256
REQUIRE_EXT(ctx, RVD);
257
258
#ifdef TARGET_RISCV64
259
- TCGv t0 = tcg_temp_new();
260
- gen_get_gpr(ctx, t0, a->rs1);
261
-
262
- tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
263
- tcg_temp_free(t0);
264
+ tcg_gen_mov_tl(cpu_fpr[a->rd], get_gpr(ctx, a->rs1, EXT_NONE));
265
mark_fs_dirty(ctx);
266
return true;
267
#else
268
--
105
--
269
2.31.1
106
2.41.0
270
271
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
We will require the context to handle RV64 word operations.
3
Zvbb (implemented in later commit) has a widening instruction, which
4
requires an extra check on the enabled extensions. Refactor
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
it.
4
7
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-id: 20210823195529.560295-5-richard.henderson@linaro.org
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
target/riscv/translate.c | 58 ++++++++++++-------------
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
13
target/riscv/insn_trans/trans_rva.c.inc | 18 ++++----
16
1 file changed, 23 insertions(+), 29 deletions(-)
14
target/riscv/insn_trans/trans_rvb.c.inc | 4 +-
15
target/riscv/insn_trans/trans_rvd.c.inc | 32 +++++++-------
16
target/riscv/insn_trans/trans_rvf.c.inc | 32 +++++++-------
17
target/riscv/insn_trans/trans_rvh.c.inc | 52 +++++++++++-----------
18
target/riscv/insn_trans/trans_rvi.c.inc | 44 +++++++++----------
19
target/riscv/insn_trans/trans_rvm.c.inc | 12 ++---
20
target/riscv/insn_trans/trans_rvv.c.inc | 36 +++++++--------
21
9 files changed, 144 insertions(+), 144 deletions(-)
22
17
23
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/translate.c
26
+++ b/target/riscv/translate.c
27
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
28
/* Wrapper for getting reg values - need to check of reg is zero since
29
* cpu_gpr[0] is not actually allocated
30
*/
31
-static inline void gen_get_gpr(TCGv t, int reg_num)
32
+static void gen_get_gpr(DisasContext *ctx, TCGv t, int reg_num)
33
{
34
if (reg_num == 0) {
35
tcg_gen_movi_tl(t, 0);
36
@@ -XXX,XX +XXX,XX @@ static inline void gen_get_gpr(TCGv t, int reg_num)
37
* since we usually avoid calling the OP_TYPE_gen function if we see a write to
38
* $zero
39
*/
40
-static inline void gen_set_gpr(int reg_num_dst, TCGv t)
41
+static void gen_set_gpr(DisasContext *ctx, int reg_num_dst, TCGv t)
42
{
43
if (reg_num_dst != 0) {
44
tcg_gen_mov_tl(cpu_gpr[reg_num_dst], t);
45
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
46
TCGv source1;
47
source1 = tcg_temp_new();
48
49
- gen_get_gpr(source1, a->rs1);
50
+ gen_get_gpr(ctx, source1, a->rs1);
51
52
(*func)(source1, source1, a->imm);
53
54
- gen_set_gpr(a->rd, source1);
55
+ gen_set_gpr(ctx, a->rd, source1);
56
tcg_temp_free(source1);
57
return true;
58
}
59
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
60
source1 = tcg_temp_new();
61
source2 = tcg_temp_new();
62
63
- gen_get_gpr(source1, a->rs1);
64
+ gen_get_gpr(ctx, source1, a->rs1);
65
tcg_gen_movi_tl(source2, a->imm);
66
67
(*func)(source1, source1, source2);
68
69
- gen_set_gpr(a->rd, source1);
70
+ gen_set_gpr(ctx, a->rd, source1);
71
tcg_temp_free(source1);
72
tcg_temp_free(source2);
73
return true;
74
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
75
source1 = tcg_temp_new();
76
source2 = tcg_temp_new();
77
78
- gen_get_gpr(source1, a->rs1);
79
- gen_get_gpr(source2, a->rs2);
80
+ gen_get_gpr(ctx, source1, a->rs1);
81
+ gen_get_gpr(ctx, source2, a->rs2);
82
tcg_gen_ext32s_tl(source1, source1);
83
tcg_gen_ext32s_tl(source2, source2);
84
85
(*func)(source1, source1, source2);
86
87
tcg_gen_ext32s_tl(source1, source1);
88
- gen_set_gpr(a->rd, source1);
89
+ gen_set_gpr(ctx, a->rd, source1);
90
tcg_temp_free(source1);
91
tcg_temp_free(source2);
92
return true;
93
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
94
source1 = tcg_temp_new();
95
source2 = tcg_temp_new();
96
97
- gen_get_gpr(source1, a->rs1);
98
- gen_get_gpr(source2, a->rs2);
99
+ gen_get_gpr(ctx, source1, a->rs1);
100
+ gen_get_gpr(ctx, source2, a->rs2);
101
tcg_gen_ext32u_tl(source1, source1);
102
tcg_gen_ext32u_tl(source2, source2);
103
104
(*func)(source1, source1, source2);
105
106
tcg_gen_ext32s_tl(source1, source1);
107
- gen_set_gpr(a->rd, source1);
108
+ gen_set_gpr(ctx, a->rd, source1);
109
tcg_temp_free(source1);
110
tcg_temp_free(source2);
111
return true;
112
@@ -XXX,XX +XXX,XX @@ static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
113
TCGv source1 = tcg_temp_new();
114
TCGv source2;
115
116
- gen_get_gpr(source1, a->rs1);
117
+ gen_get_gpr(ctx, source1, a->rs1);
118
119
if (a->shamt == (TARGET_LONG_BITS - 8)) {
120
/* rev8, byte swaps */
121
@@ -XXX,XX +XXX,XX @@ static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
122
tcg_temp_free(source2);
123
}
124
125
- gen_set_gpr(a->rd, source1);
126
+ gen_set_gpr(ctx, a->rd, source1);
127
tcg_temp_free(source1);
128
return true;
129
}
130
@@ -XXX,XX +XXX,XX @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
131
source1 = tcg_temp_new();
132
source2 = tcg_temp_new();
133
134
- gen_get_gpr(source1, a->rs1);
135
- gen_get_gpr(source2, a->rs2);
136
+ gen_get_gpr(ctx, source1, a->rs1);
137
+ gen_get_gpr(ctx, source2, a->rs2);
138
139
(*func)(source1, source1, source2);
140
141
- gen_set_gpr(a->rd, source1);
142
+ gen_set_gpr(ctx, a->rd, source1);
143
tcg_temp_free(source1);
144
tcg_temp_free(source2);
145
return true;
146
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
147
TCGv source1 = tcg_temp_new();
148
TCGv source2 = tcg_temp_new();
149
150
- gen_get_gpr(source1, a->rs1);
151
- gen_get_gpr(source2, a->rs2);
152
+ gen_get_gpr(ctx, source1, a->rs1);
153
+ gen_get_gpr(ctx, source2, a->rs2);
154
155
tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
156
(*func)(source1, source1, source2);
157
158
- gen_set_gpr(a->rd, source1);
159
+ gen_set_gpr(ctx, a->rd, source1);
160
tcg_temp_free(source1);
161
tcg_temp_free(source2);
162
return true;
163
@@ -XXX,XX +XXX,XX @@ static bool gen_shifti(DisasContext *ctx, arg_shift *a,
164
TCGv source1 = tcg_temp_new();
165
TCGv source2 = tcg_temp_new();
166
167
- gen_get_gpr(source1, a->rs1);
168
+ gen_get_gpr(ctx, source1, a->rs1);
169
170
tcg_gen_movi_tl(source2, a->shamt);
171
(*func)(source1, source1, source2);
172
173
- gen_set_gpr(a->rd, source1);
174
+ gen_set_gpr(ctx, a->rd, source1);
175
tcg_temp_free(source1);
176
tcg_temp_free(source2);
177
return true;
178
@@ -XXX,XX +XXX,XX @@ static bool gen_shiftw(DisasContext *ctx, arg_r *a,
179
TCGv source1 = tcg_temp_new();
180
TCGv source2 = tcg_temp_new();
181
182
- gen_get_gpr(source1, a->rs1);
183
- gen_get_gpr(source2, a->rs2);
184
+ gen_get_gpr(ctx, source1, a->rs1);
185
+ gen_get_gpr(ctx, source2, a->rs2);
186
187
tcg_gen_andi_tl(source2, source2, 31);
188
(*func)(source1, source1, source2);
189
tcg_gen_ext32s_tl(source1, source1);
190
191
- gen_set_gpr(a->rd, source1);
192
+ gen_set_gpr(ctx, a->rd, source1);
193
tcg_temp_free(source1);
194
tcg_temp_free(source2);
195
return true;
196
@@ -XXX,XX +XXX,XX @@ static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
197
TCGv source1 = tcg_temp_new();
198
TCGv source2 = tcg_temp_new();
199
200
- gen_get_gpr(source1, a->rs1);
201
+ gen_get_gpr(ctx, source1, a->rs1);
202
tcg_gen_movi_tl(source2, a->shamt);
203
204
(*func)(source1, source1, source2);
205
tcg_gen_ext32s_tl(source1, source1);
206
207
- gen_set_gpr(a->rd, source1);
208
+ gen_set_gpr(ctx, a->rd, source1);
209
tcg_temp_free(source1);
210
tcg_temp_free(source2);
211
return true;
212
@@ -XXX,XX +XXX,XX @@ static bool gen_unary(DisasContext *ctx, arg_r2 *a,
213
{
214
TCGv source = tcg_temp_new();
215
216
- gen_get_gpr(source, a->rs1);
217
+ gen_get_gpr(ctx, source, a->rs1);
218
219
(*func)(source, source);
220
221
- gen_set_gpr(a->rd, source);
222
+ gen_set_gpr(ctx, a->rd, source);
223
tcg_temp_free(source);
224
return true;
225
}
226
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/riscv/insn_trans/trans_rva.c.inc
229
+++ b/target/riscv/insn_trans/trans_rva.c.inc
230
@@ -XXX,XX +XXX,XX @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
231
{
232
TCGv src1 = tcg_temp_new();
233
/* Put addr in load_res, data in load_val. */
234
- gen_get_gpr(src1, a->rs1);
235
+ gen_get_gpr(ctx, src1, a->rs1);
236
if (a->rl) {
237
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
238
}
239
@@ -XXX,XX +XXX,XX @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
240
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
241
}
242
tcg_gen_mov_tl(load_res, src1);
243
- gen_set_gpr(a->rd, load_val);
244
+ gen_set_gpr(ctx, a->rd, load_val);
245
246
tcg_temp_free(src1);
247
return true;
248
@@ -XXX,XX +XXX,XX @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
249
TCGLabel *l1 = gen_new_label();
250
TCGLabel *l2 = gen_new_label();
251
252
- gen_get_gpr(src1, a->rs1);
253
+ gen_get_gpr(ctx, src1, a->rs1);
254
tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
255
256
- gen_get_gpr(src2, a->rs2);
257
+ gen_get_gpr(ctx, src2, a->rs2);
258
/*
259
* Note that the TCG atomic primitives are SC,
260
* so we can ignore AQ/RL along this path.
261
@@ -XXX,XX +XXX,XX @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
262
tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
263
ctx->mem_idx, mop);
264
tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
265
- gen_set_gpr(a->rd, dat);
266
+ gen_set_gpr(ctx, a->rd, dat);
267
tcg_gen_br(l2);
268
269
gen_set_label(l1);
270
@@ -XXX,XX +XXX,XX @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
271
*/
272
tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
273
tcg_gen_movi_tl(dat, 1);
274
- gen_set_gpr(a->rd, dat);
275
+ gen_set_gpr(ctx, a->rd, dat);
276
277
gen_set_label(l2);
278
/*
279
@@ -XXX,XX +XXX,XX @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
280
TCGv src1 = tcg_temp_new();
281
TCGv src2 = tcg_temp_new();
282
283
- gen_get_gpr(src1, a->rs1);
284
- gen_get_gpr(src2, a->rs2);
285
+ gen_get_gpr(ctx, src1, a->rs1);
286
+ gen_get_gpr(ctx, src2, a->rs2);
287
288
(*func)(src2, src1, src2, ctx->mem_idx, mop);
289
290
- gen_set_gpr(a->rd, src2);
291
+ gen_set_gpr(ctx, a->rd, src2);
292
tcg_temp_free(src1);
293
tcg_temp_free(src2);
294
return true;
295
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
296
index XXXXXXX..XXXXXXX 100644
297
--- a/target/riscv/insn_trans/trans_rvb.c.inc
298
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
299
@@ -XXX,XX +XXX,XX @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
300
REQUIRE_EXT(ctx, RVB);
301
302
TCGv source1 = tcg_temp_new();
303
- gen_get_gpr(source1, a->rs1);
304
+ gen_get_gpr(ctx, source1, a->rs1);
305
306
if (a->shamt < 32) {
307
tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
309
tcg_gen_shli_tl(source1, source1, a->shamt);
310
}
311
312
- gen_set_gpr(a->rd, source1);
313
+ gen_set_gpr(ctx, a->rd, source1);
314
tcg_temp_free(source1);
315
return true;
316
}
317
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
318
index XXXXXXX..XXXXXXX 100644
319
--- a/target/riscv/insn_trans/trans_rvd.c.inc
320
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
321
@@ -XXX,XX +XXX,XX @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
322
REQUIRE_FPU;
323
REQUIRE_EXT(ctx, RVD);
324
TCGv t0 = tcg_temp_new();
325
- gen_get_gpr(t0, a->rs1);
326
+ gen_get_gpr(ctx, t0, a->rs1);
327
tcg_gen_addi_tl(t0, t0, a->imm);
328
329
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
330
@@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
331
REQUIRE_FPU;
332
REQUIRE_EXT(ctx, RVD);
333
TCGv t0 = tcg_temp_new();
334
- gen_get_gpr(t0, a->rs1);
335
+ gen_get_gpr(ctx, t0, a->rs1);
336
tcg_gen_addi_tl(t0, t0, a->imm);
337
338
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
339
@@ -XXX,XX +XXX,XX @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
340
341
TCGv t0 = tcg_temp_new();
342
gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
343
- gen_set_gpr(a->rd, t0);
344
+ gen_set_gpr(ctx, a->rd, t0);
345
tcg_temp_free(t0);
346
347
return true;
348
@@ -XXX,XX +XXX,XX @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
349
350
TCGv t0 = tcg_temp_new();
351
gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
352
- gen_set_gpr(a->rd, t0);
353
+ gen_set_gpr(ctx, a->rd, t0);
354
tcg_temp_free(t0);
355
356
return true;
357
@@ -XXX,XX +XXX,XX @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
358
359
TCGv t0 = tcg_temp_new();
360
gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
361
- gen_set_gpr(a->rd, t0);
362
+ gen_set_gpr(ctx, a->rd, t0);
363
tcg_temp_free(t0);
364
365
return true;
366
@@ -XXX,XX +XXX,XX @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
367
368
TCGv t0 = tcg_temp_new();
369
gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
370
- gen_set_gpr(a->rd, t0);
371
+ gen_set_gpr(ctx, a->rd, t0);
372
tcg_temp_free(t0);
373
return true;
374
}
375
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
376
TCGv t0 = tcg_temp_new();
377
gen_set_rm(ctx, a->rm);
378
gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
379
- gen_set_gpr(a->rd, t0);
380
+ gen_set_gpr(ctx, a->rd, t0);
381
tcg_temp_free(t0);
382
383
return true;
384
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
385
TCGv t0 = tcg_temp_new();
386
gen_set_rm(ctx, a->rm);
387
gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
388
- gen_set_gpr(a->rd, t0);
389
+ gen_set_gpr(ctx, a->rd, t0);
390
tcg_temp_free(t0);
391
392
return true;
393
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
394
REQUIRE_EXT(ctx, RVD);
395
396
TCGv t0 = tcg_temp_new();
397
- gen_get_gpr(t0, a->rs1);
398
+ gen_get_gpr(ctx, t0, a->rs1);
399
400
gen_set_rm(ctx, a->rm);
401
gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
402
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
403
REQUIRE_EXT(ctx, RVD);
404
405
TCGv t0 = tcg_temp_new();
406
- gen_get_gpr(t0, a->rs1);
407
+ gen_get_gpr(ctx, t0, a->rs1);
408
409
gen_set_rm(ctx, a->rm);
410
gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
411
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
412
TCGv t0 = tcg_temp_new();
413
gen_set_rm(ctx, a->rm);
414
gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
415
- gen_set_gpr(a->rd, t0);
416
+ gen_set_gpr(ctx, a->rd, t0);
417
tcg_temp_free(t0);
418
return true;
419
}
420
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
421
TCGv t0 = tcg_temp_new();
422
gen_set_rm(ctx, a->rm);
423
gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
424
- gen_set_gpr(a->rd, t0);
425
+ gen_set_gpr(ctx, a->rd, t0);
426
tcg_temp_free(t0);
427
return true;
428
}
429
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
430
REQUIRE_EXT(ctx, RVD);
431
432
#ifdef TARGET_RISCV64
433
- gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
434
+ gen_set_gpr(ctx, a->rd, cpu_fpr[a->rs1]);
435
return true;
436
#else
437
qemu_build_not_reached();
438
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
439
REQUIRE_EXT(ctx, RVD);
440
441
TCGv t0 = tcg_temp_new();
442
- gen_get_gpr(t0, a->rs1);
443
+ gen_get_gpr(ctx, t0, a->rs1);
444
445
gen_set_rm(ctx, a->rm);
446
gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
447
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
448
REQUIRE_EXT(ctx, RVD);
449
450
TCGv t0 = tcg_temp_new();
451
- gen_get_gpr(t0, a->rs1);
452
+ gen_get_gpr(ctx, t0, a->rs1);
453
454
gen_set_rm(ctx, a->rm);
455
gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
456
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
457
458
#ifdef TARGET_RISCV64
459
TCGv t0 = tcg_temp_new();
460
- gen_get_gpr(t0, a->rs1);
461
+ gen_get_gpr(ctx, t0, a->rs1);
462
463
tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
464
tcg_temp_free(t0);
465
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
466
index XXXXXXX..XXXXXXX 100644
467
--- a/target/riscv/insn_trans/trans_rvf.c.inc
468
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
469
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
470
REQUIRE_FPU;
471
REQUIRE_EXT(ctx, RVF);
472
TCGv t0 = tcg_temp_new();
473
- gen_get_gpr(t0, a->rs1);
474
+ gen_get_gpr(ctx, t0, a->rs1);
475
tcg_gen_addi_tl(t0, t0, a->imm);
476
477
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
478
@@ -XXX,XX +XXX,XX @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
479
REQUIRE_FPU;
480
REQUIRE_EXT(ctx, RVF);
481
TCGv t0 = tcg_temp_new();
482
- gen_get_gpr(t0, a->rs1);
483
+ gen_get_gpr(ctx, t0, a->rs1);
484
485
tcg_gen_addi_tl(t0, t0, a->imm);
486
487
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
488
TCGv t0 = tcg_temp_new();
489
gen_set_rm(ctx, a->rm);
490
gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
491
- gen_set_gpr(a->rd, t0);
492
+ gen_set_gpr(ctx, a->rd, t0);
493
tcg_temp_free(t0);
494
495
return true;
496
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
497
TCGv t0 = tcg_temp_new();
498
gen_set_rm(ctx, a->rm);
499
gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
500
- gen_set_gpr(a->rd, t0);
501
+ gen_set_gpr(ctx, a->rd, t0);
502
tcg_temp_free(t0);
503
504
return true;
505
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
506
tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
507
#endif
508
509
- gen_set_gpr(a->rd, t0);
510
+ gen_set_gpr(ctx, a->rd, t0);
511
tcg_temp_free(t0);
512
513
return true;
514
@@ -XXX,XX +XXX,XX @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
515
REQUIRE_EXT(ctx, RVF);
516
TCGv t0 = tcg_temp_new();
517
gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
518
- gen_set_gpr(a->rd, t0);
519
+ gen_set_gpr(ctx, a->rd, t0);
520
tcg_temp_free(t0);
521
return true;
522
}
523
@@ -XXX,XX +XXX,XX @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
524
REQUIRE_EXT(ctx, RVF);
525
TCGv t0 = tcg_temp_new();
526
gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
527
- gen_set_gpr(a->rd, t0);
528
+ gen_set_gpr(ctx, a->rd, t0);
529
tcg_temp_free(t0);
530
return true;
531
}
532
@@ -XXX,XX +XXX,XX @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
533
REQUIRE_EXT(ctx, RVF);
534
TCGv t0 = tcg_temp_new();
535
gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
536
- gen_set_gpr(a->rd, t0);
537
+ gen_set_gpr(ctx, a->rd, t0);
538
tcg_temp_free(t0);
539
return true;
540
}
541
@@ -XXX,XX +XXX,XX @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
542
543
gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
544
545
- gen_set_gpr(a->rd, t0);
546
+ gen_set_gpr(ctx, a->rd, t0);
547
tcg_temp_free(t0);
548
549
return true;
550
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
551
REQUIRE_EXT(ctx, RVF);
552
553
TCGv t0 = tcg_temp_new();
554
- gen_get_gpr(t0, a->rs1);
555
+ gen_get_gpr(ctx, t0, a->rs1);
556
557
gen_set_rm(ctx, a->rm);
558
gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
559
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
560
REQUIRE_EXT(ctx, RVF);
561
562
TCGv t0 = tcg_temp_new();
563
- gen_get_gpr(t0, a->rs1);
564
+ gen_get_gpr(ctx, t0, a->rs1);
565
566
gen_set_rm(ctx, a->rm);
567
gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
568
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
569
REQUIRE_EXT(ctx, RVF);
570
571
TCGv t0 = tcg_temp_new();
572
- gen_get_gpr(t0, a->rs1);
573
+ gen_get_gpr(ctx, t0, a->rs1);
574
575
tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
576
gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
577
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
578
TCGv t0 = tcg_temp_new();
579
gen_set_rm(ctx, a->rm);
580
gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
581
- gen_set_gpr(a->rd, t0);
582
+ gen_set_gpr(ctx, a->rd, t0);
583
tcg_temp_free(t0);
584
return true;
585
}
586
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
587
TCGv t0 = tcg_temp_new();
588
gen_set_rm(ctx, a->rm);
589
gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
590
- gen_set_gpr(a->rd, t0);
591
+ gen_set_gpr(ctx, a->rd, t0);
592
tcg_temp_free(t0);
593
return true;
594
}
595
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
596
REQUIRE_EXT(ctx, RVF);
597
598
TCGv t0 = tcg_temp_new();
599
- gen_get_gpr(t0, a->rs1);
600
+ gen_get_gpr(ctx, t0, a->rs1);
601
602
gen_set_rm(ctx, a->rm);
603
gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
604
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
605
REQUIRE_EXT(ctx, RVF);
606
607
TCGv t0 = tcg_temp_new();
608
- gen_get_gpr(t0, a->rs1);
609
+ gen_get_gpr(ctx, t0, a->rs1);
610
611
gen_set_rm(ctx, a->rm);
612
gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
613
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
614
index XXXXXXX..XXXXXXX 100644
615
--- a/target/riscv/insn_trans/trans_rvh.c.inc
616
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
617
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
618
619
check_access(ctx);
620
621
- gen_get_gpr(t0, a->rs1);
622
+ gen_get_gpr(ctx, t0, a->rs1);
623
624
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
625
- gen_set_gpr(a->rd, t1);
626
+ gen_set_gpr(ctx, a->rd, t1);
627
628
tcg_temp_free(t0);
629
tcg_temp_free(t1);
630
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
631
632
check_access(ctx);
633
634
- gen_get_gpr(t0, a->rs1);
635
+ gen_get_gpr(ctx, t0, a->rs1);
636
637
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
638
- gen_set_gpr(a->rd, t1);
639
+ gen_set_gpr(ctx, a->rd, t1);
640
641
tcg_temp_free(t0);
642
tcg_temp_free(t1);
643
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
644
645
check_access(ctx);
646
647
- gen_get_gpr(t0, a->rs1);
648
+ gen_get_gpr(ctx, t0, a->rs1);
649
650
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
651
- gen_set_gpr(a->rd, t1);
652
+ gen_set_gpr(ctx, a->rd, t1);
653
654
tcg_temp_free(t0);
655
tcg_temp_free(t1);
656
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
657
658
check_access(ctx);
659
660
- gen_get_gpr(t0, a->rs1);
661
+ gen_get_gpr(ctx, t0, a->rs1);
662
663
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
664
- gen_set_gpr(a->rd, t1);
665
+ gen_set_gpr(ctx, a->rd, t1);
666
667
tcg_temp_free(t0);
668
tcg_temp_free(t1);
669
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
670
671
check_access(ctx);
672
673
- gen_get_gpr(t0, a->rs1);
674
+ gen_get_gpr(ctx, t0, a->rs1);
675
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
676
- gen_set_gpr(a->rd, t1);
677
+ gen_set_gpr(ctx, a->rd, t1);
678
679
tcg_temp_free(t0);
680
tcg_temp_free(t1);
681
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
682
683
check_access(ctx);
684
685
- gen_get_gpr(t0, a->rs1);
686
- gen_get_gpr(dat, a->rs2);
687
+ gen_get_gpr(ctx, t0, a->rs1);
688
+ gen_get_gpr(ctx, dat, a->rs2);
689
690
tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
691
692
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
693
694
check_access(ctx);
695
696
- gen_get_gpr(t0, a->rs1);
697
- gen_get_gpr(dat, a->rs2);
698
+ gen_get_gpr(ctx, t0, a->rs1);
699
+ gen_get_gpr(ctx, dat, a->rs2);
700
701
tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
702
703
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
704
705
check_access(ctx);
706
707
- gen_get_gpr(t0, a->rs1);
708
- gen_get_gpr(dat, a->rs2);
709
+ gen_get_gpr(ctx, t0, a->rs1);
710
+ gen_get_gpr(ctx, dat, a->rs2);
711
712
tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
713
714
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
715
716
check_access(ctx);
717
718
- gen_get_gpr(t0, a->rs1);
719
+ gen_get_gpr(ctx, t0, a->rs1);
720
721
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
722
- gen_set_gpr(a->rd, t1);
723
+ gen_set_gpr(ctx, a->rd, t1);
724
725
tcg_temp_free(t0);
726
tcg_temp_free(t1);
727
@@ -XXX,XX +XXX,XX @@ static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
728
729
check_access(ctx);
730
731
- gen_get_gpr(t0, a->rs1);
732
+ gen_get_gpr(ctx, t0, a->rs1);
733
734
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
735
- gen_set_gpr(a->rd, t1);
736
+ gen_set_gpr(ctx, a->rd, t1);
737
738
tcg_temp_free(t0);
739
tcg_temp_free(t1);
740
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
741
742
check_access(ctx);
743
744
- gen_get_gpr(t0, a->rs1);
745
- gen_get_gpr(dat, a->rs2);
746
+ gen_get_gpr(ctx, t0, a->rs1);
747
+ gen_get_gpr(ctx, dat, a->rs2);
748
749
tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
750
751
@@ -XXX,XX +XXX,XX @@ static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
752
753
check_access(ctx);
754
755
- gen_get_gpr(t0, a->rs1);
756
+ gen_get_gpr(ctx, t0, a->rs1);
757
758
gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
759
- gen_set_gpr(a->rd, t1);
760
+ gen_set_gpr(ctx, a->rd, t1);
761
762
tcg_temp_free(t0);
763
tcg_temp_free(t1);
764
@@ -XXX,XX +XXX,XX @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
765
766
check_access(ctx);
767
768
- gen_get_gpr(t0, a->rs1);
769
+ gen_get_gpr(ctx, t0, a->rs1);
770
771
gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
772
- gen_set_gpr(a->rd, t1);
773
+ gen_set_gpr(ctx, a->rd, t1);
774
775
tcg_temp_free(t0);
776
tcg_temp_free(t1);
777
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
778
index XXXXXXX..XXXXXXX 100644
779
--- a/target/riscv/insn_trans/trans_rvi.c.inc
780
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
781
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
782
TCGv t0 = tcg_temp_new();
783
784
785
- gen_get_gpr(cpu_pc, a->rs1);
786
+ gen_get_gpr(ctx, cpu_pc, a->rs1);
787
tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
788
tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
789
790
@@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
791
TCGv source1, source2;
792
source1 = tcg_temp_new();
793
source2 = tcg_temp_new();
794
- gen_get_gpr(source1, a->rs1);
795
- gen_get_gpr(source2, a->rs2);
796
+ gen_get_gpr(ctx, source1, a->rs1);
797
+ gen_get_gpr(ctx, source2, a->rs2);
798
799
tcg_gen_brcond_tl(cond, source1, source2, l);
800
gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
801
@@ -XXX,XX +XXX,XX @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
802
{
803
TCGv t0 = tcg_temp_new();
804
TCGv t1 = tcg_temp_new();
805
- gen_get_gpr(t0, a->rs1);
806
+ gen_get_gpr(ctx, t0, a->rs1);
807
tcg_gen_addi_tl(t0, t0, a->imm);
808
809
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
810
- gen_set_gpr(a->rd, t1);
811
+ gen_set_gpr(ctx, a->rd, t1);
812
tcg_temp_free(t0);
813
tcg_temp_free(t1);
814
return true;
815
@@ -XXX,XX +XXX,XX @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
816
{
817
TCGv t0 = tcg_temp_new();
818
TCGv dat = tcg_temp_new();
819
- gen_get_gpr(t0, a->rs1);
820
+ gen_get_gpr(ctx, t0, a->rs1);
821
tcg_gen_addi_tl(t0, t0, a->imm);
822
- gen_get_gpr(dat, a->rs2);
823
+ gen_get_gpr(ctx, dat, a->rs2);
824
825
tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
826
tcg_temp_free(t0);
827
@@ -XXX,XX +XXX,XX @@ static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
828
{
829
REQUIRE_64BIT(ctx);
830
TCGv t = tcg_temp_new();
831
- gen_get_gpr(t, a->rs1);
832
+ gen_get_gpr(ctx, t, a->rs1);
833
tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
834
/* sign-extend for W instructions */
835
tcg_gen_ext32s_tl(t, t);
836
- gen_set_gpr(a->rd, t);
837
+ gen_set_gpr(ctx, a->rd, t);
838
tcg_temp_free(t);
839
return true;
840
}
841
@@ -XXX,XX +XXX,XX @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
842
{
843
REQUIRE_64BIT(ctx);
844
TCGv t = tcg_temp_new();
845
- gen_get_gpr(t, a->rs1);
846
+ gen_get_gpr(ctx, t, a->rs1);
847
tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
848
- gen_set_gpr(a->rd, t);
849
+ gen_set_gpr(ctx, a->rd, t);
850
tcg_temp_free(t);
851
return true;
852
}
853
@@ -XXX,XX +XXX,XX @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
854
TCGv source1 = tcg_temp_new();
855
TCGv source2 = tcg_temp_new();
856
857
- gen_get_gpr(source1, a->rs1);
858
- gen_get_gpr(source2, a->rs2);
859
+ gen_get_gpr(ctx, source1, a->rs1);
860
+ gen_get_gpr(ctx, source2, a->rs2);
861
862
tcg_gen_andi_tl(source2, source2, 0x1F);
863
tcg_gen_shl_tl(source1, source1, source2);
864
865
tcg_gen_ext32s_tl(source1, source1);
866
- gen_set_gpr(a->rd, source1);
867
+ gen_set_gpr(ctx, a->rd, source1);
868
tcg_temp_free(source1);
869
tcg_temp_free(source2);
870
return true;
871
@@ -XXX,XX +XXX,XX @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
872
TCGv source1 = tcg_temp_new();
873
TCGv source2 = tcg_temp_new();
874
875
- gen_get_gpr(source1, a->rs1);
876
- gen_get_gpr(source2, a->rs2);
877
+ gen_get_gpr(ctx, source1, a->rs1);
878
+ gen_get_gpr(ctx, source2, a->rs2);
879
880
/* clear upper 32 */
881
tcg_gen_ext32u_tl(source1, source1);
882
@@ -XXX,XX +XXX,XX @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
883
tcg_gen_shr_tl(source1, source1, source2);
884
885
tcg_gen_ext32s_tl(source1, source1);
886
- gen_set_gpr(a->rd, source1);
887
+ gen_set_gpr(ctx, a->rd, source1);
888
tcg_temp_free(source1);
889
tcg_temp_free(source2);
890
return true;
891
@@ -XXX,XX +XXX,XX @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
892
TCGv source1 = tcg_temp_new();
893
TCGv source2 = tcg_temp_new();
894
895
- gen_get_gpr(source1, a->rs1);
896
- gen_get_gpr(source2, a->rs2);
897
+ gen_get_gpr(ctx, source1, a->rs1);
898
+ gen_get_gpr(ctx, source2, a->rs2);
899
900
/*
901
* first, trick to get it to act like working on 32 bits (get rid of
902
@@ -XXX,XX +XXX,XX @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
903
tcg_gen_andi_tl(source2, source2, 0x1F);
904
tcg_gen_sar_tl(source1, source1, source2);
905
906
- gen_set_gpr(a->rd, source1);
907
+ gen_set_gpr(ctx, a->rd, source1);
908
tcg_temp_free(source1);
909
tcg_temp_free(source2);
910
911
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
912
csr_store = tcg_temp_new(); \
913
dest = tcg_temp_new(); \
914
rs1_pass = tcg_temp_new(); \
915
- gen_get_gpr(source1, a->rs1); \
916
+ gen_get_gpr(ctx, source1, a->rs1); \
917
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
918
tcg_gen_movi_tl(rs1_pass, a->rs1); \
919
tcg_gen_movi_tl(csr_store, a->csr); \
920
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
921
} while (0)
922
923
#define RISCV_OP_CSR_POST do {\
924
- gen_set_gpr(a->rd, dest); \
925
+ gen_set_gpr(ctx, a->rd, dest); \
926
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
927
exit_tb(ctx); \
928
ctx->base.is_jmp = DISAS_NORETURN; \
929
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
930
index XXXXXXX..XXXXXXX 100644
931
--- a/target/riscv/insn_trans/trans_rvm.c.inc
932
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
933
@@ -XXX,XX +XXX,XX @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
934
REQUIRE_EXT(ctx, RVM);
935
TCGv source1 = tcg_temp_new();
936
TCGv source2 = tcg_temp_new();
937
- gen_get_gpr(source1, a->rs1);
938
- gen_get_gpr(source2, a->rs2);
939
+ gen_get_gpr(ctx, source1, a->rs1);
940
+ gen_get_gpr(ctx, source2, a->rs2);
941
942
tcg_gen_muls2_tl(source2, source1, source1, source2);
943
944
- gen_set_gpr(a->rd, source1);
945
+ gen_set_gpr(ctx, a->rd, source1);
946
tcg_temp_free(source1);
947
tcg_temp_free(source2);
948
return true;
949
@@ -XXX,XX +XXX,XX @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
950
REQUIRE_EXT(ctx, RVM);
951
TCGv source1 = tcg_temp_new();
952
TCGv source2 = tcg_temp_new();
953
- gen_get_gpr(source1, a->rs1);
954
- gen_get_gpr(source2, a->rs2);
955
+ gen_get_gpr(ctx, source1, a->rs1);
956
+ gen_get_gpr(ctx, source2, a->rs2);
957
958
tcg_gen_mulu2_tl(source2, source1, source1, source2);
959
960
- gen_set_gpr(a->rd, source1);
961
+ gen_set_gpr(ctx, a->rd, source1);
962
tcg_temp_free(source1);
963
tcg_temp_free(source2);
964
return true;
965
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
966
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
967
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
968
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
969
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
970
s1 = tcg_constant_tl(RV_VLEN_MAX);
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
971
} else {
24
}
972
s1 = tcg_temp_new();
25
973
- gen_get_gpr(s1, a->rs1);
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
974
+ gen_get_gpr(ctx, s1, a->rs1);
27
- gen_helper_opivx *fn)
975
}
28
-{
976
- gen_get_gpr(s2, a->rs2);
29
- if (opivx_widen_check(s, a)) {
977
+ gen_get_gpr(ctx, s2, a->rs2);
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
978
gen_helper_vsetvl(dst, cpu_env, s1, s2);
31
- }
979
- gen_set_gpr(a->rd, dst);
32
- return false;
980
+ gen_set_gpr(ctx, a->rd, dst);
33
-}
981
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
34
-
982
lookup_and_goto_ptr(ctx);
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
983
ctx->base.is_jmp = DISAS_NORETURN;
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
984
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
37
-{ \
985
s1 = tcg_constant_tl(RV_VLEN_MAX);
38
- static gen_helper_opivx * const fns[3] = { \
986
} else {
39
- gen_helper_##NAME##_b, \
987
s1 = tcg_temp_new();
40
- gen_helper_##NAME##_h, \
988
- gen_get_gpr(s1, a->rs1);
41
- gen_helper_##NAME##_w \
989
+ gen_get_gpr(ctx, s1, a->rs1);
42
- }; \
990
}
43
- return do_opivx_widen(s, a, fns[s->sew]); \
991
gen_helper_vsetvl(dst, cpu_env, s1, s2);
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
992
- gen_set_gpr(a->rd, dst);
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
993
+ gen_set_gpr(ctx, a->rd, dst);
46
+{ \
994
gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
47
+ if (CHECK(s, a)) { \
995
ctx->base.is_jmp = DISAS_NORETURN;
48
+ static gen_helper_opivx * const fns[3] = { \
996
49
+ gen_helper_##NAME##_b, \
997
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
50
+ gen_helper_##NAME##_h, \
998
*/
51
+ gen_helper_##NAME##_w \
999
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
52
+ }; \
1000
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
1001
- gen_get_gpr(base, rs1);
54
+ } \
1002
+ gen_get_gpr(s, base, rs1);
55
+ return false; \
1003
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
56
}
1004
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
57
1005
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
1006
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
1007
stride = tcg_temp_new();
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
1008
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
1009
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
1010
- gen_get_gpr(base, rs1);
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
1011
- gen_get_gpr(stride, rs2);
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
1012
+ gen_get_gpr(s, base, rs1);
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
1013
+ gen_get_gpr(s, stride, rs2);
66
1014
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
67
/* WIDEN OPIVV with WIDEN */
1015
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
1016
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
1017
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
1018
base = tcg_temp_new();
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
1019
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
1020
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
1021
- gen_get_gpr(base, rs1);
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
1022
+ gen_get_gpr(s, base, rs1);
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
1023
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
1024
tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
1025
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
1026
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
79
1027
base = tcg_temp_new();
80
/* Vector Single-Width Integer Multiply-Add Instructions */
1028
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
1029
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
1030
- gen_get_gpr(base, rs1);
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
1031
+ gen_get_gpr(s, base, rs1);
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
1032
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
1033
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
1034
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
1035
@@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
1036
base = tcg_temp_new();
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
1037
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
1038
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
1039
- gen_get_gpr(base, rs1);
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
1040
+ gen_get_gpr(s, base, rs1);
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
1041
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
94
1042
tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
95
/* Vector Integer Merge and Move Instructions */
1043
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
1044
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
1045
mask = tcg_temp_new_ptr();
1046
src2 = tcg_temp_new_ptr();
1047
src1 = tcg_temp_new();
1048
- gen_get_gpr(src1, rs1);
1049
+ gen_get_gpr(s, src1, rs1);
1050
1051
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
1052
data = FIELD_DP32(data, VDATA, VM, vm);
1053
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
1054
TCGv_i64 src1 = tcg_temp_new_i64();
1055
TCGv tmp = tcg_temp_new();
1056
1057
- gen_get_gpr(tmp, a->rs1);
1058
+ gen_get_gpr(s, tmp, a->rs1);
1059
tcg_gen_ext_tl_i64(src1, tmp);
1060
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
1061
src1, MAXSZ(s), MAXSZ(s));
1062
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
1063
TCGv_i32 src1 = tcg_temp_new_i32();
1064
TCGv tmp = tcg_temp_new();
1065
1066
- gen_get_gpr(tmp, a->rs1);
1067
+ gen_get_gpr(s, tmp, a->rs1);
1068
tcg_gen_trunc_tl_i32(src1, tmp);
1069
tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
1070
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
1071
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
1072
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
1073
1074
s1 = tcg_temp_new();
1075
- gen_get_gpr(s1, a->rs1);
1076
+ gen_get_gpr(s, s1, a->rs1);
1077
1078
if (s->vl_eq_vlmax) {
1079
tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
1080
@@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
1081
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
1082
1083
gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
1084
- gen_set_gpr(a->rd, dst);
1085
+ gen_set_gpr(s, a->rd, dst);
1086
1087
tcg_temp_free_ptr(mask);
1088
tcg_temp_free_ptr(src2);
1089
@@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
1090
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
1091
1092
gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
1093
- gen_set_gpr(a->rd, dst);
1094
+ gen_set_gpr(s, a->rd, dst);
1095
1096
tcg_temp_free_ptr(mask);
1097
tcg_temp_free_ptr(src2);
1098
@@ -XXX,XX +XXX,XX @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
1099
vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
1100
}
1101
tcg_gen_trunc_i64_tl(dest, tmp);
1102
- gen_set_gpr(a->rd, dest);
1103
+ gen_set_gpr(s, a->rd, dest);
1104
1105
tcg_temp_free(dest);
1106
tcg_temp_free_i64(tmp);
1107
--
97
--
1108
2.31.1
98
2.41.0
1109
1110
1111
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
These operations are greatly simplified by ctx->w, which allows
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
us to fold gen_shiftw into gen_shift. Split gen_shifti into
4
This ensures they can be used by both vector and vector-crypto helpers
5
gen_shift_imm_{fn,tl} like we do for gen_arith_imm_{fn,tl}.
5
(latter implemented in proceeding commits).
6
6
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-id: 20210823195529.560295-13-richard.henderson@linaro.org
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
target/riscv/translate.c | 110 +++++++++-----------
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
14
target/riscv/insn_trans/trans_rvb.c.inc | 129 +++++++++++-------------
14
target/riscv/vector_helper.c | 42 ------------------------------
15
target/riscv/insn_trans/trans_rvi.c.inc | 88 ++++------------
15
2 files changed, 46 insertions(+), 42 deletions(-)
16
3 files changed, 125 insertions(+), 202 deletions(-)
17
16
18
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/translate.c
19
--- a/target/riscv/vector_internals.h
21
+++ b/target/riscv/translate.c
20
+++ b/target/riscv/vector_internals.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool is_32bit(DisasContext *ctx)
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
23
}
22
/* expand macro args before macro */
24
#endif
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
25
24
26
+/* The word size for this operation. */
25
+/* (TD, T2, TX2) */
27
+static inline int oper_len(DisasContext *ctx)
26
+#define OP_UU_B uint8_t, uint8_t, uint8_t
28
+{
27
+#define OP_UU_H uint16_t, uint16_t, uint16_t
29
+ return ctx->w ? 32 : TARGET_LONG_BITS;
28
+#define OP_UU_W uint32_t, uint32_t, uint32_t
29
+#define OP_UU_D uint64_t, uint64_t, uint64_t
30
+
31
/* (TD, T1, T2, TX1, TX2) */
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
35
#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
36
37
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
38
+static void do_##NAME(void *vd, void *vs2, int i) \
39
+{ \
40
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
41
+ *((TD *)vd + HD(i)) = OP(s2); \
30
+}
42
+}
31
+
43
+
44
+#define GEN_VEXT_V(NAME, ESZ) \
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
46
+ CPURISCVState *env, uint32_t desc) \
47
+{ \
48
+ uint32_t vm = vext_vm(desc); \
49
+ uint32_t vl = env->vl; \
50
+ uint32_t total_elems = \
51
+ vext_get_total_elems(env, desc, ESZ); \
52
+ uint32_t vta = vext_vta(desc); \
53
+ uint32_t vma = vext_vma(desc); \
54
+ uint32_t i; \
55
+ \
56
+ for (i = env->vstart; i < vl; i++) { \
57
+ if (!vm && !vext_elem_mask(v0, i)) { \
58
+ /* set masked-off elements to 1s */ \
59
+ vext_set_elems_1s(vd, vma, i * ESZ, \
60
+ (i + 1) * ESZ); \
61
+ continue; \
62
+ } \
63
+ do_##NAME(vd, vs2, i); \
64
+ } \
65
+ env->vstart = 0; \
66
+ /* set tail elements to 1s */ \
67
+ vext_set_elems_1s(vd, vta, vl * ESZ, \
68
+ total_elems * ESZ); \
69
+}
32
+
70
+
33
/*
71
/* operation of two vector elements */
34
* RISC-V requires NaN-boxing of narrower width floating point values.
72
typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
35
* This applies when a 32-bit value is assigned to a 64-bit FP register.
73
36
@@ -XXX,XX +XXX,XX @@ static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
74
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
37
return true;
75
do_##NAME, ESZ); \
38
}
76
}
39
77
40
-static bool gen_shift(DisasContext *ctx, arg_r *a,
78
+/* Three of the widening shortening macros: */
41
- void(*func)(TCGv, TCGv, TCGv))
79
+/* (TD, T1, T2, TX1, TX2) */
42
-{
80
+#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
43
- TCGv source1 = tcg_temp_new();
81
+#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
44
- TCGv source2 = tcg_temp_new();
82
+#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
83
+
84
#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
85
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/riscv/vector_helper.c
88
+++ b/target/riscv/vector_helper.c
89
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
90
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
91
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
92
#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
93
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
94
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
95
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
96
#define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
97
#define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
98
#define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
99
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
100
GEN_VEXT_VF(vfwnmsac_vf_w, 8)
101
102
/* Vector Floating-Point Square-Root Instruction */
103
-/* (TD, T2, TX2) */
104
-#define OP_UU_H uint16_t, uint16_t, uint16_t
105
-#define OP_UU_W uint32_t, uint32_t, uint32_t
106
-#define OP_UU_D uint64_t, uint64_t, uint64_t
45
-
107
-
46
- gen_get_gpr(ctx, source1, a->rs1);
108
#define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
47
- gen_get_gpr(ctx, source2, a->rs2);
109
static void do_##NAME(void *vd, void *vs2, int i, \
48
-
110
CPURISCVState *env) \
49
- tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
111
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
50
- (*func)(source1, source1, source2);
112
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
51
-
113
52
- gen_set_gpr(ctx, a->rd, source1);
114
/* Vector Floating-Point Classify Instruction */
53
- tcg_temp_free(source1);
115
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
54
- tcg_temp_free(source2);
116
-static void do_##NAME(void *vd, void *vs2, int i) \
55
- return true;
117
-{ \
118
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
119
- *((TD *)vd + HD(i)) = OP(s2); \
56
-}
120
-}
57
-
121
-
58
-static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
122
-#define GEN_VEXT_V(NAME, ESZ) \
59
+static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
60
+ void (*func)(TCGv, TCGv, target_long))
124
- CPURISCVState *env, uint32_t desc) \
61
{
125
-{ \
62
- DisasContext *ctx = container_of(dcbase, DisasContext, base);
126
- uint32_t vm = vext_vm(desc); \
63
- CPUState *cpu = ctx->cs;
127
- uint32_t vl = env->vl; \
64
- CPURISCVState *env = cpu->env_ptr;
128
- uint32_t total_elems = \
65
+ TCGv dest, src1;
129
- vext_get_total_elems(env, desc, ESZ); \
66
+ int max_len = oper_len(ctx);
130
- uint32_t vta = vext_vta(desc); \
67
131
- uint32_t vma = vext_vma(desc); \
68
- return cpu_ldl_code(env, pc);
132
- uint32_t i; \
133
- \
134
- for (i = env->vstart; i < vl; i++) { \
135
- if (!vm && !vext_elem_mask(v0, i)) { \
136
- /* set masked-off elements to 1s */ \
137
- vext_set_elems_1s(vd, vma, i * ESZ, \
138
- (i + 1) * ESZ); \
139
- continue; \
140
- } \
141
- do_##NAME(vd, vs2, i); \
142
- } \
143
- env->vstart = 0; \
144
- /* set tail elements to 1s */ \
145
- vext_set_elems_1s(vd, vta, vl * ESZ, \
146
- total_elems * ESZ); \
69
-}
147
-}
70
-
148
-
71
-static bool gen_shifti(DisasContext *ctx, arg_shift *a,
149
target_ulong fclass_h(uint64_t frs1)
72
- void(*func)(TCGv, TCGv, TCGv))
73
-{
74
- if (a->shamt >= TARGET_LONG_BITS) {
75
+ if (a->shamt >= max_len) {
76
return false;
77
}
78
79
- TCGv source1 = tcg_temp_new();
80
- TCGv source2 = tcg_temp_new();
81
-
82
- gen_get_gpr(ctx, source1, a->rs1);
83
+ dest = dest_gpr(ctx, a->rd);
84
+ src1 = get_gpr(ctx, a->rs1, ext);
85
86
- tcg_gen_movi_tl(source2, a->shamt);
87
- (*func)(source1, source1, source2);
88
+ func(dest, src1, a->shamt);
89
90
- gen_set_gpr(ctx, a->rd, source1);
91
- tcg_temp_free(source1);
92
- tcg_temp_free(source2);
93
+ gen_set_gpr(ctx, a->rd, dest);
94
return true;
95
}
96
97
-static bool gen_shiftw(DisasContext *ctx, arg_r *a,
98
- void(*func)(TCGv, TCGv, TCGv))
99
+static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
100
+ void (*func)(TCGv, TCGv, TCGv))
101
{
150
{
102
- TCGv source1 = tcg_temp_new();
151
float16 f = frs1;
103
- TCGv source2 = tcg_temp_new();
104
+ TCGv dest, src1, src2;
105
+ int max_len = oper_len(ctx);
106
+
107
+ if (a->shamt >= max_len) {
108
+ return false;
109
+ }
110
111
- gen_get_gpr(ctx, source1, a->rs1);
112
- gen_get_gpr(ctx, source2, a->rs2);
113
+ dest = dest_gpr(ctx, a->rd);
114
+ src1 = get_gpr(ctx, a->rs1, ext);
115
+ src2 = tcg_constant_tl(a->shamt);
116
117
- tcg_gen_andi_tl(source2, source2, 31);
118
- (*func)(source1, source1, source2);
119
- tcg_gen_ext32s_tl(source1, source1);
120
+ func(dest, src1, src2);
121
122
- gen_set_gpr(ctx, a->rd, source1);
123
- tcg_temp_free(source1);
124
- tcg_temp_free(source2);
125
+ gen_set_gpr(ctx, a->rd, dest);
126
return true;
127
}
128
129
-static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
130
- void(*func)(TCGv, TCGv, TCGv))
131
+static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
132
+ void (*func)(TCGv, TCGv, TCGv))
133
{
134
- TCGv source1 = tcg_temp_new();
135
- TCGv source2 = tcg_temp_new();
136
-
137
- gen_get_gpr(ctx, source1, a->rs1);
138
- tcg_gen_movi_tl(source2, a->shamt);
139
+ TCGv dest = dest_gpr(ctx, a->rd);
140
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
141
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
142
+ TCGv ext2 = tcg_temp_new();
143
144
- (*func)(source1, source1, source2);
145
- tcg_gen_ext32s_tl(source1, source1);
146
+ tcg_gen_andi_tl(ext2, src2, oper_len(ctx) - 1);
147
+ func(dest, src1, ext2);
148
149
- gen_set_gpr(ctx, a->rd, source1);
150
- tcg_temp_free(source1);
151
- tcg_temp_free(source2);
152
+ gen_set_gpr(ctx, a->rd, dest);
153
+ tcg_temp_free(ext2);
154
return true;
155
}
156
157
@@ -XXX,XX +XXX,XX @@ static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
158
return true;
159
}
160
161
+static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
162
+{
163
+ DisasContext *ctx = container_of(dcbase, DisasContext, base);
164
+ CPUState *cpu = ctx->cs;
165
+ CPURISCVState *env = cpu->env_ptr;
166
+
167
+ return cpu_ldl_code(env, pc);
168
+}
169
+
170
/* Include insn module translation function */
171
#include "insn_trans/trans_rvi.c.inc"
172
#include "insn_trans/trans_rvm.c.inc"
173
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/insn_trans/trans_rvb.c.inc
176
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
177
@@ -XXX,XX +XXX,XX @@ static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
178
static bool trans_bset(DisasContext *ctx, arg_bset *a)
179
{
180
REQUIRE_EXT(ctx, RVB);
181
- return gen_shift(ctx, a, gen_bset);
182
+ return gen_shift(ctx, a, EXT_NONE, gen_bset);
183
}
184
185
static bool trans_bseti(DisasContext *ctx, arg_bseti *a)
186
{
187
REQUIRE_EXT(ctx, RVB);
188
- return gen_shifti(ctx, a, gen_bset);
189
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bset);
190
}
191
192
static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
193
@@ -XXX,XX +XXX,XX @@ static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
194
static bool trans_bclr(DisasContext *ctx, arg_bclr *a)
195
{
196
REQUIRE_EXT(ctx, RVB);
197
- return gen_shift(ctx, a, gen_bclr);
198
+ return gen_shift(ctx, a, EXT_NONE, gen_bclr);
199
}
200
201
static bool trans_bclri(DisasContext *ctx, arg_bclri *a)
202
{
203
REQUIRE_EXT(ctx, RVB);
204
- return gen_shifti(ctx, a, gen_bclr);
205
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bclr);
206
}
207
208
static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
209
@@ -XXX,XX +XXX,XX @@ static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
210
static bool trans_binv(DisasContext *ctx, arg_binv *a)
211
{
212
REQUIRE_EXT(ctx, RVB);
213
- return gen_shift(ctx, a, gen_binv);
214
+ return gen_shift(ctx, a, EXT_NONE, gen_binv);
215
}
216
217
static bool trans_binvi(DisasContext *ctx, arg_binvi *a)
218
{
219
REQUIRE_EXT(ctx, RVB);
220
- return gen_shifti(ctx, a, gen_binv);
221
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_binv);
222
}
223
224
static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
225
@@ -XXX,XX +XXX,XX @@ static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
226
static bool trans_bext(DisasContext *ctx, arg_bext *a)
227
{
228
REQUIRE_EXT(ctx, RVB);
229
- return gen_shift(ctx, a, gen_bext);
230
+ return gen_shift(ctx, a, EXT_NONE, gen_bext);
231
}
232
233
static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
234
{
235
REQUIRE_EXT(ctx, RVB);
236
- return gen_shifti(ctx, a, gen_bext);
237
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
238
}
239
240
static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
241
@@ -XXX,XX +XXX,XX @@ static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
242
static bool trans_slo(DisasContext *ctx, arg_slo *a)
243
{
244
REQUIRE_EXT(ctx, RVB);
245
- return gen_shift(ctx, a, gen_slo);
246
+ return gen_shift(ctx, a, EXT_NONE, gen_slo);
247
}
248
249
static bool trans_sloi(DisasContext *ctx, arg_sloi *a)
250
{
251
REQUIRE_EXT(ctx, RVB);
252
- return gen_shifti(ctx, a, gen_slo);
253
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_slo);
254
}
255
256
static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
257
@@ -XXX,XX +XXX,XX @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
258
static bool trans_sro(DisasContext *ctx, arg_sro *a)
259
{
260
REQUIRE_EXT(ctx, RVB);
261
- return gen_shift(ctx, a, gen_sro);
262
+ return gen_shift(ctx, a, EXT_ZERO, gen_sro);
263
}
264
265
static bool trans_sroi(DisasContext *ctx, arg_sroi *a)
266
{
267
REQUIRE_EXT(ctx, RVB);
268
- return gen_shifti(ctx, a, gen_sro);
269
+ return gen_shift_imm_tl(ctx, a, EXT_ZERO, gen_sro);
270
}
271
272
static bool trans_ror(DisasContext *ctx, arg_ror *a)
273
{
274
REQUIRE_EXT(ctx, RVB);
275
- return gen_shift(ctx, a, tcg_gen_rotr_tl);
276
+ return gen_shift(ctx, a, EXT_NONE, tcg_gen_rotr_tl);
277
}
278
279
static bool trans_rori(DisasContext *ctx, arg_rori *a)
280
{
281
REQUIRE_EXT(ctx, RVB);
282
- return gen_shifti(ctx, a, tcg_gen_rotr_tl);
283
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_rotri_tl);
284
}
285
286
static bool trans_rol(DisasContext *ctx, arg_rol *a)
287
{
288
REQUIRE_EXT(ctx, RVB);
289
- return gen_shift(ctx, a, tcg_gen_rotl_tl);
290
+ return gen_shift(ctx, a, EXT_NONE, tcg_gen_rotl_tl);
291
}
292
293
static bool trans_grev(DisasContext *ctx, arg_grev *a)
294
{
295
REQUIRE_EXT(ctx, RVB);
296
- return gen_shift(ctx, a, gen_helper_grev);
297
+ return gen_shift(ctx, a, EXT_NONE, gen_helper_grev);
298
}
299
300
-static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
301
+static void gen_grevi(TCGv dest, TCGv src, target_long shamt)
302
{
303
- TCGv source1 = tcg_temp_new();
304
- TCGv source2;
305
-
306
- gen_get_gpr(ctx, source1, a->rs1);
307
-
308
- if (a->shamt == (TARGET_LONG_BITS - 8)) {
309
+ if (shamt == TARGET_LONG_BITS - 8) {
310
/* rev8, byte swaps */
311
- tcg_gen_bswap_tl(source1, source1);
312
+ tcg_gen_bswap_tl(dest, src);
313
} else {
314
- source2 = tcg_temp_new();
315
- tcg_gen_movi_tl(source2, a->shamt);
316
- gen_helper_grev(source1, source1, source2);
317
- tcg_temp_free(source2);
318
+ gen_helper_grev(dest, src, tcg_constant_tl(shamt));
319
}
320
-
321
- gen_set_gpr(ctx, a->rd, source1);
322
- tcg_temp_free(source1);
323
- return true;
324
}
325
326
static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
327
{
328
REQUIRE_EXT(ctx, RVB);
329
-
330
- if (a->shamt >= TARGET_LONG_BITS) {
331
- return false;
332
- }
333
-
334
- return gen_grevi(ctx, a);
335
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_grevi);
336
}
337
338
static bool trans_gorc(DisasContext *ctx, arg_gorc *a)
339
{
340
REQUIRE_EXT(ctx, RVB);
341
- return gen_shift(ctx, a, gen_helper_gorc);
342
+ return gen_shift(ctx, a, EXT_ZERO, gen_helper_gorc);
343
}
344
345
static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
346
{
347
REQUIRE_EXT(ctx, RVB);
348
- return gen_shifti(ctx, a, gen_helper_gorc);
349
+ return gen_shift_imm_tl(ctx, a, EXT_ZERO, gen_helper_gorc);
350
}
351
352
#define GEN_SHADD(SHAMT) \
353
@@ -XXX,XX +XXX,XX @@ static bool trans_bsetw(DisasContext *ctx, arg_bsetw *a)
354
{
355
REQUIRE_64BIT(ctx);
356
REQUIRE_EXT(ctx, RVB);
357
- return gen_shiftw(ctx, a, gen_bset);
358
+ ctx->w = true;
359
+ return gen_shift(ctx, a, EXT_NONE, gen_bset);
360
}
361
362
static bool trans_bsetiw(DisasContext *ctx, arg_bsetiw *a)
363
{
364
REQUIRE_64BIT(ctx);
365
REQUIRE_EXT(ctx, RVB);
366
- return gen_shiftiw(ctx, a, gen_bset);
367
+ ctx->w = true;
368
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bset);
369
}
370
371
static bool trans_bclrw(DisasContext *ctx, arg_bclrw *a)
372
{
373
REQUIRE_64BIT(ctx);
374
REQUIRE_EXT(ctx, RVB);
375
- return gen_shiftw(ctx, a, gen_bclr);
376
+ ctx->w = true;
377
+ return gen_shift(ctx, a, EXT_NONE, gen_bclr);
378
}
379
380
static bool trans_bclriw(DisasContext *ctx, arg_bclriw *a)
381
{
382
REQUIRE_64BIT(ctx);
383
REQUIRE_EXT(ctx, RVB);
384
- return gen_shiftiw(ctx, a, gen_bclr);
385
+ ctx->w = true;
386
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bclr);
387
}
388
389
static bool trans_binvw(DisasContext *ctx, arg_binvw *a)
390
{
391
REQUIRE_64BIT(ctx);
392
REQUIRE_EXT(ctx, RVB);
393
- return gen_shiftw(ctx, a, gen_binv);
394
+ ctx->w = true;
395
+ return gen_shift(ctx, a, EXT_NONE, gen_binv);
396
}
397
398
static bool trans_binviw(DisasContext *ctx, arg_binviw *a)
399
{
400
REQUIRE_64BIT(ctx);
401
REQUIRE_EXT(ctx, RVB);
402
- return gen_shiftiw(ctx, a, gen_binv);
403
+ ctx->w = true;
404
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_binv);
405
}
406
407
static bool trans_bextw(DisasContext *ctx, arg_bextw *a)
408
{
409
REQUIRE_64BIT(ctx);
410
REQUIRE_EXT(ctx, RVB);
411
- return gen_shiftw(ctx, a, gen_bext);
412
+ ctx->w = true;
413
+ return gen_shift(ctx, a, EXT_NONE, gen_bext);
414
}
415
416
static bool trans_slow(DisasContext *ctx, arg_slow *a)
417
{
418
REQUIRE_64BIT(ctx);
419
REQUIRE_EXT(ctx, RVB);
420
- return gen_shiftw(ctx, a, gen_slo);
421
+ ctx->w = true;
422
+ return gen_shift(ctx, a, EXT_NONE, gen_slo);
423
}
424
425
static bool trans_sloiw(DisasContext *ctx, arg_sloiw *a)
426
{
427
REQUIRE_64BIT(ctx);
428
REQUIRE_EXT(ctx, RVB);
429
- return gen_shiftiw(ctx, a, gen_slo);
430
+ ctx->w = true;
431
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_slo);
432
}
433
434
static bool trans_srow(DisasContext *ctx, arg_srow *a)
435
{
436
REQUIRE_64BIT(ctx);
437
REQUIRE_EXT(ctx, RVB);
438
- return gen_shiftw(ctx, a, gen_sro);
439
+ ctx->w = true;
440
+ return gen_shift(ctx, a, EXT_ZERO, gen_sro);
441
}
442
443
static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
444
{
445
REQUIRE_64BIT(ctx);
446
REQUIRE_EXT(ctx, RVB);
447
- return gen_shiftiw(ctx, a, gen_sro);
448
+ ctx->w = true;
449
+ return gen_shift_imm_tl(ctx, a, EXT_ZERO, gen_sro);
450
}
451
452
static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
453
@@ -XXX,XX +XXX,XX @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
454
{
455
REQUIRE_64BIT(ctx);
456
REQUIRE_EXT(ctx, RVB);
457
- return gen_shiftw(ctx, a, gen_rorw);
458
+ ctx->w = true;
459
+ return gen_shift(ctx, a, EXT_NONE, gen_rorw);
460
}
461
462
static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
463
{
464
REQUIRE_64BIT(ctx);
465
REQUIRE_EXT(ctx, RVB);
466
- return gen_shiftiw(ctx, a, gen_rorw);
467
+ ctx->w = true;
468
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_rorw);
469
}
470
471
static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
472
@@ -XXX,XX +XXX,XX @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
473
{
474
REQUIRE_64BIT(ctx);
475
REQUIRE_EXT(ctx, RVB);
476
- return gen_shiftw(ctx, a, gen_rolw);
477
-}
478
-
479
-static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
480
-{
481
- tcg_gen_ext32u_tl(arg1, arg1);
482
- gen_helper_grev(ret, arg1, arg2);
483
+ ctx->w = true;
484
+ return gen_shift(ctx, a, EXT_NONE, gen_rolw);
485
}
486
487
static bool trans_grevw(DisasContext *ctx, arg_grevw *a)
488
{
489
REQUIRE_64BIT(ctx);
490
REQUIRE_EXT(ctx, RVB);
491
- return gen_shiftw(ctx, a, gen_grevw);
492
+ ctx->w = true;
493
+ return gen_shift(ctx, a, EXT_ZERO, gen_helper_grev);
494
}
495
496
static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
497
{
498
REQUIRE_64BIT(ctx);
499
REQUIRE_EXT(ctx, RVB);
500
- return gen_shiftiw(ctx, a, gen_grevw);
501
-}
502
-
503
-static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2)
504
-{
505
- tcg_gen_ext32u_tl(arg1, arg1);
506
- gen_helper_gorcw(ret, arg1, arg2);
507
+ ctx->w = true;
508
+ return gen_shift_imm_tl(ctx, a, EXT_ZERO, gen_helper_grev);
509
}
510
511
static bool trans_gorcw(DisasContext *ctx, arg_gorcw *a)
512
{
513
REQUIRE_64BIT(ctx);
514
REQUIRE_EXT(ctx, RVB);
515
- return gen_shiftw(ctx, a, gen_gorcw);
516
+ ctx->w = true;
517
+ return gen_shift(ctx, a, EXT_ZERO, gen_helper_gorc);
518
}
519
520
static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a)
521
{
522
REQUIRE_64BIT(ctx);
523
REQUIRE_EXT(ctx, RVB);
524
- return gen_shiftiw(ctx, a, gen_gorcw);
525
+ ctx->w = true;
526
+ return gen_shift_imm_tl(ctx, a, EXT_ZERO, gen_helper_gorc);
527
}
528
529
#define GEN_SHADD_UW(SHAMT) \
530
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
531
index XXXXXXX..XXXXXXX 100644
532
--- a/target/riscv/insn_trans/trans_rvi.c.inc
533
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
534
@@ -XXX,XX +XXX,XX @@ static bool trans_andi(DisasContext *ctx, arg_andi *a)
535
536
static bool trans_slli(DisasContext *ctx, arg_slli *a)
537
{
538
- return gen_shifti(ctx, a, tcg_gen_shl_tl);
539
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
540
}
541
542
static bool trans_srli(DisasContext *ctx, arg_srli *a)
543
{
544
- return gen_shifti(ctx, a, tcg_gen_shr_tl);
545
+ return gen_shift_imm_fn(ctx, a, EXT_ZERO, tcg_gen_shri_tl);
546
}
547
548
static bool trans_srai(DisasContext *ctx, arg_srai *a)
549
{
550
- return gen_shifti(ctx, a, tcg_gen_sar_tl);
551
+ return gen_shift_imm_fn(ctx, a, EXT_SIGN, tcg_gen_sari_tl);
552
}
553
554
static bool trans_add(DisasContext *ctx, arg_add *a)
555
@@ -XXX,XX +XXX,XX @@ static bool trans_sub(DisasContext *ctx, arg_sub *a)
556
557
static bool trans_sll(DisasContext *ctx, arg_sll *a)
558
{
559
- return gen_shift(ctx, a, &tcg_gen_shl_tl);
560
+ return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl);
561
}
562
563
static bool trans_slt(DisasContext *ctx, arg_slt *a)
564
@@ -XXX,XX +XXX,XX @@ static bool trans_xor(DisasContext *ctx, arg_xor *a)
565
566
static bool trans_srl(DisasContext *ctx, arg_srl *a)
567
{
568
- return gen_shift(ctx, a, &tcg_gen_shr_tl);
569
+ return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl);
570
}
571
572
static bool trans_sra(DisasContext *ctx, arg_sra *a)
573
{
574
- return gen_shift(ctx, a, &tcg_gen_sar_tl);
575
+ return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl);
576
}
577
578
static bool trans_or(DisasContext *ctx, arg_or *a)
579
@@ -XXX,XX +XXX,XX @@ static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
580
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
581
{
582
REQUIRE_64BIT(ctx);
583
- return gen_shiftiw(ctx, a, tcg_gen_shl_tl);
584
+ ctx->w = true;
585
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
586
}
587
588
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
589
{
590
REQUIRE_64BIT(ctx);
591
- TCGv t = tcg_temp_new();
592
- gen_get_gpr(ctx, t, a->rs1);
593
- tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
594
- /* sign-extend for W instructions */
595
- tcg_gen_ext32s_tl(t, t);
596
- gen_set_gpr(ctx, a->rd, t);
597
- tcg_temp_free(t);
598
- return true;
599
+ ctx->w = true;
600
+ return gen_shift_imm_fn(ctx, a, EXT_ZERO, tcg_gen_shri_tl);
601
}
602
603
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
604
{
605
REQUIRE_64BIT(ctx);
606
- TCGv t = tcg_temp_new();
607
- gen_get_gpr(ctx, t, a->rs1);
608
- tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
609
- gen_set_gpr(ctx, a->rd, t);
610
- tcg_temp_free(t);
611
- return true;
612
+ ctx->w = true;
613
+ return gen_shift_imm_fn(ctx, a, EXT_SIGN, tcg_gen_sari_tl);
614
}
615
616
static bool trans_addw(DisasContext *ctx, arg_addw *a)
617
@@ -XXX,XX +XXX,XX @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
618
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
619
{
620
REQUIRE_64BIT(ctx);
621
- TCGv source1 = tcg_temp_new();
622
- TCGv source2 = tcg_temp_new();
623
-
624
- gen_get_gpr(ctx, source1, a->rs1);
625
- gen_get_gpr(ctx, source2, a->rs2);
626
-
627
- tcg_gen_andi_tl(source2, source2, 0x1F);
628
- tcg_gen_shl_tl(source1, source1, source2);
629
-
630
- tcg_gen_ext32s_tl(source1, source1);
631
- gen_set_gpr(ctx, a->rd, source1);
632
- tcg_temp_free(source1);
633
- tcg_temp_free(source2);
634
- return true;
635
+ ctx->w = true;
636
+ return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl);
637
}
638
639
static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
640
{
641
REQUIRE_64BIT(ctx);
642
- TCGv source1 = tcg_temp_new();
643
- TCGv source2 = tcg_temp_new();
644
-
645
- gen_get_gpr(ctx, source1, a->rs1);
646
- gen_get_gpr(ctx, source2, a->rs2);
647
-
648
- /* clear upper 32 */
649
- tcg_gen_ext32u_tl(source1, source1);
650
- tcg_gen_andi_tl(source2, source2, 0x1F);
651
- tcg_gen_shr_tl(source1, source1, source2);
652
-
653
- tcg_gen_ext32s_tl(source1, source1);
654
- gen_set_gpr(ctx, a->rd, source1);
655
- tcg_temp_free(source1);
656
- tcg_temp_free(source2);
657
- return true;
658
+ ctx->w = true;
659
+ return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl);
660
}
661
662
static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
663
{
664
REQUIRE_64BIT(ctx);
665
- TCGv source1 = tcg_temp_new();
666
- TCGv source2 = tcg_temp_new();
667
-
668
- gen_get_gpr(ctx, source1, a->rs1);
669
- gen_get_gpr(ctx, source2, a->rs2);
670
-
671
- /*
672
- * first, trick to get it to act like working on 32 bits (get rid of
673
- * upper 32, sign extend to fill space)
674
- */
675
- tcg_gen_ext32s_tl(source1, source1);
676
- tcg_gen_andi_tl(source2, source2, 0x1F);
677
- tcg_gen_sar_tl(source1, source1, source2);
678
-
679
- gen_set_gpr(ctx, a->rd, source1);
680
- tcg_temp_free(source1);
681
- tcg_temp_free(source2);
682
-
683
- return true;
684
+ ctx->w = true;
685
+ return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl);
686
}
687
688
static bool trans_fence(DisasContext *ctx, arg_fence *a)
689
--
152
--
690
2.31.1
153
2.41.0
691
692
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
Move these helpers near their use by the trans_*
3
This commit adds support for the Zvbb vector-crypto extension, which
4
functions within insn_trans/trans_rvb.c.inc.
4
consists of the following instructions:
5
5
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
* vrol.[vv,vx]
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
* vror.[vv,vx,vi]
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
* vbrev8.v
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
* vrev8.v
10
Message-id: 20210823195529.560295-11-richard.henderson@linaro.org
10
* vandn.[vv,vx]
11
* vbrev.v
12
* vclz.v
13
* vctz.v
14
* vcpop.v
15
* vwsll.[vv,vx,vi]
16
17
Translation functions are defined in
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
19
`target/riscv/vcrypto_helper.c`.
20
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
22
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
23
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
24
[max.chou@sifive.com: Fix imm mode of vror.vi]
25
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
26
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
27
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
28
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
29
Signed-off-by: Max Chou <max.chou@sifive.com>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
[max.chou@sifive.com: Exposed x-zvbb property]
32
Message-ID: <20230711165917.2629866-9-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
34
---
13
target/riscv/translate.c | 233 -----------------------
35
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/insn_trans/trans_rvb.c.inc | 234 ++++++++++++++++++++++++
36
target/riscv/helper.h | 62 +++++++++
15
2 files changed, 234 insertions(+), 233 deletions(-)
37
target/riscv/insn32.decode | 20 +++
38
target/riscv/cpu.c | 12 ++
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
41
6 files changed, 397 insertions(+)
16
42
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
18
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/translate.c
45
--- a/target/riscv/cpu_cfg.h
20
+++ b/target/riscv/translate.c
46
+++ b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
22
return true;
48
bool ext_zve32f;
23
}
49
bool ext_zve64f;
24
50
bool ext_zve64d;
25
-static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
51
+ bool ext_zvbb;
26
-{
52
bool ext_zvbc;
27
- tcg_gen_deposit_tl(ret, arg1, arg2,
53
bool ext_zmmul;
28
- TARGET_LONG_BITS / 2,
54
bool ext_zvfbfmin;
29
- TARGET_LONG_BITS / 2);
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
30
-}
31
-
32
-static void gen_packu(TCGv ret, TCGv arg1, TCGv arg2)
33
-{
34
- TCGv t = tcg_temp_new();
35
- tcg_gen_shri_tl(t, arg1, TARGET_LONG_BITS / 2);
36
- tcg_gen_deposit_tl(ret, arg2, t, 0, TARGET_LONG_BITS / 2);
37
- tcg_temp_free(t);
38
-}
39
-
40
-static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
41
-{
42
- TCGv t = tcg_temp_new();
43
- tcg_gen_ext8u_tl(t, arg2);
44
- tcg_gen_deposit_tl(ret, arg1, t, 8, TARGET_LONG_BITS - 8);
45
- tcg_temp_free(t);
46
-}
47
-
48
-static void gen_sbop_mask(TCGv ret, TCGv shamt)
49
-{
50
- tcg_gen_movi_tl(ret, 1);
51
- tcg_gen_shl_tl(ret, ret, shamt);
52
-}
53
-
54
-static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
55
-{
56
- TCGv t = tcg_temp_new();
57
-
58
- gen_sbop_mask(t, shamt);
59
- tcg_gen_or_tl(ret, arg1, t);
60
-
61
- tcg_temp_free(t);
62
-}
63
-
64
-static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
65
-{
66
- TCGv t = tcg_temp_new();
67
-
68
- gen_sbop_mask(t, shamt);
69
- tcg_gen_andc_tl(ret, arg1, t);
70
-
71
- tcg_temp_free(t);
72
-}
73
-
74
-static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
75
-{
76
- TCGv t = tcg_temp_new();
77
-
78
- gen_sbop_mask(t, shamt);
79
- tcg_gen_xor_tl(ret, arg1, t);
80
-
81
- tcg_temp_free(t);
82
-}
83
-
84
-static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
85
-{
86
- tcg_gen_shr_tl(ret, arg1, shamt);
87
- tcg_gen_andi_tl(ret, ret, 1);
88
-}
89
-
90
-static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
91
-{
92
- tcg_gen_not_tl(ret, arg1);
93
- tcg_gen_shl_tl(ret, ret, arg2);
94
- tcg_gen_not_tl(ret, ret);
95
-}
96
-
97
-static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
98
-{
99
- tcg_gen_not_tl(ret, arg1);
100
- tcg_gen_shr_tl(ret, ret, arg2);
101
- tcg_gen_not_tl(ret, ret);
102
-}
103
-
104
-static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
105
-{
106
- TCGv source1 = tcg_temp_new();
107
- TCGv source2;
108
-
109
- gen_get_gpr(ctx, source1, a->rs1);
110
-
111
- if (a->shamt == (TARGET_LONG_BITS - 8)) {
112
- /* rev8, byte swaps */
113
- tcg_gen_bswap_tl(source1, source1);
114
- } else {
115
- source2 = tcg_temp_new();
116
- tcg_gen_movi_tl(source2, a->shamt);
117
- gen_helper_grev(source1, source1, source2);
118
- tcg_temp_free(source2);
119
- }
120
-
121
- gen_set_gpr(ctx, a->rd, source1);
122
- tcg_temp_free(source1);
123
- return true;
124
-}
125
-
126
-#define GEN_SHADD(SHAMT) \
127
-static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
128
-{ \
129
- TCGv t = tcg_temp_new(); \
130
- \
131
- tcg_gen_shli_tl(t, arg1, SHAMT); \
132
- tcg_gen_add_tl(ret, t, arg2); \
133
- \
134
- tcg_temp_free(t); \
135
-}
136
-
137
-GEN_SHADD(1)
138
-GEN_SHADD(2)
139
-GEN_SHADD(3)
140
-
141
-static void gen_ctzw(TCGv ret, TCGv arg1)
142
-{
143
- tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32));
144
- tcg_gen_ctzi_tl(ret, ret, 64);
145
-}
146
-
147
-static void gen_clzw(TCGv ret, TCGv arg1)
148
-{
149
- tcg_gen_ext32u_tl(ret, arg1);
150
- tcg_gen_clzi_tl(ret, ret, 64);
151
- tcg_gen_subi_tl(ret, ret, 32);
152
-}
153
-
154
-static void gen_cpopw(TCGv ret, TCGv arg1)
155
-{
156
- tcg_gen_ext32u_tl(arg1, arg1);
157
- tcg_gen_ctpop_tl(ret, arg1);
158
-}
159
-
160
-static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
161
-{
162
- TCGv t = tcg_temp_new();
163
- tcg_gen_ext16s_tl(t, arg2);
164
- tcg_gen_deposit_tl(ret, arg1, t, 16, 48);
165
- tcg_temp_free(t);
166
-}
167
-
168
-static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
169
-{
170
- TCGv t = tcg_temp_new();
171
- tcg_gen_shri_tl(t, arg1, 16);
172
- tcg_gen_deposit_tl(ret, arg2, t, 0, 16);
173
- tcg_gen_ext32s_tl(ret, ret);
174
- tcg_temp_free(t);
175
-}
176
-
177
-static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
178
-{
179
- TCGv_i32 t1 = tcg_temp_new_i32();
180
- TCGv_i32 t2 = tcg_temp_new_i32();
181
-
182
- /* truncate to 32-bits */
183
- tcg_gen_trunc_tl_i32(t1, arg1);
184
- tcg_gen_trunc_tl_i32(t2, arg2);
185
-
186
- tcg_gen_rotr_i32(t1, t1, t2);
187
-
188
- /* sign-extend 64-bits */
189
- tcg_gen_ext_i32_tl(ret, t1);
190
-
191
- tcg_temp_free_i32(t1);
192
- tcg_temp_free_i32(t2);
193
-}
194
-
195
-static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
196
-{
197
- TCGv_i32 t1 = tcg_temp_new_i32();
198
- TCGv_i32 t2 = tcg_temp_new_i32();
199
-
200
- /* truncate to 32-bits */
201
- tcg_gen_trunc_tl_i32(t1, arg1);
202
- tcg_gen_trunc_tl_i32(t2, arg2);
203
-
204
- tcg_gen_rotl_i32(t1, t1, t2);
205
-
206
- /* sign-extend 64-bits */
207
- tcg_gen_ext_i32_tl(ret, t1);
208
-
209
- tcg_temp_free_i32(t1);
210
- tcg_temp_free_i32(t2);
211
-}
212
-
213
-static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
214
-{
215
- tcg_gen_ext32u_tl(arg1, arg1);
216
- gen_helper_grev(ret, arg1, arg2);
217
-}
218
-
219
-static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2)
220
-{
221
- tcg_gen_ext32u_tl(arg1, arg1);
222
- gen_helper_gorcw(ret, arg1, arg2);
223
-}
224
-
225
-#define GEN_SHADD_UW(SHAMT) \
226
-static void gen_sh##SHAMT##add_uw(TCGv ret, TCGv arg1, TCGv arg2) \
227
-{ \
228
- TCGv t = tcg_temp_new(); \
229
- \
230
- tcg_gen_ext32u_tl(t, arg1); \
231
- \
232
- tcg_gen_shli_tl(t, t, SHAMT); \
233
- tcg_gen_add_tl(ret, t, arg2); \
234
- \
235
- tcg_temp_free(t); \
236
-}
237
-
238
-GEN_SHADD_UW(1)
239
-GEN_SHADD_UW(2)
240
-GEN_SHADD_UW(3)
241
-
242
-static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
243
-{
244
- tcg_gen_ext32u_tl(arg1, arg1);
245
- tcg_gen_add_tl(ret, arg1, arg2);
246
-}
247
-
248
static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
249
void (*func)(TCGv, TCGv, TCGv))
250
{
251
@@ -XXX,XX +XXX,XX @@ static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
252
return true;
253
}
254
255
-static void gen_ctz(TCGv ret, TCGv arg1)
256
-{
257
- tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
258
-}
259
-
260
-static void gen_clz(TCGv ret, TCGv arg1)
261
-{
262
- tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
263
-}
264
-
265
static bool gen_unary(DisasContext *ctx, arg_r2 *a,
266
void(*func)(TCGv, TCGv))
267
{
268
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
269
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
270
--- a/target/riscv/insn_trans/trans_rvb.c.inc
57
--- a/target/riscv/helper.h
271
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
58
+++ b/target/riscv/helper.h
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
63
+
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
67
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
68
+
69
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
70
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
71
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
72
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
73
+
74
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
75
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
76
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
77
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
78
+
79
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
80
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
81
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
82
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
83
+
84
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
85
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
86
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
87
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
88
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
89
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
90
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
91
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
92
+DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32)
93
+DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32)
94
+DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32)
95
+DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32)
96
+
97
+DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32)
98
+DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32)
99
+DEF_HELPER_5(vclz_v_w, void, ptr, ptr, ptr, env, i32)
100
+DEF_HELPER_5(vclz_v_d, void, ptr, ptr, ptr, env, i32)
101
+DEF_HELPER_5(vctz_v_b, void, ptr, ptr, ptr, env, i32)
102
+DEF_HELPER_5(vctz_v_h, void, ptr, ptr, ptr, env, i32)
103
+DEF_HELPER_5(vctz_v_w, void, ptr, ptr, ptr, env, i32)
104
+DEF_HELPER_5(vctz_v_d, void, ptr, ptr, ptr, env, i32)
105
+DEF_HELPER_5(vcpop_v_b, void, ptr, ptr, ptr, env, i32)
106
+DEF_HELPER_5(vcpop_v_h, void, ptr, ptr, ptr, env, i32)
107
+DEF_HELPER_5(vcpop_v_w, void, ptr, ptr, ptr, env, i32)
108
+DEF_HELPER_5(vcpop_v_d, void, ptr, ptr, ptr, env, i32)
109
+
110
+DEF_HELPER_6(vwsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
111
+DEF_HELPER_6(vwsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
112
+DEF_HELPER_6(vwsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
113
+DEF_HELPER_6(vwsll_vx_b, void, ptr, ptr, tl, ptr, env, i32)
114
+DEF_HELPER_6(vwsll_vx_h, void, ptr, ptr, tl, ptr, env, i32)
115
+DEF_HELPER_6(vwsll_vx_w, void, ptr, ptr, tl, ptr, env, i32)
116
+
117
+DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
118
+DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
119
+DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
120
+DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
121
+DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
122
+DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
123
+DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
124
+DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
125
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn32.decode
128
+++ b/target/riscv/insn32.decode
272
@@ -XXX,XX +XXX,XX @@
129
@@ -XXX,XX +XXX,XX @@
273
* this program. If not, see <http://www.gnu.org/licenses/>.
130
%imm_u 12:s20 !function=ex_shift_12
274
*/
131
%imm_bs 30:2 !function=ex_shift_3
275
132
%imm_rnum 20:4
276
+
133
+%imm_z6 26:1 15:5
277
+static void gen_clz(TCGv ret, TCGv arg1)
134
135
# Argument sets:
136
&empty
137
@@ -XXX,XX +XXX,XX @@
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
149
+
150
+# *** Zvbb vector crypto extension ***
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
167
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/target/riscv/cpu.c
170
+++ b/target/riscv/cpu.c
171
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
172
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
173
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
174
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
175
+ ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
176
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
177
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
178
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
180
return;
181
}
182
183
+ /*
184
+ * In principle Zve*x would also suffice here, were they supported
185
+ * in qemu
186
+ */
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
188
+ error_setg(errp,
189
+ "Vector crypto extensions require V or Zve* extensions");
190
+ return;
191
+ }
192
+
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
195
return;
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
198
199
/* Vector cryptography extensions */
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
202
203
DEFINE_PROP_END_OF_LIST(),
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/riscv/vcrypto_helper.c
207
+++ b/target/riscv/vcrypto_helper.c
208
@@ -XXX,XX +XXX,XX @@
209
#include "qemu/osdep.h"
210
#include "qemu/host-utils.h"
211
#include "qemu/bitops.h"
212
+#include "qemu/bswap.h"
213
#include "cpu.h"
214
#include "exec/memop.h"
215
#include "exec/exec-all.h"
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
217
GEN_VEXT_VV(vclmulh_vv, 8)
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
219
GEN_VEXT_VX(vclmulh_vx, 8)
220
+
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
225
+GEN_VEXT_VV(vror_vv_b, 1)
226
+GEN_VEXT_VV(vror_vv_h, 2)
227
+GEN_VEXT_VV(vror_vv_w, 4)
228
+GEN_VEXT_VV(vror_vv_d, 8)
229
+
230
+RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8)
231
+RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16)
232
+RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32)
233
+RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64)
234
+GEN_VEXT_VX(vror_vx_b, 1)
235
+GEN_VEXT_VX(vror_vx_h, 2)
236
+GEN_VEXT_VX(vror_vx_w, 4)
237
+GEN_VEXT_VX(vror_vx_d, 8)
238
+
239
+RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8)
240
+RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16)
241
+RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32)
242
+RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64)
243
+GEN_VEXT_VV(vrol_vv_b, 1)
244
+GEN_VEXT_VV(vrol_vv_h, 2)
245
+GEN_VEXT_VV(vrol_vv_w, 4)
246
+GEN_VEXT_VV(vrol_vv_d, 8)
247
+
248
+RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8)
249
+RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16)
250
+RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32)
251
+RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64)
252
+GEN_VEXT_VX(vrol_vx_b, 1)
253
+GEN_VEXT_VX(vrol_vx_h, 2)
254
+GEN_VEXT_VX(vrol_vx_w, 4)
255
+GEN_VEXT_VX(vrol_vx_d, 8)
256
+
257
+static uint64_t brev8(uint64_t val)
278
+{
258
+{
279
+ tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
259
+ val = ((val & 0x5555555555555555ull) << 1) |
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
261
+ val = ((val & 0x3333333333333333ull) << 2) |
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
265
+
266
+ return val;
280
+}
267
+}
281
+
268
+
282
static bool trans_clz(DisasContext *ctx, arg_clz *a)
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
283
{
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
284
REQUIRE_EXT(ctx, RVB);
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
285
return gen_unary(ctx, a, gen_clz);
272
+RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8)
286
}
273
+GEN_VEXT_V(vbrev8_v_b, 1)
287
274
+GEN_VEXT_V(vbrev8_v_h, 2)
288
+static void gen_ctz(TCGv ret, TCGv arg1)
275
+GEN_VEXT_V(vbrev8_v_w, 4)
276
+GEN_VEXT_V(vbrev8_v_d, 8)
277
+
278
+#define DO_IDENTITY(a) (a)
279
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
280
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
281
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
282
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
283
+GEN_VEXT_V(vrev8_v_b, 1)
284
+GEN_VEXT_V(vrev8_v_h, 2)
285
+GEN_VEXT_V(vrev8_v_w, 4)
286
+GEN_VEXT_V(vrev8_v_d, 8)
287
+
288
+#define DO_ANDN(a, b) ((a) & ~(b))
289
+RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN)
290
+RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN)
291
+RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN)
292
+RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN)
293
+GEN_VEXT_VV(vandn_vv_b, 1)
294
+GEN_VEXT_VV(vandn_vv_h, 2)
295
+GEN_VEXT_VV(vandn_vv_w, 4)
296
+GEN_VEXT_VV(vandn_vv_d, 8)
297
+
298
+RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN)
299
+RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN)
300
+RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN)
301
+RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN)
302
+GEN_VEXT_VX(vandn_vx_b, 1)
303
+GEN_VEXT_VX(vandn_vx_h, 2)
304
+GEN_VEXT_VX(vandn_vx_w, 4)
305
+GEN_VEXT_VX(vandn_vx_d, 8)
306
+
307
+RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8)
308
+RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16)
309
+RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32)
310
+RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64)
311
+GEN_VEXT_V(vbrev_v_b, 1)
312
+GEN_VEXT_V(vbrev_v_h, 2)
313
+GEN_VEXT_V(vbrev_v_w, 4)
314
+GEN_VEXT_V(vbrev_v_d, 8)
315
+
316
+RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8)
317
+RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16)
318
+RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32)
319
+RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64)
320
+GEN_VEXT_V(vclz_v_b, 1)
321
+GEN_VEXT_V(vclz_v_h, 2)
322
+GEN_VEXT_V(vclz_v_w, 4)
323
+GEN_VEXT_V(vclz_v_d, 8)
324
+
325
+RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8)
326
+RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16)
327
+RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32)
328
+RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64)
329
+GEN_VEXT_V(vctz_v_b, 1)
330
+GEN_VEXT_V(vctz_v_h, 2)
331
+GEN_VEXT_V(vctz_v_w, 4)
332
+GEN_VEXT_V(vctz_v_d, 8)
333
+
334
+RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8)
335
+RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16)
336
+RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32)
337
+RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64)
338
+GEN_VEXT_V(vcpop_v_b, 1)
339
+GEN_VEXT_V(vcpop_v_h, 2)
340
+GEN_VEXT_V(vcpop_v_w, 4)
341
+GEN_VEXT_V(vcpop_v_d, 8)
342
+
343
+#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1)))
344
+RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL)
345
+RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL)
346
+RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL)
347
+GEN_VEXT_VV(vwsll_vv_b, 2)
348
+GEN_VEXT_VV(vwsll_vv_h, 4)
349
+GEN_VEXT_VV(vwsll_vv_w, 8)
350
+
351
+RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL)
352
+RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL)
353
+RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
354
+GEN_VEXT_VX(vwsll_vx_b, 2)
355
+GEN_VEXT_VX(vwsll_vx_h, 4)
356
+GEN_VEXT_VX(vwsll_vx_w, 8)
357
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
358
index XXXXXXX..XXXXXXX 100644
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
362
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
365
+
366
+/*
367
+ * Zvbb
368
+ */
369
+
370
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
371
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
372
+ { \
373
+ if (CHECK(s, a)) { \
374
+ static gen_helper_opivx *const fns[4] = { \
375
+ gen_helper_##OPIVX##_b, \
376
+ gen_helper_##OPIVX##_h, \
377
+ gen_helper_##OPIVX##_w, \
378
+ gen_helper_##OPIVX##_d, \
379
+ }; \
380
+ return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
381
+ IMM_MODE); \
382
+ } \
383
+ return false; \
384
+ }
385
+
386
+#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
387
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
388
+ { \
389
+ if (CHECK(s, a)) { \
390
+ static gen_helper_gvec_4_ptr *const fns[4] = { \
391
+ gen_helper_##NAME##_b, \
392
+ gen_helper_##NAME##_h, \
393
+ gen_helper_##NAME##_w, \
394
+ gen_helper_##NAME##_d, \
395
+ }; \
396
+ return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
397
+ } \
398
+ return false; \
399
+ }
400
+
401
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \
402
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
403
+ { \
404
+ if (CHECK(s, a)) { \
405
+ static gen_helper_opivx *const fns[4] = { \
406
+ gen_helper_##NAME##_b, \
407
+ gen_helper_##NAME##_h, \
408
+ gen_helper_##NAME##_w, \
409
+ gen_helper_##NAME##_d, \
410
+ }; \
411
+ return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
412
+ fns[s->sew]); \
413
+ } \
414
+ return false; \
415
+ }
416
+
417
+static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a)
289
+{
418
+{
290
+ tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
291
+}
420
+}
292
+
421
+
293
static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
294
{
295
REQUIRE_EXT(ctx, RVB);
296
@@ -XXX,XX +XXX,XX @@ static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
297
return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl);
298
}
299
300
+static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
301
+{
423
+{
302
+ tcg_gen_deposit_tl(ret, arg1, arg2,
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
303
+ TARGET_LONG_BITS / 2,
304
+ TARGET_LONG_BITS / 2);
305
+}
425
+}
306
+
426
+
307
static bool trans_pack(DisasContext *ctx, arg_pack *a)
427
+/* vrol.v[vx] */
308
{
428
+GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
309
REQUIRE_EXT(ctx, RVB);
429
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
310
return gen_arith(ctx, a, EXT_NONE, gen_pack);
430
+
311
}
431
+/* vror.v[vxi] */
312
432
+GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
313
+static void gen_packu(TCGv ret, TCGv arg1, TCGv arg2)
433
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvbb_vx_check)
434
+GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri, zvbb_vx_check)
435
+
436
+#define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
437
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
438
+ { \
439
+ if (CHECK(s, a)) { \
440
+ static gen_helper_opivx *const fns[4] = { \
441
+ gen_helper_##NAME##_b, \
442
+ gen_helper_##NAME##_h, \
443
+ gen_helper_##NAME##_w, \
444
+ gen_helper_##NAME##_d, \
445
+ }; \
446
+ return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
447
+ } \
448
+ return false; \
449
+ }
450
+
451
+/* vandn.v[vx] */
452
+GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvbb_vv_check)
453
+GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvbb_vx_check)
454
+
455
+#define GEN_OPIV_TRANS(NAME, CHECK) \
456
+ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
457
+ { \
458
+ if (CHECK(s, a)) { \
459
+ uint32_t data = 0; \
460
+ static gen_helper_gvec_3_ptr *const fns[4] = { \
461
+ gen_helper_##NAME##_b, \
462
+ gen_helper_##NAME##_h, \
463
+ gen_helper_##NAME##_w, \
464
+ gen_helper_##NAME##_d, \
465
+ }; \
466
+ TCGLabel *over = gen_new_label(); \
467
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
468
+ \
469
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
470
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
471
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
472
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
473
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
474
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
475
+ vreg_ofs(s, a->rs2), cpu_env, \
476
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
477
+ data, fns[s->sew]); \
478
+ mark_vs_dirty(s); \
479
+ gen_set_label(over); \
480
+ return true; \
481
+ } \
482
+ return false; \
483
+ }
484
+
485
+static bool zvbb_opiv_check(DisasContext *s, arg_rmr *a)
314
+{
486
+{
315
+ TCGv t = tcg_temp_new();
487
+ return s->cfg_ptr->ext_zvbb == true &&
316
+ tcg_gen_shri_tl(t, arg1, TARGET_LONG_BITS / 2);
488
+ require_rvv(s) &&
317
+ tcg_gen_deposit_tl(ret, arg2, t, 0, TARGET_LONG_BITS / 2);
489
+ vext_check_isa_ill(s) &&
318
+ tcg_temp_free(t);
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
319
+}
491
+}
320
+
492
+
321
static bool trans_packu(DisasContext *ctx, arg_packu *a)
493
+GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check)
322
{
494
+GEN_OPIV_TRANS(vrev8_v, zvbb_opiv_check)
323
REQUIRE_EXT(ctx, RVB);
495
+GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check)
324
return gen_arith(ctx, a, EXT_NONE, gen_packu);
496
+GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check)
325
}
497
+GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check)
326
498
+GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check)
327
+static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
499
+
500
+static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a)
328
+{
501
+{
329
+ TCGv t = tcg_temp_new();
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
330
+ tcg_gen_ext8u_tl(t, arg2);
331
+ tcg_gen_deposit_tl(ret, arg1, t, 8, TARGET_LONG_BITS - 8);
332
+ tcg_temp_free(t);
333
+}
503
+}
334
+
504
+
335
static bool trans_packh(DisasContext *ctx, arg_packh *a)
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
336
{
337
REQUIRE_EXT(ctx, RVB);
338
@@ -XXX,XX +XXX,XX @@ static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
339
return gen_unary(ctx, a, tcg_gen_ext16s_tl);
340
}
341
342
+static void gen_sbop_mask(TCGv ret, TCGv shamt)
343
+{
506
+{
344
+ tcg_gen_movi_tl(ret, 1);
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
345
+ tcg_gen_shl_tl(ret, ret, shamt);
346
+}
508
+}
347
+
509
+
348
+static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
510
+/* OPIVI without GVEC IR */
349
+{
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
350
+ TCGv t = tcg_temp_new();
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
351
+
513
+ { \
352
+ gen_sbop_mask(t, shamt);
514
+ if (CHECK(s, a)) { \
353
+ tcg_gen_or_tl(ret, arg1, t);
515
+ static gen_helper_opivx *const fns[3] = { \
354
+
516
+ gen_helper_##OPIVX##_b, \
355
+ tcg_temp_free(t);
517
+ gen_helper_##OPIVX##_h, \
356
+}
518
+ gen_helper_##OPIVX##_w, \
357
+
519
+ }; \
358
static bool trans_bset(DisasContext *ctx, arg_bset *a)
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
359
{
521
+ IMM_MODE); \
360
REQUIRE_EXT(ctx, RVB);
522
+ } \
361
@@ -XXX,XX +XXX,XX @@ static bool trans_bseti(DisasContext *ctx, arg_bseti *a)
523
+ return false; \
362
return gen_shifti(ctx, a, gen_bset);
524
+ }
363
}
525
+
364
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
365
+static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
366
+{
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
367
+ TCGv t = tcg_temp_new();
368
+
369
+ gen_sbop_mask(t, shamt);
370
+ tcg_gen_andc_tl(ret, arg1, t);
371
+
372
+ tcg_temp_free(t);
373
+}
374
+
375
static bool trans_bclr(DisasContext *ctx, arg_bclr *a)
376
{
377
REQUIRE_EXT(ctx, RVB);
378
@@ -XXX,XX +XXX,XX @@ static bool trans_bclri(DisasContext *ctx, arg_bclri *a)
379
return gen_shifti(ctx, a, gen_bclr);
380
}
381
382
+static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
383
+{
384
+ TCGv t = tcg_temp_new();
385
+
386
+ gen_sbop_mask(t, shamt);
387
+ tcg_gen_xor_tl(ret, arg1, t);
388
+
389
+ tcg_temp_free(t);
390
+}
391
+
392
static bool trans_binv(DisasContext *ctx, arg_binv *a)
393
{
394
REQUIRE_EXT(ctx, RVB);
395
@@ -XXX,XX +XXX,XX @@ static bool trans_binvi(DisasContext *ctx, arg_binvi *a)
396
return gen_shifti(ctx, a, gen_binv);
397
}
398
399
+static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
400
+{
401
+ tcg_gen_shr_tl(ret, arg1, shamt);
402
+ tcg_gen_andi_tl(ret, ret, 1);
403
+}
404
+
405
static bool trans_bext(DisasContext *ctx, arg_bext *a)
406
{
407
REQUIRE_EXT(ctx, RVB);
408
@@ -XXX,XX +XXX,XX @@ static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
409
return gen_shifti(ctx, a, gen_bext);
410
}
411
412
+static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
413
+{
414
+ tcg_gen_not_tl(ret, arg1);
415
+ tcg_gen_shl_tl(ret, ret, arg2);
416
+ tcg_gen_not_tl(ret, ret);
417
+}
418
+
419
static bool trans_slo(DisasContext *ctx, arg_slo *a)
420
{
421
REQUIRE_EXT(ctx, RVB);
422
@@ -XXX,XX +XXX,XX @@ static bool trans_sloi(DisasContext *ctx, arg_sloi *a)
423
return gen_shifti(ctx, a, gen_slo);
424
}
425
426
+static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
427
+{
428
+ tcg_gen_not_tl(ret, arg1);
429
+ tcg_gen_shr_tl(ret, ret, arg2);
430
+ tcg_gen_not_tl(ret, ret);
431
+}
432
+
433
static bool trans_sro(DisasContext *ctx, arg_sro *a)
434
{
435
REQUIRE_EXT(ctx, RVB);
436
@@ -XXX,XX +XXX,XX @@ static bool trans_grev(DisasContext *ctx, arg_grev *a)
437
return gen_shift(ctx, a, gen_helper_grev);
438
}
439
440
+static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
441
+{
442
+ TCGv source1 = tcg_temp_new();
443
+ TCGv source2;
444
+
445
+ gen_get_gpr(ctx, source1, a->rs1);
446
+
447
+ if (a->shamt == (TARGET_LONG_BITS - 8)) {
448
+ /* rev8, byte swaps */
449
+ tcg_gen_bswap_tl(source1, source1);
450
+ } else {
451
+ source2 = tcg_temp_new();
452
+ tcg_gen_movi_tl(source2, a->shamt);
453
+ gen_helper_grev(source1, source1, source2);
454
+ tcg_temp_free(source2);
455
+ }
456
+
457
+ gen_set_gpr(ctx, a->rd, source1);
458
+ tcg_temp_free(source1);
459
+ return true;
460
+}
461
+
462
static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
463
{
464
REQUIRE_EXT(ctx, RVB);
465
@@ -XXX,XX +XXX,XX @@ static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
466
return gen_shifti(ctx, a, gen_helper_gorc);
467
}
468
469
+#define GEN_SHADD(SHAMT) \
470
+static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
471
+{ \
472
+ TCGv t = tcg_temp_new(); \
473
+ \
474
+ tcg_gen_shli_tl(t, arg1, SHAMT); \
475
+ tcg_gen_add_tl(ret, t, arg2); \
476
+ \
477
+ tcg_temp_free(t); \
478
+}
479
+
480
+GEN_SHADD(1)
481
+GEN_SHADD(2)
482
+GEN_SHADD(3)
483
+
484
#define GEN_TRANS_SHADD(SHAMT) \
485
static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
486
{ \
487
@@ -XXX,XX +XXX,XX @@ GEN_TRANS_SHADD(1)
488
GEN_TRANS_SHADD(2)
489
GEN_TRANS_SHADD(3)
490
491
+static void gen_clzw(TCGv ret, TCGv arg1)
492
+{
493
+ tcg_gen_ext32u_tl(ret, arg1);
494
+ tcg_gen_clzi_tl(ret, ret, 64);
495
+ tcg_gen_subi_tl(ret, ret, 32);
496
+}
497
+
498
static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
499
{
500
REQUIRE_64BIT(ctx);
501
@@ -XXX,XX +XXX,XX @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
502
return gen_unary(ctx, a, gen_clzw);
503
}
504
505
+static void gen_ctzw(TCGv ret, TCGv arg1)
506
+{
507
+ tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32));
508
+ tcg_gen_ctzi_tl(ret, ret, 64);
509
+}
510
+
511
static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
512
{
513
REQUIRE_64BIT(ctx);
514
@@ -XXX,XX +XXX,XX @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
515
return gen_unary(ctx, a, gen_ctzw);
516
}
517
518
+static void gen_cpopw(TCGv ret, TCGv arg1)
519
+{
520
+ tcg_gen_ext32u_tl(arg1, arg1);
521
+ tcg_gen_ctpop_tl(ret, arg1);
522
+}
523
+
524
static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
525
{
526
REQUIRE_64BIT(ctx);
527
@@ -XXX,XX +XXX,XX @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
528
return gen_unary(ctx, a, gen_cpopw);
529
}
530
531
+static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
532
+{
533
+ TCGv t = tcg_temp_new();
534
+ tcg_gen_ext16s_tl(t, arg2);
535
+ tcg_gen_deposit_tl(ret, arg1, t, 16, 48);
536
+ tcg_temp_free(t);
537
+}
538
+
539
static bool trans_packw(DisasContext *ctx, arg_packw *a)
540
{
541
REQUIRE_64BIT(ctx);
542
@@ -XXX,XX +XXX,XX @@ static bool trans_packw(DisasContext *ctx, arg_packw *a)
543
return gen_arith(ctx, a, EXT_NONE, gen_packw);
544
}
545
546
+static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
547
+{
548
+ TCGv t = tcg_temp_new();
549
+ tcg_gen_shri_tl(t, arg1, 16);
550
+ tcg_gen_deposit_tl(ret, arg2, t, 0, 16);
551
+ tcg_gen_ext32s_tl(ret, ret);
552
+ tcg_temp_free(t);
553
+}
554
+
555
static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
556
{
557
REQUIRE_64BIT(ctx);
558
@@ -XXX,XX +XXX,XX @@ static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
559
return gen_shiftiw(ctx, a, gen_sro);
560
}
561
562
+static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
563
+{
564
+ TCGv_i32 t1 = tcg_temp_new_i32();
565
+ TCGv_i32 t2 = tcg_temp_new_i32();
566
+
567
+ /* truncate to 32-bits */
568
+ tcg_gen_trunc_tl_i32(t1, arg1);
569
+ tcg_gen_trunc_tl_i32(t2, arg2);
570
+
571
+ tcg_gen_rotr_i32(t1, t1, t2);
572
+
573
+ /* sign-extend 64-bits */
574
+ tcg_gen_ext_i32_tl(ret, t1);
575
+
576
+ tcg_temp_free_i32(t1);
577
+ tcg_temp_free_i32(t2);
578
+}
579
+
580
static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
581
{
582
REQUIRE_64BIT(ctx);
583
@@ -XXX,XX +XXX,XX @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
584
return gen_shiftiw(ctx, a, gen_rorw);
585
}
586
587
+static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
588
+{
589
+ TCGv_i32 t1 = tcg_temp_new_i32();
590
+ TCGv_i32 t2 = tcg_temp_new_i32();
591
+
592
+ /* truncate to 32-bits */
593
+ tcg_gen_trunc_tl_i32(t1, arg1);
594
+ tcg_gen_trunc_tl_i32(t2, arg2);
595
+
596
+ tcg_gen_rotl_i32(t1, t1, t2);
597
+
598
+ /* sign-extend 64-bits */
599
+ tcg_gen_ext_i32_tl(ret, t1);
600
+
601
+ tcg_temp_free_i32(t1);
602
+ tcg_temp_free_i32(t2);
603
+}
604
+
605
static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
606
{
607
REQUIRE_64BIT(ctx);
608
@@ -XXX,XX +XXX,XX @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
609
return gen_shiftw(ctx, a, gen_rolw);
610
}
611
612
+static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
613
+{
614
+ tcg_gen_ext32u_tl(arg1, arg1);
615
+ gen_helper_grev(ret, arg1, arg2);
616
+}
617
+
618
static bool trans_grevw(DisasContext *ctx, arg_grevw *a)
619
{
620
REQUIRE_64BIT(ctx);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
622
return gen_shiftiw(ctx, a, gen_grevw);
623
}
624
625
+static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2)
626
+{
627
+ tcg_gen_ext32u_tl(arg1, arg1);
628
+ gen_helper_gorcw(ret, arg1, arg2);
629
+}
630
+
631
static bool trans_gorcw(DisasContext *ctx, arg_gorcw *a)
632
{
633
REQUIRE_64BIT(ctx);
634
@@ -XXX,XX +XXX,XX @@ static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a)
635
return gen_shiftiw(ctx, a, gen_gorcw);
636
}
637
638
+#define GEN_SHADD_UW(SHAMT) \
639
+static void gen_sh##SHAMT##add_uw(TCGv ret, TCGv arg1, TCGv arg2) \
640
+{ \
641
+ TCGv t = tcg_temp_new(); \
642
+ \
643
+ tcg_gen_ext32u_tl(t, arg1); \
644
+ \
645
+ tcg_gen_shli_tl(t, t, SHAMT); \
646
+ tcg_gen_add_tl(ret, t, arg2); \
647
+ \
648
+ tcg_temp_free(t); \
649
+}
650
+
651
+GEN_SHADD_UW(1)
652
+GEN_SHADD_UW(2)
653
+GEN_SHADD_UW(3)
654
+
655
#define GEN_TRANS_SHADD_UW(SHAMT) \
656
static bool trans_sh##SHAMT##add_uw(DisasContext *ctx, \
657
arg_sh##SHAMT##add_uw *a) \
658
@@ -XXX,XX +XXX,XX @@ GEN_TRANS_SHADD_UW(1)
659
GEN_TRANS_SHADD_UW(2)
660
GEN_TRANS_SHADD_UW(3)
661
662
+static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
663
+{
664
+ tcg_gen_ext32u_tl(arg1, arg1);
665
+ tcg_gen_add_tl(ret, arg1, arg2);
666
+}
667
+
668
static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
669
{
670
REQUIRE_64BIT(ctx);
671
--
529
--
672
2.31.1
530
2.41.0
673
674
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Exit early if check_access fails.
3
This commit adds support for the Zvkned vector-crypto extension, which
4
Split out do_hlv, do_hsv, do_hlvx subroutines.
4
consists of the following instructions:
5
Use dest_gpr, get_gpr in the new subroutines.
6
5
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
* vaesef.[vv,vs]
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
* vaesdf.[vv,vs]
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
* vaesdm.[vv,vs]
10
Message-id: 20210823195529.560295-24-richard.henderson@linaro.org
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
13
14
Translation functions are defined in
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
16
`target/riscv/vcrypto_helper.c`.
17
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
19
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
20
[max.chou@sifive.com: Replaced vstart checking by TCG op]
21
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
22
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
23
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
24
Signed-off-by: Max Chou <max.chou@sifive.com>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
[max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned
27
property]
28
[max.chou@sifive.com: Fixed endian issues and replaced the vstart & vl
29
egs checking by helper function]
30
[max.chou@sifive.com: Replaced bswap32 calls in aes key expanding]
31
Message-ID: <20230711165917.2629866-10-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
33
---
13
target/riscv/insn32.decode | 1 +
34
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/insn_trans/trans_rvh.c.inc | 266 +++++-------------------
35
target/riscv/helper.h | 14 ++
15
2 files changed, 57 insertions(+), 210 deletions(-)
36
target/riscv/insn32.decode | 14 ++
37
target/riscv/cpu.c | 4 +-
38
target/riscv/vcrypto_helper.c | 202 +++++++++++++++++++++++
39
target/riscv/insn_trans/trans_rvvk.c.inc | 147 +++++++++++++++++
40
6 files changed, 381 insertions(+), 1 deletion(-)
16
41
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_cfg.h
45
+++ b/target/riscv/cpu_cfg.h
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_zve64d;
48
bool ext_zvbb;
49
bool ext_zvbc;
50
+ bool ext_zvkned;
51
bool ext_zmmul;
52
bool ext_zvfbfmin;
53
bool ext_zvfbfwma;
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/helper.h
57
+++ b/target/riscv/helper.h
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
62
+
63
+DEF_HELPER_2(egs_check, void, i32, env)
64
+
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
68
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
69
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
70
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
71
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
72
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
73
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
74
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
75
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
17
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
76
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
18
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn32.decode
78
--- a/target/riscv/insn32.decode
20
+++ b/target/riscv/insn32.decode
79
+++ b/target/riscv/insn32.decode
21
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
22
&j imm rd
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
23
&r rd rs1 rs2
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
24
&r2 rd rs1
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
25
+&r2_s rs1 rs2
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
26
&s imm rs1 rs2
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
27
&u imm rd
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
28
&shift shamt rs1 rd
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
29
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
90
vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
91
vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
92
+
93
+# *** Zvkned vector crypto extension ***
94
+vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1
95
+vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1
96
+vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1
97
+vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1
98
+vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1
99
+vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1
100
+vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1
101
+vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
102
+vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
103
+vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
104
+vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/insn_trans/trans_rvh.c.inc
107
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
108
+++ b/target/riscv/cpu.c
109
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
110
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
111
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
112
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
113
+ ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
114
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
115
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
116
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
117
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
118
* In principle Zve*x would also suffice here, were they supported
119
* in qemu
120
*/
121
- if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
122
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
123
error_setg(errp,
124
"Vector crypto extensions require V or Zve* extensions");
125
return;
126
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
127
/* Vector cryptography extensions */
128
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
129
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
130
+ DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
131
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/riscv/vcrypto_helper.c
137
+++ b/target/riscv/vcrypto_helper.c
33
@@ -XXX,XX +XXX,XX @@
138
@@ -XXX,XX +XXX,XX @@
34
*/
139
#include "qemu/bitops.h"
35
140
#include "qemu/bswap.h"
36
#ifndef CONFIG_USER_ONLY
141
#include "cpu.h"
37
-static void check_access(DisasContext *ctx) {
142
+#include "crypto/aes.h"
38
+static bool check_access(DisasContext *ctx)
143
+#include "crypto/aes-round.h"
39
+{
144
#include "exec/memop.h"
40
if (!ctx->hlsx) {
145
#include "exec/exec-all.h"
41
if (ctx->virt_enabled) {
146
#include "exec/helper-proto.h"
42
generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
147
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
43
} else {
148
GEN_VEXT_VX(vwsll_vx_b, 2)
44
generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
149
GEN_VEXT_VX(vwsll_vx_h, 4)
45
}
150
GEN_VEXT_VX(vwsll_vx_w, 8)
46
+ return false;
151
+
47
}
152
+void HELPER(egs_check)(uint32_t egs, CPURISCVState *env)
48
+ return true;
153
+{
49
}
154
+ uint32_t vl = env->vl;
50
#endif
155
+ uint32_t vstart = env->vstart;
51
156
+
52
-static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
157
+ if (vl % egs != 0 || vstart % egs != 0) {
53
+static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
{
159
+ }
55
- REQUIRE_EXT(ctx, RVH);
160
+}
56
-#ifndef CONFIG_USER_ONLY
161
+
57
- TCGv t0 = tcg_temp_new();
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
58
- TCGv t1 = tcg_temp_new();
163
+{
59
-
164
+ round_state->v = round_state->v ^ round_key->v;
60
- check_access(ctx);
165
+}
61
-
166
+
62
- gen_get_gpr(ctx, t0, a->rs1);
167
+#define GEN_ZVKNED_HELPER_VV(NAME, ...) \
63
-
168
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
64
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
169
+ uint32_t desc) \
65
- gen_set_gpr(ctx, a->rd, t1);
170
+ { \
66
-
171
+ uint32_t vl = env->vl; \
67
- tcg_temp_free(t0);
172
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
68
- tcg_temp_free(t1);
173
+ uint32_t vta = vext_vta(desc); \
69
- return true;
174
+ \
70
-#else
175
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
71
+#ifdef CONFIG_USER_ONLY
176
+ AESState round_key; \
72
return false;
177
+ round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
73
+#else
178
+ round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \
74
+ if (check_access(ctx)) {
179
+ AESState round_state; \
75
+ TCGv dest = dest_gpr(ctx, a->rd);
180
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
76
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
181
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
77
+ int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
182
+ __VA_ARGS__; \
78
+ tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
183
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
79
+ gen_set_gpr(ctx, a->rd, dest);
184
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
80
+ }
185
+ } \
81
+ return true;
186
+ env->vstart = 0; \
82
#endif
187
+ /* set tail elements to 1s */ \
83
}
188
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
84
189
+ }
85
-static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
190
+
86
+static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
191
+#define GEN_ZVKNED_HELPER_VS(NAME, ...) \
87
{
192
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
88
REQUIRE_EXT(ctx, RVH);
193
+ uint32_t desc) \
89
-#ifndef CONFIG_USER_ONLY
194
+ { \
90
- TCGv t0 = tcg_temp_new();
195
+ uint32_t vl = env->vl; \
91
- TCGv t1 = tcg_temp_new();
196
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
92
-
197
+ uint32_t vta = vext_vta(desc); \
93
- check_access(ctx);
198
+ \
94
-
199
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
95
- gen_get_gpr(ctx, t0, a->rs1);
200
+ AESState round_key; \
96
-
201
+ round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
97
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
202
+ round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \
98
- gen_set_gpr(ctx, a->rd, t1);
203
+ AESState round_state; \
99
+ return do_hlv(ctx, a, MO_SB);
204
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
100
+}
205
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
101
206
+ __VA_ARGS__; \
102
- tcg_temp_free(t0);
207
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
103
- tcg_temp_free(t1);
208
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
104
- return true;
209
+ } \
105
-#else
210
+ env->vstart = 0; \
106
- return false;
211
+ /* set tail elements to 1s */ \
107
-#endif
212
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
108
+static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
213
+ }
109
+{
214
+
110
+ REQUIRE_EXT(ctx, RVH);
215
+GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state,
111
+ return do_hlv(ctx, a, MO_TESW);
216
+ &round_state,
112
}
217
+ &round_key,
113
218
+ false);)
114
static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
219
+GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state,
115
{
220
+ &round_state,
116
REQUIRE_EXT(ctx, RVH);
221
+ &round_key,
117
-#ifndef CONFIG_USER_ONLY
222
+ false);)
118
- TCGv t0 = tcg_temp_new();
223
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state,
119
- TCGv t1 = tcg_temp_new();
224
+ &round_state,
120
-
225
+ &round_key,
121
- check_access(ctx);
226
+ false);)
122
-
227
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state,
123
- gen_get_gpr(ctx, t0, a->rs1);
228
+ &round_state,
124
-
229
+ &round_key,
125
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
230
+ false);)
126
- gen_set_gpr(ctx, a->rd, t1);
231
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state,
127
-
232
+ &round_state,
128
- tcg_temp_free(t0);
233
+ &round_key,
129
- tcg_temp_free(t1);
234
+ false);)
130
- return true;
235
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state,
131
-#else
236
+ &round_state,
132
- return false;
237
+ &round_key,
133
-#endif
238
+ false);)
134
+ return do_hlv(ctx, a, MO_TESL);
239
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state,
135
}
240
+ &round_state,
136
241
+ &round_key,
137
static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
242
+ false);)
138
{
243
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state,
139
REQUIRE_EXT(ctx, RVH);
244
+ &round_state,
140
-#ifndef CONFIG_USER_ONLY
245
+ &round_key,
141
- TCGv t0 = tcg_temp_new();
246
+ false);)
142
- TCGv t1 = tcg_temp_new();
247
+GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);)
143
-
248
+
144
- check_access(ctx);
249
+void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
145
-
250
+ CPURISCVState *env, uint32_t desc)
146
- gen_get_gpr(ctx, t0, a->rs1);
251
+{
147
-
252
+ uint32_t *vd = vd_vptr;
148
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
253
+ uint32_t *vs2 = vs2_vptr;
149
- gen_set_gpr(ctx, a->rd, t1);
254
+ uint32_t vl = env->vl;
150
-
255
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
151
- tcg_temp_free(t0);
256
+ uint32_t vta = vext_vta(desc);
152
- tcg_temp_free(t1);
257
+
153
- return true;
258
+ uimm &= 0b1111;
154
-#else
259
+ if (uimm > 10 || uimm == 0) {
155
- return false;
260
+ uimm ^= 0b1000;
156
-#endif
261
+ }
157
+ return do_hlv(ctx, a, MO_UB);
262
+
158
}
263
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
159
264
+ uint32_t rk[8], tmp;
160
static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
265
+ static const uint32_t rcon[] = {
161
{
266
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
162
REQUIRE_EXT(ctx, RVH);
267
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
163
-#ifndef CONFIG_USER_ONLY
268
+ };
164
- TCGv t0 = tcg_temp_new();
269
+
165
- TCGv t1 = tcg_temp_new();
270
+ rk[0] = vs2[i * 4 + H4(0)];
166
-
271
+ rk[1] = vs2[i * 4 + H4(1)];
167
- check_access(ctx);
272
+ rk[2] = vs2[i * 4 + H4(2)];
168
-
273
+ rk[3] = vs2[i * 4 + H4(3)];
169
- gen_get_gpr(ctx, t0, a->rs1);
274
+ tmp = ror32(rk[3], 8);
170
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
275
+
171
- gen_set_gpr(ctx, a->rd, t1);
276
+ rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
172
+ return do_hlv(ctx, a, MO_TEUW);
277
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
173
+}
278
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
174
279
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
175
- tcg_temp_free(t0);
280
+ ^ rcon[uimm - 1];
176
- tcg_temp_free(t1);
281
+ rk[5] = rk[1] ^ rk[4];
177
- return true;
282
+ rk[6] = rk[2] ^ rk[5];
178
-#else
283
+ rk[7] = rk[3] ^ rk[6];
179
+static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
284
+
180
+{
285
+ vd[i * 4 + H4(0)] = rk[4];
181
+#ifdef CONFIG_USER_ONLY
286
+ vd[i * 4 + H4(1)] = rk[5];
182
return false;
287
+ vd[i * 4 + H4(2)] = rk[6];
183
+#else
288
+ vd[i * 4 + H4(3)] = rk[7];
184
+ if (check_access(ctx)) {
289
+ }
185
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
290
+ env->vstart = 0;
186
+ TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
291
+ /* set tail elements to 1s */
187
+ int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
292
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
188
+ tcg_gen_qemu_st_tl(data, addr, mem_idx, mop);
293
+}
189
+ }
294
+
190
+ return true;
295
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
191
#endif
296
+ CPURISCVState *env, uint32_t desc)
192
}
297
+{
193
298
+ uint32_t *vd = vd_vptr;
194
static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
299
+ uint32_t *vs2 = vs2_vptr;
195
{
300
+ uint32_t vl = env->vl;
196
REQUIRE_EXT(ctx, RVH);
301
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
197
-#ifndef CONFIG_USER_ONLY
302
+ uint32_t vta = vext_vta(desc);
198
- TCGv t0 = tcg_temp_new();
303
+
199
- TCGv dat = tcg_temp_new();
304
+ uimm &= 0b1111;
200
-
305
+ if (uimm > 14 || uimm < 2) {
201
- check_access(ctx);
306
+ uimm ^= 0b1000;
202
-
307
+ }
203
- gen_get_gpr(ctx, t0, a->rs1);
308
+
204
- gen_get_gpr(ctx, dat, a->rs2);
309
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
205
-
310
+ uint32_t rk[12], tmp;
206
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
311
+ static const uint32_t rcon[] = {
207
-
312
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
208
- tcg_temp_free(t0);
313
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
209
- tcg_temp_free(dat);
314
+ };
210
- return true;
315
+
211
-#else
316
+ rk[0] = vd[i * 4 + H4(0)];
212
- return false;
317
+ rk[1] = vd[i * 4 + H4(1)];
213
-#endif
318
+ rk[2] = vd[i * 4 + H4(2)];
214
+ return do_hsv(ctx, a, MO_SB);
319
+ rk[3] = vd[i * 4 + H4(3)];
215
}
320
+ rk[4] = vs2[i * 4 + H4(0)];
216
321
+ rk[5] = vs2[i * 4 + H4(1)];
217
static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
322
+ rk[6] = vs2[i * 4 + H4(2)];
218
{
323
+ rk[7] = vs2[i * 4 + H4(3)];
219
REQUIRE_EXT(ctx, RVH);
324
+
220
-#ifndef CONFIG_USER_ONLY
325
+ if (uimm % 2 == 0) {
221
- TCGv t0 = tcg_temp_new();
326
+ tmp = ror32(rk[7], 8);
222
- TCGv dat = tcg_temp_new();
327
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
223
-
328
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
224
- check_access(ctx);
329
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
225
-
330
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
226
- gen_get_gpr(ctx, t0, a->rs1);
331
+ ^ rcon[(uimm - 1) / 2];
227
- gen_get_gpr(ctx, dat, a->rs2);
332
+ } else {
228
-
333
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) |
229
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
334
+ ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) |
230
-
335
+ ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) |
231
- tcg_temp_free(t0);
336
+ ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0));
232
- tcg_temp_free(dat);
337
+ }
233
- return true;
338
+ rk[9] = rk[1] ^ rk[8];
234
-#else
339
+ rk[10] = rk[2] ^ rk[9];
235
- return false;
340
+ rk[11] = rk[3] ^ rk[10];
236
-#endif
341
+
237
+ return do_hsv(ctx, a, MO_TESW);
342
+ vd[i * 4 + H4(0)] = rk[8];
238
}
343
+ vd[i * 4 + H4(1)] = rk[9];
239
344
+ vd[i * 4 + H4(2)] = rk[10];
240
static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
345
+ vd[i * 4 + H4(3)] = rk[11];
241
{
346
+ }
242
REQUIRE_EXT(ctx, RVH);
347
+ env->vstart = 0;
243
-#ifndef CONFIG_USER_ONLY
348
+ /* set tail elements to 1s */
244
- TCGv t0 = tcg_temp_new();
349
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
245
- TCGv dat = tcg_temp_new();
350
+}
246
-
351
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
247
- check_access(ctx);
352
index XXXXXXX..XXXXXXX 100644
248
-
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
249
- gen_get_gpr(ctx, t0, a->rs1);
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
250
- gen_get_gpr(ctx, dat, a->rs2);
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
251
-
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
252
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
253
-
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
254
- tcg_temp_free(t0);
359
+
255
- tcg_temp_free(dat);
360
+/*
256
- return true;
361
+ * Zvkned
257
-#else
362
+ */
258
- return false;
363
+
259
-#endif
364
+#define ZVKNED_EGS 4
260
+ return do_hsv(ctx, a, MO_TESL);
365
+
261
}
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
262
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
263
static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
368
+ { \
264
{
369
+ if (CHECK(s, a)) { \
265
REQUIRE_64BIT(ctx);
370
+ TCGv_ptr rd_v, rs2_v; \
266
REQUIRE_EXT(ctx, RVH);
371
+ TCGv_i32 desc, egs; \
267
-
372
+ uint32_t data = 0; \
268
-#ifndef CONFIG_USER_ONLY
373
+ TCGLabel *over = gen_new_label(); \
269
- TCGv t0 = tcg_temp_new();
374
+ \
270
- TCGv t1 = tcg_temp_new();
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
271
-
376
+ /* save opcode for unwinding in case we throw an exception */ \
272
- check_access(ctx);
377
+ decode_save_opc(s); \
273
-
378
+ egs = tcg_constant_i32(EGS); \
274
- gen_get_gpr(ctx, t0, a->rs1);
379
+ gen_helper_egs_check(egs, cpu_env); \
275
-
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
276
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
381
+ } \
277
- gen_set_gpr(ctx, a->rd, t1);
382
+ \
278
-
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
279
- tcg_temp_free(t0);
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
280
- tcg_temp_free(t1);
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
281
- return true;
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
282
-#else
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
283
- return false;
388
+ rd_v = tcg_temp_new_ptr(); \
284
-#endif
389
+ rs2_v = tcg_temp_new_ptr(); \
285
+ return do_hlv(ctx, a, MO_TEUL);
390
+ desc = tcg_constant_i32( \
286
}
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
287
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
288
static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
289
{
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
290
REQUIRE_64BIT(ctx);
395
+ mark_vs_dirty(s); \
291
REQUIRE_EXT(ctx, RVH);
396
+ gen_set_label(over); \
292
-
397
+ return true; \
293
-#ifndef CONFIG_USER_ONLY
398
+ } \
294
- TCGv t0 = tcg_temp_new();
399
+ return false; \
295
- TCGv t1 = tcg_temp_new();
400
+ }
296
-
401
+
297
- check_access(ctx);
402
+static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
298
-
403
+{
299
- gen_get_gpr(ctx, t0, a->rs1);
404
+ int egw_bytes = ZVKNED_EGS << s->sew;
300
-
405
+ return s->cfg_ptr->ext_zvkned == true &&
301
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
406
+ require_rvv(s) &&
302
- gen_set_gpr(ctx, a->rd, t1);
407
+ vext_check_isa_ill(s) &&
303
-
408
+ MAXSZ(s) >= egw_bytes &&
304
- tcg_temp_free(t0);
409
+ require_align(a->rd, s->lmul) &&
305
- tcg_temp_free(t1);
410
+ require_align(a->rs2, s->lmul) &&
306
- return true;
411
+ s->sew == MO_32;
307
-#else
412
+}
308
- return false;
413
+
309
-#endif
414
+static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
310
+ return do_hlv(ctx, a, MO_TEQ);
415
+{
311
}
416
+ int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
312
417
+ return !is_overlapped(vd, op_size, vs2, 1);
313
static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
418
+}
314
{
419
+
315
REQUIRE_64BIT(ctx);
420
+static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
316
REQUIRE_EXT(ctx, RVH);
421
+{
317
+ return do_hsv(ctx, a, MO_TEQ);
422
+ int egw_bytes = ZVKNED_EGS << s->sew;
318
+}
423
+ return vaes_check_overlap(s, a->rd, a->rs2) &&
319
424
+ MAXSZ(s) >= egw_bytes &&
320
#ifndef CONFIG_USER_ONLY
425
+ s->cfg_ptr->ext_zvkned == true &&
321
- TCGv t0 = tcg_temp_new();
426
+ require_rvv(s) &&
322
- TCGv dat = tcg_temp_new();
427
+ vext_check_isa_ill(s) &&
323
-
428
+ require_align(a->rd, s->lmul) &&
324
- check_access(ctx);
429
+ s->sew == MO_32;
325
-
430
+}
326
- gen_get_gpr(ctx, t0, a->rs1);
431
+
327
- gen_get_gpr(ctx, dat, a->rs2);
432
+GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
328
-
433
+GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
329
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
434
+GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
330
-
435
+GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
331
- tcg_temp_free(t0);
436
+GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
332
- tcg_temp_free(dat);
437
+GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
333
+static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
438
+GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
334
+ void (*func)(TCGv, TCGv_env, TCGv))
439
+GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
335
+{
440
+GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
336
+ if (check_access(ctx)) {
441
+
337
+ TCGv dest = dest_gpr(ctx, a->rd);
442
+#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS) \
338
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
443
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
339
+ func(dest, cpu_env, addr);
444
+ { \
340
+ gen_set_gpr(ctx, a->rd, dest);
445
+ if (CHECK(s, a)) { \
341
+ }
446
+ TCGv_ptr rd_v, rs2_v; \
342
return true;
447
+ TCGv_i32 uimm_v, desc, egs; \
343
-#else
448
+ uint32_t data = 0; \
344
- return false;
449
+ TCGLabel *over = gen_new_label(); \
345
-#endif
450
+ \
346
}
451
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
347
+#endif
452
+ /* save opcode for unwinding in case we throw an exception */ \
348
453
+ decode_save_opc(s); \
349
static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
454
+ egs = tcg_constant_i32(EGS); \
350
{
455
+ gen_helper_egs_check(egs, cpu_env); \
351
REQUIRE_EXT(ctx, RVH);
456
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
352
#ifndef CONFIG_USER_ONLY
457
+ } \
353
- TCGv t0 = tcg_temp_new();
458
+ \
354
- TCGv t1 = tcg_temp_new();
459
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
355
-
460
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
356
- check_access(ctx);
461
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
357
-
462
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
358
- gen_get_gpr(ctx, t0, a->rs1);
463
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
359
-
464
+ \
360
- gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
465
+ rd_v = tcg_temp_new_ptr(); \
361
- gen_set_gpr(ctx, a->rd, t1);
466
+ rs2_v = tcg_temp_new_ptr(); \
362
-
467
+ uimm_v = tcg_constant_i32(a->rs1); \
363
- tcg_temp_free(t0);
468
+ desc = tcg_constant_i32( \
364
- tcg_temp_free(t1);
469
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
365
- return true;
470
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
366
+ return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
471
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
367
#else
472
+ gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc); \
368
return false;
473
+ mark_vs_dirty(s); \
369
#endif
474
+ gen_set_label(over); \
370
@@ -XXX,XX +XXX,XX @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
475
+ return true; \
371
{
476
+ } \
372
REQUIRE_EXT(ctx, RVH);
477
+ return false; \
373
#ifndef CONFIG_USER_ONLY
478
+ }
374
- TCGv t0 = tcg_temp_new();
479
+
375
- TCGv t1 = tcg_temp_new();
480
+static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
376
-
481
+{
377
- check_access(ctx);
482
+ int egw_bytes = ZVKNED_EGS << s->sew;
378
-
483
+ return s->cfg_ptr->ext_zvkned == true &&
379
- gen_get_gpr(ctx, t0, a->rs1);
484
+ require_rvv(s) &&
380
-
485
+ vext_check_isa_ill(s) &&
381
- gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
486
+ MAXSZ(s) >= egw_bytes &&
382
- gen_set_gpr(ctx, a->rd, t1);
487
+ s->sew == MO_32 &&
383
-
488
+ require_align(a->rd, s->lmul) &&
384
- tcg_temp_free(t0);
489
+ require_align(a->rs2, s->lmul);
385
- tcg_temp_free(t1);
490
+}
386
- return true;
491
+
387
+ return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
492
+static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
388
#else
493
+{
389
return false;
494
+ int egw_bytes = ZVKNED_EGS << s->sew;
390
#endif
495
+ return s->cfg_ptr->ext_zvkned == true &&
496
+ require_rvv(s) &&
497
+ vext_check_isa_ill(s) &&
498
+ MAXSZ(s) >= egw_bytes &&
499
+ s->sew == MO_32 &&
500
+ require_align(a->rd, s->lmul) &&
501
+ require_align(a->rs2, s->lmul);
502
+}
503
+
504
+GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
505
+GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
391
--
506
--
392
2.31.1
507
2.41.0
393
394
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
This commit adds support for the Zvknh vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsha2ms.vv
7
* vsha2c[hl].vv
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
target/riscv/cpu_cfg.h | 2 +
28
target/riscv/helper.h | 6 +
29
target/riscv/insn32.decode | 5 +
30
target/riscv/cpu.c | 13 +-
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
34
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_cfg.h
38
+++ b/target/riscv/cpu_cfg.h
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
bool ext_zvbb;
41
bool ext_zvbc;
42
bool ext_zvkned;
43
+ bool ext_zvknha;
44
+ bool ext_zvknhb;
45
bool ext_zmmul;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
48
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
56
+
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
60
+DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
61
+DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
62
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/riscv/insn32.decode
65
+++ b/target/riscv/insn32.decode
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
70
+
71
+# *** Zvknh vector crypto extension ***
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
89
* In principle Zve*x would also suffice here, were they supported
90
* in qemu
91
*/
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
94
+ !cpu->cfg.ext_zve32f) {
95
error_setg(errp,
96
"Vector crypto extensions require V or Zve* extensions");
97
return;
98
}
99
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
103
+ error_setg(
104
+ errp,
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
106
return;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/riscv/vcrypto_helper.c
121
+++ b/target/riscv/vcrypto_helper.c
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
123
/* set tail elements to 1s */
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
125
}
126
+
127
+static inline uint32_t sig0_sha256(uint32_t x)
128
+{
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
130
+}
131
+
132
+static inline uint32_t sig1_sha256(uint32_t x)
133
+{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
135
+}
136
+
137
+static inline uint64_t sig0_sha512(uint64_t x)
138
+{
139
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
140
+}
141
+
142
+static inline uint64_t sig1_sha512(uint64_t x)
143
+{
144
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
145
+}
146
+
147
+static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2)
148
+{
149
+ uint32_t res[4];
150
+ res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) +
151
+ vd[H4(0)];
152
+ res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) +
153
+ vd[H4(1)];
154
+ res[2] =
155
+ sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)];
156
+ res[3] =
157
+ sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)];
158
+ vd[H4(3)] = res[3];
159
+ vd[H4(2)] = res[2];
160
+ vd[H4(1)] = res[1];
161
+ vd[H4(0)] = res[0];
162
+}
163
+
164
+static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2)
165
+{
166
+ uint64_t res[4];
167
+ res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0];
168
+ res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1];
169
+ res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2];
170
+ res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3];
171
+ vd[3] = res[3];
172
+ vd[2] = res[2];
173
+ vd[1] = res[1];
174
+ vd[0] = res[0];
175
+}
176
+
177
+void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
178
+ uint32_t desc)
179
+{
180
+ uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
181
+ uint32_t esz = sew == MO_32 ? 4 : 8;
182
+ uint32_t total_elems;
183
+ uint32_t vta = vext_vta(desc);
184
+
185
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
186
+ if (sew == MO_32) {
187
+ vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
188
+ ((uint32_t *)vs2) + i * 4);
189
+ } else {
190
+ /* If not 32 then SEW should be 64 */
191
+ vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4,
192
+ ((uint64_t *)vs2) + i * 4);
193
+ }
194
+ }
195
+ /* set tail elements to 1s */
196
+ total_elems = vext_get_total_elems(env, desc, esz);
197
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
198
+ env->vstart = 0;
199
+}
200
+
201
+static inline uint64_t sum0_64(uint64_t x)
202
+{
203
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
204
+}
205
+
206
+static inline uint32_t sum0_32(uint32_t x)
207
+{
208
+ return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
209
+}
210
+
211
+static inline uint64_t sum1_64(uint64_t x)
212
+{
213
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
214
+}
215
+
216
+static inline uint32_t sum1_32(uint32_t x)
217
+{
218
+ return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
219
+}
220
+
221
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
222
+
223
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
224
+
225
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
226
+{
227
+ uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
228
+ uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
229
+ uint64_t W0 = vs1[0], W1 = vs1[1];
230
+ uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
231
+ uint64_t T2 = sum0_64(a) + maj(a, b, c);
232
+
233
+ h = g;
234
+ g = f;
235
+ f = e;
236
+ e = d + T1;
237
+ d = c;
238
+ c = b;
239
+ b = a;
240
+ a = T1 + T2;
241
+
242
+ T1 = h + sum1_64(e) + ch(e, f, g) + W1;
243
+ T2 = sum0_64(a) + maj(a, b, c);
244
+ h = g;
245
+ g = f;
246
+ f = e;
247
+ e = d + T1;
248
+ d = c;
249
+ c = b;
250
+ b = a;
251
+ a = T1 + T2;
252
+
253
+ vd[0] = f;
254
+ vd[1] = e;
255
+ vd[2] = b;
256
+ vd[3] = a;
257
+}
258
+
259
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
260
+{
261
+ uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
262
+ uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
263
+ uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
264
+ uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
265
+ uint32_t T2 = sum0_32(a) + maj(a, b, c);
266
+
267
+ h = g;
268
+ g = f;
269
+ f = e;
270
+ e = d + T1;
271
+ d = c;
272
+ c = b;
273
+ b = a;
274
+ a = T1 + T2;
275
+
276
+ T1 = h + sum1_32(e) + ch(e, f, g) + W1;
277
+ T2 = sum0_32(a) + maj(a, b, c);
278
+ h = g;
279
+ g = f;
280
+ f = e;
281
+ e = d + T1;
282
+ d = c;
283
+ c = b;
284
+ b = a;
285
+ a = T1 + T2;
286
+
287
+ vd[H4(0)] = f;
288
+ vd[H4(1)] = e;
289
+ vd[H4(2)] = b;
290
+ vd[H4(3)] = a;
291
+}
292
+
293
+void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
294
+ uint32_t desc)
295
+{
296
+ const uint32_t esz = 4;
297
+ uint32_t total_elems;
298
+ uint32_t vta = vext_vta(desc);
299
+
300
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
301
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
302
+ ((uint32_t *)vs1) + 4 * i + 2);
303
+ }
304
+
305
+ /* set tail elements to 1s */
306
+ total_elems = vext_get_total_elems(env, desc, esz);
307
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
308
+ env->vstart = 0;
309
+}
310
+
311
+void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
312
+ uint32_t desc)
313
+{
314
+ const uint32_t esz = 8;
315
+ uint32_t total_elems;
316
+ uint32_t vta = vext_vta(desc);
317
+
318
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
319
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
320
+ ((uint64_t *)vs1) + 4 * i + 2);
321
+ }
322
+
323
+ /* set tail elements to 1s */
324
+ total_elems = vext_get_total_elems(env, desc, esz);
325
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
326
+ env->vstart = 0;
327
+}
328
+
329
+void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
330
+ uint32_t desc)
331
+{
332
+ const uint32_t esz = 4;
333
+ uint32_t total_elems;
334
+ uint32_t vta = vext_vta(desc);
335
+
336
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
337
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
338
+ (((uint32_t *)vs1) + 4 * i));
339
+ }
340
+
341
+ /* set tail elements to 1s */
342
+ total_elems = vext_get_total_elems(env, desc, esz);
343
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
344
+ env->vstart = 0;
345
+}
346
+
347
+void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
348
+ uint32_t desc)
349
+{
350
+ uint32_t esz = 8;
351
+ uint32_t total_elems;
352
+ uint32_t vta = vext_vta(desc);
353
+
354
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
355
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
356
+ (((uint64_t *)vs1) + 4 * i));
357
+ }
358
+
359
+ /* set tail elements to 1s */
360
+ total_elems = vext_get_total_elems(env, desc, esz);
361
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
362
+ env->vstart = 0;
363
+}
364
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
369
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
372
+
373
+/*
374
+ * Zvknh
375
+ */
376
+
377
+#define ZVKNH_EGS 4
378
+
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
381
+ { \
382
+ if (CHECK(s, a)) { \
383
+ uint32_t data = 0; \
384
+ TCGLabel *over = gen_new_label(); \
385
+ TCGv_i32 egs; \
386
+ \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
388
+ /* save opcode for unwinding in case we throw an exception */ \
389
+ decode_save_opc(s); \
390
+ egs = tcg_constant_i32(EGS); \
391
+ gen_helper_egs_check(egs, cpu_env); \
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ } \
394
+ \
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
400
+ \
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
402
+ vreg_ofs(s, a->rs2), cpu_env, \
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
404
+ data, gen_helper_##NAME); \
405
+ \
406
+ mark_vs_dirty(s); \
407
+ gen_set_label(over); \
408
+ return true; \
409
+ } \
410
+ return false; \
411
+ }
412
+
413
+static bool vsha_check_sew(DisasContext *s)
414
+{
415
+ return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
416
+ (s->cfg_ptr->ext_zvknhb == true &&
417
+ (s->sew == MO_32 || s->sew == MO_64));
418
+}
419
+
420
+static bool vsha_check(DisasContext *s, arg_rmrr *a)
421
+{
422
+ int egw_bytes = ZVKNH_EGS << s->sew;
423
+ int mult = 1 << MAX(s->lmul, 0);
424
+ return opivv_check(s, a) &&
425
+ vsha_check_sew(s) &&
426
+ MAXSZ(s) >= egw_bytes &&
427
+ !is_overlapped(a->rd, mult, a->rs1, mult) &&
428
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
429
+ s->lmul >= 0;
430
+}
431
+
432
+GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
433
+
434
+static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
435
+{
436
+ if (vsha_check(s, a)) {
437
+ uint32_t data = 0;
438
+ TCGLabel *over = gen_new_label();
439
+ TCGv_i32 egs;
440
+
441
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
442
+ /* save opcode for unwinding in case we throw an exception */
443
+ decode_save_opc(s);
444
+ egs = tcg_constant_i32(ZVKNH_EGS);
445
+ gen_helper_egs_check(egs, cpu_env);
446
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
447
+ }
448
+
449
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
450
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
451
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
452
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
453
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
454
+
455
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
456
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
457
+ s->cfg_ptr->vlen / 8, data,
458
+ s->sew == MO_32 ?
459
+ gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460
+
461
+ mark_vs_dirty(s);
462
+ gen_set_label(over);
463
+ return true;
464
+ }
465
+ return false;
466
+}
467
+
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
469
+{
470
+ if (vsha_check(s, a)) {
471
+ uint32_t data = 0;
472
+ TCGLabel *over = gen_new_label();
473
+ TCGv_i32 egs;
474
+
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
476
+ /* save opcode for unwinding in case we throw an exception */
477
+ decode_save_opc(s);
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
479
+ gen_helper_egs_check(egs, cpu_env);
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
481
+ }
482
+
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
488
+
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
491
+ s->cfg_ptr->vlen / 8, data,
492
+ s->sew == MO_32 ?
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
494
+
495
+ mark_vs_dirty(s);
496
+ gen_set_label(over);
497
+ return true;
498
+ }
499
+ return false;
500
+}
501
--
502
2.41.0
diff view generated by jsdifflib
New patch
1
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
3
This commit adds support for the Zvksh vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsm3me.vv
7
* vsm3c.vi
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvksh property]
20
Message-ID: <20230711165917.2629866-12-max.chou@sifive.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
target/riscv/cpu_cfg.h | 1 +
24
target/riscv/helper.h | 3 +
25
target/riscv/insn32.decode | 4 +
26
target/riscv/cpu.c | 6 +-
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
29
6 files changed, 177 insertions(+), 2 deletions(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksh;
40
bool ext_zmmul;
41
bool ext_zvfbfmin;
42
bool ext_zvfbfwma;
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
51
+
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/insn32.decode
57
+++ b/target/riscv/insn32.decode
58
@@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
59
vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
61
vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
+
63
+# *** Zvksh vector crypto extension ***
64
+vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
65
+vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/cpu.c
69
+++ b/target/riscv/cpu.c
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
79
* In principle Zve*x would also suffice here, were they supported
80
* in qemu
81
*/
82
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
83
- !cpu->cfg.ext_zve32f) {
84
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
85
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
86
error_setg(errp,
87
"Vector crypto extensions require V or Zve* extensions");
88
return;
89
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
90
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
91
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
92
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
93
+ DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
94
95
DEFINE_PROP_END_OF_LIST(),
96
};
97
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/riscv/vcrypto_helper.c
100
+++ b/target/riscv/vcrypto_helper.c
101
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
102
vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
103
env->vstart = 0;
104
}
105
+
106
+static inline uint32_t p1(uint32_t x)
107
+{
108
+ return x ^ rol32(x, 15) ^ rol32(x, 23);
109
+}
110
+
111
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
112
+ uint32_t m13, uint32_t m6)
113
+{
114
+ return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
115
+}
116
+
117
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
118
+ CPURISCVState *env, uint32_t desc)
119
+{
120
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
121
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
122
+ uint32_t vta = vext_vta(desc);
123
+ uint32_t *vd = vd_vptr;
124
+ uint32_t *vs1 = vs1_vptr;
125
+ uint32_t *vs2 = vs2_vptr;
126
+
127
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
128
+ uint32_t w[24];
129
+ for (int j = 0; j < 8; j++) {
130
+ w[j] = bswap32(vs1[H4((i * 8) + j)]);
131
+ w[j + 8] = bswap32(vs2[H4((i * 8) + j)]);
132
+ }
133
+ for (int j = 0; j < 8; j++) {
134
+ w[j + 16] =
135
+ zvksh_w(w[j], w[j + 7], w[j + 13], w[j + 3], w[j + 10]);
136
+ }
137
+ for (int j = 0; j < 8; j++) {
138
+ vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
139
+ }
140
+ }
141
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
142
+ env->vstart = 0;
143
+}
144
+
145
+static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
146
+{
147
+ return x ^ y ^ z;
148
+}
149
+
150
+static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z)
151
+{
152
+ return (x & y) | (x & z) | (y & z);
153
+}
154
+
155
+static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
156
+{
157
+ return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z);
158
+}
159
+
160
+static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
161
+{
162
+ return x ^ y ^ z;
163
+}
164
+
165
+static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z)
166
+{
167
+ return (x & y) | (~x & z);
168
+}
169
+
170
+static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
171
+{
172
+ return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z);
173
+}
174
+
175
+static inline uint32_t t_j(uint32_t j)
176
+{
177
+ return (j <= 15) ? 0x79cc4519 : 0x7a879d8a;
178
+}
179
+
180
+static inline uint32_t p_0(uint32_t x)
181
+{
182
+ return x ^ rol32(x, 9) ^ rol32(x, 17);
183
+}
184
+
185
+static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm)
186
+{
187
+ uint32_t x0, x1;
188
+ uint32_t j;
189
+ uint32_t ss1, ss2, tt1, tt2;
190
+ x0 = vs2[0] ^ vs2[4];
191
+ x1 = vs2[1] ^ vs2[5];
192
+ j = 2 * uimm;
193
+ ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7);
194
+ ss2 = ss1 ^ rol32(vs1[0], 12);
195
+ tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0;
196
+ tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0];
197
+ vs1[3] = vs1[2];
198
+ vd[3] = rol32(vs1[1], 9);
199
+ vs1[1] = vs1[0];
200
+ vd[1] = tt1;
201
+ vs1[7] = vs1[6];
202
+ vd[7] = rol32(vs1[5], 19);
203
+ vs1[5] = vs1[4];
204
+ vd[5] = p_0(tt2);
205
+ j = 2 * uimm + 1;
206
+ ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7);
207
+ ss2 = ss1 ^ rol32(vd[1], 12);
208
+ tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1;
209
+ tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1];
210
+ vd[2] = rol32(vs1[1], 9);
211
+ vd[0] = tt1;
212
+ vd[6] = rol32(vs1[5], 19);
213
+ vd[4] = p_0(tt2);
214
+}
215
+
216
+void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
217
+ CPURISCVState *env, uint32_t desc)
218
+{
219
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
220
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
221
+ uint32_t vta = vext_vta(desc);
222
+ uint32_t *vd = vd_vptr;
223
+ uint32_t *vs2 = vs2_vptr;
224
+ uint32_t v1[8], v2[8], v3[8];
225
+
226
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
227
+ for (int k = 0; k < 8; k++) {
228
+ v2[k] = bswap32(vd[H4(i * 8 + k)]);
229
+ v3[k] = bswap32(vs2[H4(i * 8 + k)]);
230
+ }
231
+ sm3c(v1, v2, v3, uimm);
232
+ for (int k = 0; k < 8; k++) {
233
+ vd[i * 8 + k] = bswap32(v1[H4(k)]);
234
+ }
235
+ }
236
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
237
+ env->vstart = 0;
238
+}
239
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
242
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
243
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
244
}
245
return false;
246
}
247
+
248
+/*
249
+ * Zvksh
250
+ */
251
+
252
+#define ZVKSH_EGS 8
253
+
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
255
+{
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
257
+ int mult = 1 << MAX(s->lmul, 0);
258
+ return s->cfg_ptr->ext_zvksh == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
262
+ MAXSZ(s) >= egw_bytes &&
263
+ s->sew == MO_32;
264
+}
265
+
266
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
267
+{
268
+ return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
269
+}
270
+
271
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
272
+{
273
+ return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
274
+}
275
+
276
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
277
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
278
--
279
2.41.0
diff view generated by jsdifflib
New patch
1
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
3
This commit adds support for the Zvkg vector-crypto extension, which
4
consists of the following instructions:
5
6
* vgmul.vv
7
* vghsh.vv
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvkg property]
20
[max.chou@sifive.com: Replaced uint by int for cross win32 build]
21
Message-ID: <20230711165917.2629866-13-max.chou@sifive.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu_cfg.h | 1 +
25
target/riscv/helper.h | 3 +
26
target/riscv/insn32.decode | 4 ++
27
target/riscv/cpu.c | 6 +-
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
30
6 files changed, 114 insertions(+), 2 deletions(-)
31
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu_cfg.h
35
+++ b/target/riscv/cpu_cfg.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64d;
38
bool ext_zvbb;
39
bool ext_zvbc;
40
+ bool ext_zvkg;
41
bool ext_zvkned;
42
bool ext_zvknha;
43
bool ext_zvknhb;
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/helper.h
47
+++ b/target/riscv/helper.h
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
49
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
52
+
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/insn32.decode
58
+++ b/target/riscv/insn32.decode
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvksh vector crypto extension ***
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
63
+
64
+# *** Zvkg vector crypto extension ***
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
80
* In principle Zve*x would also suffice here, were they supported
81
* in qemu
82
*/
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
/* Vector cryptography extensions */
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
env->vstart = 0;
105
}
106
+
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
108
+ CPURISCVState *env, uint32_t desc)
109
+{
110
+ uint64_t *vd = vd_vptr;
111
+ uint64_t *vs1 = vs1_vptr;
112
+ uint64_t *vs2 = vs2_vptr;
113
+ uint32_t vta = vext_vta(desc);
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
115
+
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
120
+ uint64_t Z[2] = {0, 0};
121
+
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
123
+
124
+ for (int j = 0; j < 128; j++) {
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
126
+ Z[0] ^= H[0];
127
+ Z[1] ^= H[1];
128
+ }
129
+ bool reduce = ((H[1] >> 63) & 1);
130
+ H[1] = H[1] << 1 | H[0] >> 63;
131
+ H[0] = H[0] << 1;
132
+ if (reduce) {
133
+ H[0] ^= 0x87;
134
+ }
135
+ }
136
+
137
+ vd[i * 2 + 0] = brev8(Z[0]);
138
+ vd[i * 2 + 1] = brev8(Z[1]);
139
+ }
140
+ /* set tail elements to 1s */
141
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
142
+ env->vstart = 0;
143
+}
144
+
145
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
146
+ uint32_t desc)
147
+{
148
+ uint64_t *vd = vd_vptr;
149
+ uint64_t *vs2 = vs2_vptr;
150
+ uint32_t vta = vext_vta(desc);
151
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
152
+
153
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
154
+ uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
155
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
156
+ uint64_t Z[2] = {0, 0};
157
+
158
+ for (int j = 0; j < 128; j++) {
159
+ if ((Y[j / 64] >> (j % 64)) & 1) {
160
+ Z[0] ^= H[0];
161
+ Z[1] ^= H[1];
162
+ }
163
+ bool reduce = ((H[1] >> 63) & 1);
164
+ H[1] = H[1] << 1 | H[0] >> 63;
165
+ H[0] = H[0] << 1;
166
+ if (reduce) {
167
+ H[0] ^= 0x87;
168
+ }
169
+ }
170
+
171
+ vd[i * 2 + 0] = brev8(Z[0]);
172
+ vd[i * 2 + 1] = brev8(Z[1]);
173
+ }
174
+ /* set tail elements to 1s */
175
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
176
+ env->vstart = 0;
177
+}
178
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
183
184
GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
185
GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
186
+
187
+/*
188
+ * Zvkg
189
+ */
190
+
191
+#define ZVKG_EGS 4
192
+
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
194
+{
195
+ int egw_bytes = ZVKG_EGS << s->sew;
196
+ return s->cfg_ptr->ext_zvkg == true &&
197
+ vext_check_isa_ill(s) &&
198
+ require_rvv(s) &&
199
+ MAXSZ(s) >= egw_bytes &&
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
201
+ s->sew == MO_32;
202
+}
203
+
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
205
+
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
207
+{
208
+ int egw_bytes = ZVKG_EGS << s->sew;
209
+ return s->cfg_ptr->ext_zvkg == true &&
210
+ opivv_check(s, a) &&
211
+ MAXSZ(s) >= egw_bytes &&
212
+ s->sew == MO_32;
213
+}
214
+
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
216
--
217
2.41.0
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
We already have some utilities to handle 64-bit wide registers, so this just
3
Allows sharing of sm4_subword between different targets.
4
adds some more for:
5
- Initializing 64-bit registers
6
- Extracting and depositing to an array of 64-bit registers
7
4
8
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
5
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Message-id: 1626805903-162860-2-git-send-email-joe.komlodi@xilinx.com
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
include/hw/register.h | 8 ++++++++
12
include/crypto/sm4.h | 8 ++++++++
14
include/hw/registerfields.h | 8 ++++++++
13
target/arm/tcg/crypto_helper.c | 10 ++--------
15
hw/core/register.c | 12 ++++++++++++
14
2 files changed, 10 insertions(+), 8 deletions(-)
16
3 files changed, 28 insertions(+)
17
15
18
diff --git a/include/hw/register.h b/include/hw/register.h
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/register.h
18
--- a/include/crypto/sm4.h
21
+++ b/include/hw/register.h
19
+++ b/include/crypto/sm4.h
22
@@ -XXX,XX +XXX,XX @@ RegisterInfoArray *register_init_block32(DeviceState *owner,
23
bool debug_enabled,
24
uint64_t memory_size);
25
26
+RegisterInfoArray *register_init_block64(DeviceState *owner,
27
+ const RegisterAccessInfo *rae,
28
+ int num, RegisterInfo *ri,
29
+ uint64_t *data,
30
+ const MemoryRegionOps *ops,
31
+ bool debug_enabled,
32
+ uint64_t memory_size);
33
+
34
/**
35
* This function should be called to cleanup the registers that were initialized
36
* when calling register_init_block32(). This function should only be called
37
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/hw/registerfields.h
40
+++ b/include/hw/registerfields.h
41
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
42
enum { A_ ## reg = (addr) }; \
21
43
enum { R_ ## reg = (addr) / 2 };
22
extern const uint8_t sm4_sbox[256];
44
23
45
+#define REG64(reg, addr) \
24
+static inline uint32_t sm4_subword(uint32_t word)
46
+ enum { A_ ## reg = (addr) }; \
47
+ enum { R_ ## reg = (addr) / 8 };
48
+
49
/* Define SHIFT, LENGTH and MASK constants for a field within a register */
50
51
/* This macro will define R_FOO_BAR_MASK, R_FOO_BAR_SHIFT and R_FOO_BAR_LENGTH
52
@@ -XXX,XX +XXX,XX @@
53
/* Extract a field from an array of registers */
54
#define ARRAY_FIELD_EX32(regs, reg, field) \
55
FIELD_EX32((regs)[R_ ## reg], reg, field)
56
+#define ARRAY_FIELD_EX64(regs, reg, field) \
57
+ FIELD_EX64((regs)[R_ ## reg], reg, field)
58
59
/* Deposit a register field.
60
* Assigning values larger then the target field will result in
61
@@ -XXX,XX +XXX,XX @@
62
/* Deposit a field to array of registers. */
63
#define ARRAY_FIELD_DP32(regs, reg, field, val) \
64
(regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val);
65
+#define ARRAY_FIELD_DP64(regs, reg, field, val) \
66
+ (regs)[R_ ## reg] = FIELD_DP64((regs)[R_ ## reg], reg, field, val);
67
68
#endif
69
diff --git a/hw/core/register.c b/hw/core/register.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/core/register.c
72
+++ b/hw/core/register.c
73
@@ -XXX,XX +XXX,XX @@ RegisterInfoArray *register_init_block32(DeviceState *owner,
74
data, ops, debug_enabled, memory_size, 32);
75
}
76
77
+RegisterInfoArray *register_init_block64(DeviceState *owner,
78
+ const RegisterAccessInfo *rae,
79
+ int num, RegisterInfo *ri,
80
+ uint64_t *data,
81
+ const MemoryRegionOps *ops,
82
+ bool debug_enabled,
83
+ uint64_t memory_size)
84
+{
25
+{
85
+ return register_init_block(owner, rae, num, ri, (void *)
26
+ return sm4_sbox[word & 0xff] |
86
+ data, ops, debug_enabled, memory_size, 64);
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
87
+}
30
+}
88
+
31
+
89
void register_finalize_block(RegisterInfoArray *r_array)
32
#endif
90
{
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
91
object_unparent(OBJECT(&r_array->mem));
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/crypto_helper.c
36
+++ b/target/arm/tcg/crypto_helper.c
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
38
CR_ST_WORD(d, (i + 3) % 4) ^
39
CR_ST_WORD(n, i);
40
41
- t = sm4_sbox[t & 0xff] |
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
45
+ t = sm4_subword(t);
46
47
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
48
rol32(t, 24);
49
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
50
CR_ST_WORD(d, (i + 3) % 4) ^
51
CR_ST_WORD(m, i);
52
53
- t = sm4_sbox[t & 0xff] |
54
- sm4_sbox[(t >> 8) & 0xff] << 8 |
55
- sm4_sbox[(t >> 16) & 0xff] << 16 |
56
- sm4_sbox[(t >> 24) & 0xff] << 24;
57
+ t = sm4_subword(t);
58
59
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
60
}
92
--
61
--
93
2.31.1
62
2.41.0
94
95
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-ID: <20230711165917.2629866-15-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/crypto/sm4.h | 1 +
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
14
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/crypto/sm4.h
18
+++ b/include/crypto/sm4.h
19
@@ -XXX,XX +XXX,XX @@
20
#define QEMU_SM4_H
21
22
extern const uint8_t sm4_sbox[256];
23
+extern const uint32_t sm4_ck[32];
24
25
static inline uint32_t sm4_subword(uint32_t word)
26
{
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/crypto/sm4.c
30
+++ b/crypto/sm4.c
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
33
};
34
35
+uint32_t const sm4_ck[] = {
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
44
+};
45
--
46
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Introduce csrr and csrw helpers, for read-only and write-only insns.
3
This commit adds support for the Zvksed vector-crypto extension, which
4
4
consists of the following instructions:
5
Note that we do not properly implement this in riscv_csrrw, in that
5
6
we cannot distinguish true read-only (rs1 == 0) from any other zero
6
* vsm4k.vi
7
write_mask another source register -- this should still raise an
7
* vsm4r.[vv,vs]
8
exception for read-only registers.
8
9
9
Translation functions are defined in
10
Only issue gen_io_start for CF_USE_ICOUNT.
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
Use ctx->zero for csrrc.
11
`target/riscv/vcrypto_helper.c`.
12
Use get_gpr and dest_gpr.
12
13
13
Signed-off-by: Max Chou <max.chou@sifive.com>
14
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
14
Reviewed-by: Frank Chang <frank.chang@sifive.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
[lawrence.hunter@codethink.co.uk: Moved SM4 functions from
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
crypto_helper.c to vcrypto_helper.c]
17
Message-id: 20210823195529.560295-19-richard.henderson@linaro.org
17
[nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to
18
use macros, and minor style changes]
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Message-ID: <20230711165917.2629866-16-max.chou@sifive.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
22
---
20
target/riscv/helper.h | 6 +-
23
target/riscv/cpu_cfg.h | 1 +
21
target/riscv/op_helper.c | 18 +--
24
target/riscv/helper.h | 4 +
22
target/riscv/insn_trans/trans_rvi.c.inc | 174 +++++++++++++++++-------
25
target/riscv/insn32.decode | 5 +
23
3 files changed, 132 insertions(+), 66 deletions(-)
26
target/riscv/cpu.c | 5 +-
24
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
29
6 files changed, 184 insertions(+), 1 deletion(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksed;
40
bool ext_zvksh;
41
bool ext_zmmul;
42
bool ext_zvfbfmin;
25
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
26
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/helper.h
45
--- a/target/riscv/helper.h
28
+++ b/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
30
DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
48
31
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
32
/* Special functions */
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
33
-DEF_HELPER_3(csrrw, tl, env, tl, tl)
51
+
34
-DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
35
-DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
36
+DEF_HELPER_2(csrr, tl, env, int)
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
37
+DEF_HELPER_3(csrw, void, env, int, tl)
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
38
+DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
56
index XXXXXXX..XXXXXXX 100644
39
#ifndef CONFIG_USER_ONLY
57
--- a/target/riscv/insn32.decode
40
DEF_HELPER_2(sret, tl, env, tl)
58
+++ b/target/riscv/insn32.decode
41
DEF_HELPER_2(mret, tl, env, tl)
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
42
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
60
# *** Zvkg vector crypto extension ***
43
index XXXXXXX..XXXXXXX 100644
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
44
--- a/target/riscv/op_helper.c
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
45
+++ b/target/riscv/op_helper.c
63
+
46
@@ -XXX,XX +XXX,XX @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
64
+# *** Zvksed vector crypto extension ***
47
riscv_raise_exception(env, exception, 0);
65
+vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1
67
+vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
73
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
74
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
75
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
76
+ ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
77
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
78
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
79
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
80
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
81
* in qemu
82
*/
83
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
84
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
86
+ !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
92
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
93
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
94
+ DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
95
DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
96
97
DEFINE_PROP_END_OF_LIST(),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@
103
#include "cpu.h"
104
#include "crypto/aes.h"
105
#include "crypto/aes-round.h"
106
+#include "crypto/sm4.h"
107
#include "exec/memop.h"
108
#include "exec/exec-all.h"
109
#include "exec/helper-proto.h"
110
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
111
vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
112
env->vstart = 0;
48
}
113
}
49
114
+
50
-target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
51
- target_ulong csr)
116
+ uint32_t desc)
52
+target_ulong helper_csrr(CPURISCVState *env, int csr)
117
+{
53
{
118
+ const uint32_t egs = 4;
54
target_ulong val = 0;
119
+ uint32_t rnd = uimm5 & 0x7;
55
- RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
120
+ uint32_t group_start = env->vstart / egs;
56
+ RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
121
+ uint32_t group_end = env->vl / egs;
57
122
+ uint32_t esz = sizeof(uint32_t);
58
if (ret != RISCV_EXCP_NONE) {
123
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
59
riscv_raise_exception(env, ret, GETPC());
124
+
60
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
125
+ for (uint32_t i = group_start; i < group_end; ++i) {
61
return val;
126
+ uint32_t vstart = i * egs;
127
+ uint32_t vend = (i + 1) * egs;
128
+ uint32_t rk[4] = {0};
129
+ uint32_t tmp[8] = {0};
130
+
131
+ for (uint32_t j = vstart; j < vend; ++j) {
132
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
133
+ }
134
+
135
+ for (uint32_t j = 0; j < egs; ++j) {
136
+ tmp[j] = rk[j];
137
+ }
138
+
139
+ for (uint32_t j = 0; j < egs; ++j) {
140
+ uint32_t b, s;
141
+ b = tmp[j + 1] ^ tmp[j + 2] ^ tmp[j + 3] ^ sm4_ck[rnd * 4 + j];
142
+
143
+ s = sm4_subword(b);
144
+
145
+ tmp[j + 4] = tmp[j] ^ (s ^ rol32(s, 13) ^ rol32(s, 23));
146
+ }
147
+
148
+ for (uint32_t j = vstart; j < vend; ++j) {
149
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
150
+ }
151
+ }
152
+
153
+ env->vstart = 0;
154
+ /* set tail elements to 1s */
155
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
156
+}
157
+
158
+static void do_sm4_round(uint32_t *rk, uint32_t *buf)
159
+{
160
+ const uint32_t egs = 4;
161
+ uint32_t s, b;
162
+
163
+ for (uint32_t j = egs; j < egs * 2; ++j) {
164
+ b = buf[j - 3] ^ buf[j - 2] ^ buf[j - 1] ^ rk[j - 4];
165
+
166
+ s = sm4_subword(b);
167
+
168
+ buf[j] = buf[j - 4] ^ (s ^ rol32(s, 2) ^ rol32(s, 10) ^ rol32(s, 18) ^
169
+ rol32(s, 24));
170
+ }
171
+}
172
+
173
+void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
174
+{
175
+ const uint32_t egs = 4;
176
+ uint32_t group_start = env->vstart / egs;
177
+ uint32_t group_end = env->vl / egs;
178
+ uint32_t esz = sizeof(uint32_t);
179
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
180
+
181
+ for (uint32_t i = group_start; i < group_end; ++i) {
182
+ uint32_t vstart = i * egs;
183
+ uint32_t vend = (i + 1) * egs;
184
+ uint32_t rk[4] = {0};
185
+ uint32_t tmp[8] = {0};
186
+
187
+ for (uint32_t j = vstart; j < vend; ++j) {
188
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
189
+ }
190
+
191
+ for (uint32_t j = vstart; j < vend; ++j) {
192
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
193
+ }
194
+
195
+ do_sm4_round(rk, tmp);
196
+
197
+ for (uint32_t j = vstart; j < vend; ++j) {
198
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
199
+ }
200
+ }
201
+
202
+ env->vstart = 0;
203
+ /* set tail elements to 1s */
204
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
205
+}
206
+
207
+void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
208
+{
209
+ const uint32_t egs = 4;
210
+ uint32_t group_start = env->vstart / egs;
211
+ uint32_t group_end = env->vl / egs;
212
+ uint32_t esz = sizeof(uint32_t);
213
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
214
+
215
+ for (uint32_t i = group_start; i < group_end; ++i) {
216
+ uint32_t vstart = i * egs;
217
+ uint32_t vend = (i + 1) * egs;
218
+ uint32_t rk[4] = {0};
219
+ uint32_t tmp[8] = {0};
220
+
221
+ for (uint32_t j = 0; j < egs; ++j) {
222
+ rk[j] = *((uint32_t *)vs2 + H4(j));
223
+ }
224
+
225
+ for (uint32_t j = vstart; j < vend; ++j) {
226
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
227
+ }
228
+
229
+ do_sm4_round(rk, tmp);
230
+
231
+ for (uint32_t j = vstart; j < vend; ++j) {
232
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
233
+ }
234
+ }
235
+
236
+ env->vstart = 0;
237
+ /* set tail elements to 1s */
238
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
239
+}
240
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
241
index XXXXXXX..XXXXXXX 100644
242
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
243
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
244
@@ -XXX,XX +XXX,XX @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a)
62
}
245
}
63
246
64
-target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
65
- target_ulong csr, target_ulong rs1_pass)
248
+
66
+void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
249
+/*
67
{
250
+ * Zvksed
68
- target_ulong val = 0;
251
+ */
69
- RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
252
+
70
+ RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
253
+#define ZVKSED_EGS 4
71
254
+
72
if (ret != RISCV_EXCP_NONE) {
255
+static bool zvksed_check(DisasContext *s)
73
riscv_raise_exception(env, ret, GETPC());
256
+{
74
}
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
75
- return val;
258
+ return s->cfg_ptr->ext_zvksed == true &&
76
}
259
+ require_rvv(s) &&
77
260
+ vext_check_isa_ill(s) &&
78
-target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
261
+ MAXSZ(s) >= egw_bytes &&
79
- target_ulong csr, target_ulong rs1_pass)
262
+ s->sew == MO_32;
80
+target_ulong helper_csrrw(CPURISCVState *env, int csr,
263
+}
81
+ target_ulong src, target_ulong write_mask)
264
+
82
{
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
83
target_ulong val = 0;
266
+{
84
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
267
+ return zvksed_check(s) &&
85
+ RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
268
+ require_align(a->rd, s->lmul) &&
86
269
+ require_align(a->rs2, s->lmul);
87
if (ret != RISCV_EXCP_NONE) {
270
+}
88
riscv_raise_exception(env, ret, GETPC());
271
+
89
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
90
index XXXXXXX..XXXXXXX 100644
273
+
91
--- a/target/riscv/insn_trans/trans_rvi.c.inc
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
92
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
275
+{
93
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
276
+ return zvksed_check(s) &&
94
return true;
277
+ require_align(a->rd, s->lmul) &&
95
}
278
+ require_align(a->rs2, s->lmul);
96
279
+}
97
-#define RISCV_OP_CSR_PRE do {\
280
+
98
- source1 = tcg_temp_new(); \
281
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
99
- csr_store = tcg_temp_new(); \
282
+
100
- dest = tcg_temp_new(); \
283
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
101
- rs1_pass = tcg_temp_new(); \
284
+{
102
- gen_get_gpr(ctx, source1, a->rs1); \
285
+ return zvksed_check(s) &&
103
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
286
+ !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
104
- tcg_gen_movi_tl(rs1_pass, a->rs1); \
287
+ require_align(a->rd, s->lmul);
105
- tcg_gen_movi_tl(csr_store, a->csr); \
288
+}
106
- gen_io_start();\
289
+
107
-} while (0)
290
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)
108
-
109
-#define RISCV_OP_CSR_POST do {\
110
- gen_set_gpr(ctx, a->rd, dest); \
111
- tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
112
- exit_tb(ctx); \
113
- ctx->base.is_jmp = DISAS_NORETURN; \
114
- tcg_temp_free(source1); \
115
- tcg_temp_free(csr_store); \
116
- tcg_temp_free(dest); \
117
- tcg_temp_free(rs1_pass); \
118
-} while (0)
119
+static bool do_csr_post(DisasContext *ctx)
120
+{
121
+ /* We may have changed important cpu state -- exit to main loop. */
122
+ tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
123
+ exit_tb(ctx);
124
+ ctx->base.is_jmp = DISAS_NORETURN;
125
+ return true;
126
+}
127
+
128
+static bool do_csrr(DisasContext *ctx, int rd, int rc)
129
+{
130
+ TCGv dest = dest_gpr(ctx, rd);
131
+ TCGv_i32 csr = tcg_constant_i32(rc);
132
+
133
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
134
+ gen_io_start();
135
+ }
136
+ gen_helper_csrr(dest, cpu_env, csr);
137
+ gen_set_gpr(ctx, rd, dest);
138
+ return do_csr_post(ctx);
139
+}
140
+
141
+static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
142
+{
143
+ TCGv_i32 csr = tcg_constant_i32(rc);
144
145
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
146
+ gen_io_start();
147
+ }
148
+ gen_helper_csrw(cpu_env, csr, src);
149
+ return do_csr_post(ctx);
150
+}
151
+
152
+static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
153
+{
154
+ TCGv dest = dest_gpr(ctx, rd);
155
+ TCGv_i32 csr = tcg_constant_i32(rc);
156
+
157
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
158
+ gen_io_start();
159
+ }
160
+ gen_helper_csrrw(dest, cpu_env, csr, src, mask);
161
+ gen_set_gpr(ctx, rd, dest);
162
+ return do_csr_post(ctx);
163
+}
164
165
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
166
{
167
- TCGv source1, csr_store, dest, rs1_pass;
168
- RISCV_OP_CSR_PRE;
169
- gen_helper_csrrw(dest, cpu_env, source1, csr_store);
170
- RISCV_OP_CSR_POST;
171
- return true;
172
+ TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
173
+
174
+ /*
175
+ * If rd == 0, the insn shall not read the csr, nor cause any of the
176
+ * side effects that might occur on a csr read.
177
+ */
178
+ if (a->rd == 0) {
179
+ return do_csrw(ctx, a->csr, src);
180
+ }
181
+
182
+ TCGv mask = tcg_constant_tl(-1);
183
+ return do_csrrw(ctx, a->rd, a->csr, src, mask);
184
}
185
186
static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
187
{
188
- TCGv source1, csr_store, dest, rs1_pass;
189
- RISCV_OP_CSR_PRE;
190
- gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
191
- RISCV_OP_CSR_POST;
192
- return true;
193
+ /*
194
+ * If rs1 == 0, the insn shall not write to the csr at all, nor
195
+ * cause any of the side effects that might occur on a csr write.
196
+ * Note that if rs1 specifies a register other than x0, holding
197
+ * a zero value, the instruction will still attempt to write the
198
+ * unmodified value back to the csr and will cause side effects.
199
+ */
200
+ if (a->rs1 == 0) {
201
+ return do_csrr(ctx, a->rd, a->csr);
202
+ }
203
+
204
+ TCGv ones = tcg_constant_tl(-1);
205
+ TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
206
+ return do_csrrw(ctx, a->rd, a->csr, ones, mask);
207
}
208
209
static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
210
{
211
- TCGv source1, csr_store, dest, rs1_pass;
212
- RISCV_OP_CSR_PRE;
213
- gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
214
- RISCV_OP_CSR_POST;
215
- return true;
216
+ /*
217
+ * If rs1 == 0, the insn shall not write to the csr at all, nor
218
+ * cause any of the side effects that might occur on a csr write.
219
+ * Note that if rs1 specifies a register other than x0, holding
220
+ * a zero value, the instruction will still attempt to write the
221
+ * unmodified value back to the csr and will cause side effects.
222
+ */
223
+ if (a->rs1 == 0) {
224
+ return do_csrr(ctx, a->rd, a->csr);
225
+ }
226
+
227
+ TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
228
+ return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
229
}
230
231
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
232
{
233
- TCGv source1, csr_store, dest, rs1_pass;
234
- RISCV_OP_CSR_PRE;
235
- gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
236
- RISCV_OP_CSR_POST;
237
- return true;
238
+ TCGv src = tcg_constant_tl(a->rs1);
239
+
240
+ /*
241
+ * If rd == 0, the insn shall not read the csr, nor cause any of the
242
+ * side effects that might occur on a csr read.
243
+ */
244
+ if (a->rd == 0) {
245
+ return do_csrw(ctx, a->csr, src);
246
+ }
247
+
248
+ TCGv mask = tcg_constant_tl(-1);
249
+ return do_csrrw(ctx, a->rd, a->csr, src, mask);
250
}
251
252
static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
253
{
254
- TCGv source1, csr_store, dest, rs1_pass;
255
- RISCV_OP_CSR_PRE;
256
- gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
257
- RISCV_OP_CSR_POST;
258
- return true;
259
+ /*
260
+ * If rs1 == 0, the insn shall not write to the csr at all, nor
261
+ * cause any of the side effects that might occur on a csr write.
262
+ * Note that if rs1 specifies a register other than x0, holding
263
+ * a zero value, the instruction will still attempt to write the
264
+ * unmodified value back to the csr and will cause side effects.
265
+ */
266
+ if (a->rs1 == 0) {
267
+ return do_csrr(ctx, a->rd, a->csr);
268
+ }
269
+
270
+ TCGv ones = tcg_constant_tl(-1);
271
+ TCGv mask = tcg_constant_tl(a->rs1);
272
+ return do_csrrw(ctx, a->rd, a->csr, ones, mask);
273
}
274
275
static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
276
{
277
- TCGv source1, csr_store, dest, rs1_pass;
278
- RISCV_OP_CSR_PRE;
279
- gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
280
- RISCV_OP_CSR_POST;
281
- return true;
282
+ /*
283
+ * If rs1 == 0, the insn shall not write to the csr at all, nor
284
+ * cause any of the side effects that might occur on a csr write.
285
+ * Note that if rs1 specifies a register other than x0, holding
286
+ * a zero value, the instruction will still attempt to write the
287
+ * unmodified value back to the csr and will cause side effects.
288
+ */
289
+ if (a->rs1 == 0) {
290
+ return do_csrr(ctx, a->rd, a->csr);
291
+ }
292
+
293
+ TCGv mask = tcg_constant_tl(a->rs1);
294
+ return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
295
}
296
--
291
--
297
2.31.1
292
2.41.0
298
299
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
We failed to write into *val for these read functions;
3
These are WARL fields - zero out the bits for unavailable counters and
4
replace them with read_zero. Only warn about unsupported
4
special case the TM bit in mcountinhibit which is hardwired to zero.
5
non-zero value when writing a non-zero value.
5
This patch achieves this by modifying the value written so that any use
6
of the field will see the correctly masked bits.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
subsequent read the appropriate number of bits for number of PMUs is
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
enabled and the TM bit is zero in mcountinhibit.
10
Message-id: 20210823195529.560295-18-richard.henderson@linaro.org
11
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
17
---
13
target/riscv/csr.c | 26 ++++++++------------------
18
target/riscv/csr.c | 11 +++++++++--
14
1 file changed, 8 insertions(+), 18 deletions(-)
19
1 file changed, 9 insertions(+), 2 deletions(-)
15
20
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
23
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
24
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
26
{
27
int cidx;
28
PMUCTRState *counter;
29
+ RISCVCPU *cpu = env_archcpu(env);
30
31
- env->mcountinhibit = val;
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
33
+ env->mcountinhibit =
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
35
36
/* Check if any other counter is also monitoring cycles/instructions */
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
44
+
45
+ /* WARL register - disable unavailable counters */
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
47
+ COUNTEREN_IR);
21
return RISCV_EXCP_NONE;
48
return RISCV_EXCP_NONE;
22
}
49
}
23
50
24
-static RISCVException read_hgeie(CPURISCVState *env, int csrno,
25
- target_ulong *val)
26
-{
27
- qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
28
- return RISCV_EXCP_NONE;
29
-}
30
-
31
static RISCVException write_hgeie(CPURISCVState *env, int csrno,
32
target_ulong val)
33
{
34
- qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
35
+ if (val) {
36
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
37
+ }
38
return RISCV_EXCP_NONE;
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static RISCVException write_htinst(CPURISCVState *env, int csrno,
42
return RISCV_EXCP_NONE;
43
}
44
45
-static RISCVException read_hgeip(CPURISCVState *env, int csrno,
46
- target_ulong *val)
47
-{
48
- qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
49
- return RISCV_EXCP_NONE;
50
-}
51
-
52
static RISCVException write_hgeip(CPURISCVState *env, int csrno,
53
target_ulong val)
54
{
55
- qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
56
+ if (val) {
57
+ qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN.");
58
+ }
59
return RISCV_EXCP_NONE;
60
}
61
62
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
63
[CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip },
64
[CSR_HIE] = { "hie", hmode, read_hie, write_hie },
65
[CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren },
66
- [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie },
67
+ [CSR_HGEIE] = { "hgeie", hmode, read_zero, write_hgeie },
68
[CSR_HTVAL] = { "htval", hmode, read_htval, write_htval },
69
[CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst },
70
- [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, write_hgeip },
71
+ [CSR_HGEIP] = { "hgeip", hmode, read_zero, write_hgeip },
72
[CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp },
73
[CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta },
74
[CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah },
75
--
51
--
76
2.31.1
52
2.41.0
77
78
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
RVA23 Profiles states:
4
The RVA23 profiles are intended to be used for 64-bit application
5
processors that will run rich OS stacks from standard binary OS
6
distributions and with a substantial number of third-party binary user
7
applications that will be supported over a considerable length of time
8
in the field.
9
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
11
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
12
purpose is to enable application and operating system portability across
13
different implementations. Thus the DTS should contain the Zihintntl ISA
14
string in order to pass to software.
15
16
The unprivileged spec states:
17
Like any HINTs, these instructions may be freely ignored. Hence, although
18
they are described in terms of cache-based memory hierarchies, they do not
19
mandate the provision of caches.
20
21
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
22
which QEMU already supports, and QEMU does not emulate cache. Therefore
23
these instructions can be considered as a no-op, and we only need to add
24
a new property for the Zihintntl extension.
25
26
Reviewed-by: Frank Chang <frank.chang@sifive.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
32
target/riscv/cpu_cfg.h | 1 +
33
target/riscv/cpu.c | 2 ++
34
2 files changed, 3 insertions(+)
35
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_cfg.h
39
+++ b/target/riscv/cpu_cfg.h
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
41
bool ext_icbom;
42
bool ext_icboz;
43
bool ext_zicond;
44
+ bool ext_zihintntl;
45
bool ext_zihintpause;
46
bool ext_smstateen;
47
bool ext_sstc;
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
68
--
69
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
helper function.
6
Message-id: 20210823195529.560295-22-richard.henderson@linaro.org
6
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
13
---
9
target/riscv/insn_trans/trans_rvf.c.inc | 146 ++++++++++++------------
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
10
1 file changed, 70 insertions(+), 76 deletions(-)
15
1 file changed, 2 insertions(+), 2 deletions(-)
11
16
12
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/insn_trans/trans_rvf.c.inc
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
15
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
17
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
18
static bool trans_flw(DisasContext *ctx, arg_flw *a)
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
19
{
24
20
+ TCGv_i64 dest;
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
21
+ TCGv addr;
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
22
+
27
gen_set_gpr(ctx, a->rd, dest);
23
REQUIRE_FPU;
24
REQUIRE_EXT(ctx, RVF);
25
- TCGv t0 = tcg_temp_new();
26
- gen_get_gpr(ctx, t0, a->rs1);
27
- tcg_gen_addi_tl(t0, t0, a->imm);
28
29
- tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
30
- gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
31
+ addr = get_gpr(ctx, a->rs1, EXT_NONE);
32
+ if (a->imm) {
33
+ TCGv temp = temp_new(ctx);
34
+ tcg_gen_addi_tl(temp, addr, a->imm);
35
+ addr = temp;
36
+ }
37
+
38
+ dest = cpu_fpr[a->rd];
39
+ tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
40
+ gen_nanbox_s(dest, dest);
41
42
- tcg_temp_free(t0);
43
mark_fs_dirty(ctx);
44
return true;
28
return true;
45
}
29
}
46
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
47
static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
48
{
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
49
+ TCGv addr;
33
50
+
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
51
REQUIRE_FPU;
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
52
REQUIRE_EXT(ctx, RVF);
36
gen_set_gpr(ctx, a->rd, dest);
53
- TCGv t0 = tcg_temp_new();
54
- gen_get_gpr(ctx, t0, a->rs1);
55
56
- tcg_gen_addi_tl(t0, t0, a->imm);
57
+ addr = get_gpr(ctx, a->rs1, EXT_NONE);
58
+ if (a->imm) {
59
+ TCGv temp = tcg_temp_new();
60
+ tcg_gen_addi_tl(temp, addr, a->imm);
61
+ addr = temp;
62
+ }
63
64
- tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
65
+ tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
66
67
- tcg_temp_free(t0);
68
return true;
69
}
70
71
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
72
REQUIRE_FPU;
73
REQUIRE_EXT(ctx, RVF);
74
75
- TCGv t0 = tcg_temp_new();
76
- gen_set_rm(ctx, a->rm);
77
- gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
78
- gen_set_gpr(ctx, a->rd, t0);
79
- tcg_temp_free(t0);
80
+ TCGv dest = dest_gpr(ctx, a->rd);
81
82
+ gen_set_rm(ctx, a->rm);
83
+ gen_helper_fcvt_w_s(dest, cpu_env, cpu_fpr[a->rs1]);
84
+ gen_set_gpr(ctx, a->rd, dest);
85
return true;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
89
REQUIRE_FPU;
90
REQUIRE_EXT(ctx, RVF);
91
92
- TCGv t0 = tcg_temp_new();
93
- gen_set_rm(ctx, a->rm);
94
- gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
95
- gen_set_gpr(ctx, a->rd, t0);
96
- tcg_temp_free(t0);
97
+ TCGv dest = dest_gpr(ctx, a->rd);
98
99
+ gen_set_rm(ctx, a->rm);
100
+ gen_helper_fcvt_wu_s(dest, cpu_env, cpu_fpr[a->rs1]);
101
+ gen_set_gpr(ctx, a->rd, dest);
102
return true;
103
}
104
105
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
106
REQUIRE_FPU;
107
REQUIRE_EXT(ctx, RVF);
108
109
- TCGv t0 = tcg_temp_new();
110
+ TCGv dest = dest_gpr(ctx, a->rd);
111
112
#if defined(TARGET_RISCV64)
113
- tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
114
+ tcg_gen_ext32s_tl(dest, cpu_fpr[a->rs1]);
115
#else
116
- tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
117
+ tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]);
118
#endif
119
120
- gen_set_gpr(ctx, a->rd, t0);
121
- tcg_temp_free(t0);
122
-
123
+ gen_set_gpr(ctx, a->rd, dest);
124
return true;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
128
{
129
REQUIRE_FPU;
130
REQUIRE_EXT(ctx, RVF);
131
- TCGv t0 = tcg_temp_new();
132
- gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
133
- gen_set_gpr(ctx, a->rd, t0);
134
- tcg_temp_free(t0);
135
+
136
+ TCGv dest = dest_gpr(ctx, a->rd);
137
+
138
+ gen_helper_feq_s(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
139
+ gen_set_gpr(ctx, a->rd, dest);
140
return true;
141
}
142
143
@@ -XXX,XX +XXX,XX @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
144
{
145
REQUIRE_FPU;
146
REQUIRE_EXT(ctx, RVF);
147
- TCGv t0 = tcg_temp_new();
148
- gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
149
- gen_set_gpr(ctx, a->rd, t0);
150
- tcg_temp_free(t0);
151
+
152
+ TCGv dest = dest_gpr(ctx, a->rd);
153
+
154
+ gen_helper_flt_s(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
155
+ gen_set_gpr(ctx, a->rd, dest);
156
return true;
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
160
{
161
REQUIRE_FPU;
162
REQUIRE_EXT(ctx, RVF);
163
- TCGv t0 = tcg_temp_new();
164
- gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
165
- gen_set_gpr(ctx, a->rd, t0);
166
- tcg_temp_free(t0);
167
+
168
+ TCGv dest = dest_gpr(ctx, a->rd);
169
+
170
+ gen_helper_fle_s(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
171
+ gen_set_gpr(ctx, a->rd, dest);
172
return true;
173
}
174
175
@@ -XXX,XX +XXX,XX @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
176
REQUIRE_FPU;
177
REQUIRE_EXT(ctx, RVF);
178
179
- TCGv t0 = tcg_temp_new();
180
-
181
- gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
182
-
183
- gen_set_gpr(ctx, a->rd, t0);
184
- tcg_temp_free(t0);
185
+ TCGv dest = dest_gpr(ctx, a->rd);
186
187
+ gen_helper_fclass_s(dest, cpu_fpr[a->rs1]);
188
+ gen_set_gpr(ctx, a->rd, dest);
189
return true;
190
}
191
192
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
193
REQUIRE_FPU;
194
REQUIRE_EXT(ctx, RVF);
195
196
- TCGv t0 = tcg_temp_new();
197
- gen_get_gpr(ctx, t0, a->rs1);
198
+ TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
199
200
gen_set_rm(ctx, a->rm);
201
- gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
202
+ gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, src);
203
204
mark_fs_dirty(ctx);
205
- tcg_temp_free(t0);
206
-
207
return true;
208
}
209
210
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
211
REQUIRE_FPU;
212
REQUIRE_EXT(ctx, RVF);
213
214
- TCGv t0 = tcg_temp_new();
215
- gen_get_gpr(ctx, t0, a->rs1);
216
+ TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
217
218
gen_set_rm(ctx, a->rm);
219
- gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
220
+ gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, src);
221
222
mark_fs_dirty(ctx);
223
- tcg_temp_free(t0);
224
-
225
return true;
226
}
227
228
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
229
REQUIRE_FPU;
230
REQUIRE_EXT(ctx, RVF);
231
232
- TCGv t0 = tcg_temp_new();
233
- gen_get_gpr(ctx, t0, a->rs1);
234
+ TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
235
236
- tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
237
+ tcg_gen_extu_tl_i64(cpu_fpr[a->rd], src);
238
gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
239
240
mark_fs_dirty(ctx);
241
- tcg_temp_free(t0);
242
-
243
return true;
244
}
245
246
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
247
REQUIRE_FPU;
248
REQUIRE_EXT(ctx, RVF);
249
250
- TCGv t0 = tcg_temp_new();
251
+ TCGv dest = dest_gpr(ctx, a->rd);
252
+
253
gen_set_rm(ctx, a->rm);
254
- gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
255
- gen_set_gpr(ctx, a->rd, t0);
256
- tcg_temp_free(t0);
257
+ gen_helper_fcvt_l_s(dest, cpu_env, cpu_fpr[a->rs1]);
258
+ gen_set_gpr(ctx, a->rd, dest);
259
return true;
260
}
261
262
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
263
REQUIRE_FPU;
264
REQUIRE_EXT(ctx, RVF);
265
266
- TCGv t0 = tcg_temp_new();
267
+ TCGv dest = dest_gpr(ctx, a->rd);
268
+
269
gen_set_rm(ctx, a->rm);
270
- gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
271
- gen_set_gpr(ctx, a->rd, t0);
272
- tcg_temp_free(t0);
273
+ gen_helper_fcvt_lu_s(dest, cpu_env, cpu_fpr[a->rs1]);
274
+ gen_set_gpr(ctx, a->rd, dest);
275
return true;
276
}
277
278
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
279
REQUIRE_FPU;
280
REQUIRE_EXT(ctx, RVF);
281
282
- TCGv t0 = tcg_temp_new();
283
- gen_get_gpr(ctx, t0, a->rs1);
284
+ TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
285
286
gen_set_rm(ctx, a->rm);
287
- gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
288
+ gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, src);
289
290
mark_fs_dirty(ctx);
291
- tcg_temp_free(t0);
292
return true;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
296
REQUIRE_FPU;
297
REQUIRE_EXT(ctx, RVF);
298
299
- TCGv t0 = tcg_temp_new();
300
- gen_get_gpr(ctx, t0, a->rs1);
301
+ TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
302
303
gen_set_rm(ctx, a->rm);
304
- gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
305
+ gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, src);
306
307
mark_fs_dirty(ctx);
308
- tcg_temp_free(t0);
309
return true;
37
return true;
310
}
38
}
311
--
39
--
312
2.31.1
40
2.41.0
313
314
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
When writing the upper mtime, we should keep the original lower mtime
4
whose value is given by cpu_riscv_read_rtc() instead of
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/riscv_aclint.c | 5 +++--
13
1 file changed, 3 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/riscv_aclint.c
18
+++ b/hw/intc/riscv_aclint.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
20
return;
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
24
25
if (addr == mtimer->time_base) {
26
if (size == 4) {
27
/* time_lo for RV32/RV64 */
28
- mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
29
+ mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
30
} else {
31
/* time for RV64 */
32
mtimer->time_delta = value - rtc_r;
33
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
34
} else {
35
if (size == 4) {
36
/* time_hi for RV32/RV64 */
37
- mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
38
+ mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
39
} else {
40
qemu_log_mask(LOG_GUEST_ERROR,
41
"aclint-mtimer: invalid time_hi write: %08x",
42
--
43
2.41.0
diff view generated by jsdifflib
1
From: Vijai Kumar K <vijai@behindbytes.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Use a dedicated UART config(CONFIG_SHAKTI_UART) to select
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
shakti uart.
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
should be named "rtc_r".
5
6
6
Signed-off-by: Vijai Kumar K <vijai@behindbytes.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210731190229.137483-1-vijai@behindbytes.com
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
hw/char/Kconfig | 3 +++
12
hw/intc/riscv_aclint.c | 6 +++---
12
hw/char/meson.build | 2 +-
13
1 file changed, 3 insertions(+), 3 deletions(-)
13
hw/riscv/Kconfig | 5 +----
14
3 files changed, 5 insertions(+), 5 deletions(-)
15
14
16
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/char/Kconfig
17
--- a/hw/intc/riscv_aclint.c
19
+++ b/hw/char/Kconfig
18
+++ b/hw/intc/riscv_aclint.c
20
@@ -XXX,XX +XXX,XX @@ config SIFIVE_UART
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
21
20
uint64_t next;
22
config GOLDFISH_TTY
21
uint64_t diff;
23
bool
22
24
+
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
25
+config SHAKTI_UART
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
26
+ bool
25
27
diff --git a/hw/char/meson.build b/hw/char/meson.build
26
/* Compute the relative hartid w.r.t the socket */
28
index XXXXXXX..XXXXXXX 100644
27
hartid = hartid - mtimer->hartid_base;
29
--- a/hw/char/meson.build
28
30
+++ b/hw/char/meson.build
29
mtimer->timecmp[hartid] = value;
31
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SERIAL', if_true: files('serial.c'))
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
32
softmmu_ss.add(when: 'CONFIG_SERIAL_ISA', if_true: files('serial-isa.c'))
31
+ if (mtimer->timecmp[hartid] <= rtc) {
33
softmmu_ss.add(when: 'CONFIG_SERIAL_PCI', if_true: files('serial-pci.c'))
32
/*
34
softmmu_ss.add(when: 'CONFIG_SERIAL_PCI_MULTI', if_true: files('serial-pci-multi.c'))
33
* If we're setting an MTIMECMP value in the "past",
35
-softmmu_ss.add(when: 'CONFIG_SHAKTI', if_true: files('shakti_uart.c'))
34
* immediately raise the timer interrupt
36
+softmmu_ss.add(when: 'CONFIG_SHAKTI_UART', if_true: files('shakti_uart.c'))
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
37
softmmu_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-console.c'))
36
38
softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xen_console.c'))
37
/* otherwise, set up the future timer interrupt */
39
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_uartlite.c'))
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
40
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
39
- diff = mtimer->timecmp[hartid] - rtc_r;
41
index XXXXXXX..XXXXXXX 100644
40
+ diff = mtimer->timecmp[hartid] - rtc;
42
--- a/hw/riscv/Kconfig
41
/* back to ns (note args switched in muldiv64) */
43
+++ b/hw/riscv/Kconfig
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
44
@@ -XXX,XX +XXX,XX @@ config OPENTITAN
45
select IBEX
46
select UNIMP
47
48
-config SHAKTI
49
- bool
50
-
51
config SHAKTI_C
52
bool
53
select UNIMP
54
- select SHAKTI
55
+ select SHAKTI_UART
56
select SIFIVE_CLINT
57
select SIFIVE_PLIC
58
43
59
--
44
--
60
2.31.1
45
2.41.0
61
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
3
We should not use types dependend on host arch for target_ucontext.
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
This bug is found when run rv32 applications.
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Message-id: 20210823195529.560295-16-richard.henderson@linaro.org
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
12
---
9
target/riscv/insn_trans/trans_rvi.c.inc | 38 +++++++++++++------------
13
linux-user/riscv/signal.c | 4 ++--
10
1 file changed, 20 insertions(+), 18 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
11
15
12
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/insn_trans/trans_rvi.c.inc
18
--- a/linux-user/riscv/signal.c
15
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
19
+++ b/linux-user/riscv/signal.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
17
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
18
static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
22
19
{
23
struct target_ucontext {
20
- TCGv t0 = tcg_temp_new();
24
- unsigned long uc_flags;
21
- TCGv t1 = tcg_temp_new();
25
- struct target_ucontext *uc_link;
22
- gen_get_gpr(ctx, t0, a->rs1);
26
+ abi_ulong uc_flags;
23
- tcg_gen_addi_tl(t0, t0, a->imm);
27
+ abi_ptr uc_link;
24
-
28
target_stack_t uc_stack;
25
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
29
target_sigset_t uc_sigmask;
26
- gen_set_gpr(ctx, a->rd, t1);
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
27
- tcg_temp_free(t0);
28
- tcg_temp_free(t1);
29
+ TCGv dest = dest_gpr(ctx, a->rd);
30
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
31
+
32
+ if (a->imm) {
33
+ TCGv temp = temp_new(ctx);
34
+ tcg_gen_addi_tl(temp, addr, a->imm);
35
+ addr = temp;
36
+ }
37
+
38
+ tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
39
+ gen_set_gpr(ctx, a->rd, dest);
40
return true;
41
}
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
44
45
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
46
{
47
- TCGv t0 = tcg_temp_new();
48
- TCGv dat = tcg_temp_new();
49
- gen_get_gpr(ctx, t0, a->rs1);
50
- tcg_gen_addi_tl(t0, t0, a->imm);
51
- gen_get_gpr(ctx, dat, a->rs2);
52
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
53
+ TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
54
55
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
56
- tcg_temp_free(t0);
57
- tcg_temp_free(dat);
58
+ if (a->imm) {
59
+ TCGv temp = temp_new(ctx);
60
+ tcg_gen_addi_tl(temp, addr, a->imm);
61
+ addr = temp;
62
+ }
63
+
64
+ tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
65
return true;
66
}
67
68
-
69
static bool trans_sb(DisasContext *ctx, arg_sb *a)
70
{
71
return gen_store(ctx, a, MO_SB);
72
--
31
--
73
2.31.1
32
2.41.0
74
33
75
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Use ctx->w for ctpopw, which is the only one that can
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
re-use the generic algorithm for the narrow operation.
4
remove M mode AIA devices when using KVM acceleration.
5
5
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Message-id: 20210823195529.560295-12-richard.henderson@linaro.org
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
target/riscv/translate.c | 14 ++++++--------
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
12
target/riscv/insn_trans/trans_rvb.c.inc | 24 +++++++++---------------
14
1 file changed, 137 insertions(+), 153 deletions(-)
13
2 files changed, 15 insertions(+), 23 deletions(-)
14
15
15
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/translate.c
18
--- a/hw/riscv/virt.c
18
+++ b/target/riscv/translate.c
19
+++ b/hw/riscv/virt.c
19
@@ -XXX,XX +XXX,XX @@ static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
20
return true;
21
return ret;
21
}
22
}
22
23
23
-static bool gen_unary(DisasContext *ctx, arg_r2 *a,
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
24
- void(*func)(TCGv, TCGv))
25
- uint32_t *phandle, uint32_t *intc_phandles,
25
+static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
26
+ void (*func)(TCGv, TCGv))
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
29
+ bool m_mode, uint32_t imsic_guest_bits)
27
{
30
{
28
- TCGv source = tcg_temp_new();
31
int cpu, socket;
32
char *imsic_name;
33
MachineState *ms = MACHINE(s);
34
int socket_count = riscv_socket_count(ms);
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
36
+ uint32_t imsic_max_hart_per_socket;
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
38
39
- *msi_m_phandle = (*phandle)++;
40
- *msi_s_phandle = (*phandle)++;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
43
44
- /* M-level IMSIC node */
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
49
}
50
- imsic_max_hart_per_socket = 0;
51
- for (socket = 0; socket < socket_count; socket++) {
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
55
- imsic_regs[socket * 4 + 0] = 0;
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
57
- imsic_regs[socket * 4 + 2] = 0;
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
61
- }
62
- }
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
67
- "riscv,imsics");
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
69
- FDT_IMSIC_INT_CELLS);
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
71
- NULL, 0);
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
73
- NULL, 0);
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
77
- socket_count * sizeof(uint32_t) * 4);
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
79
- VIRT_IRQCHIP_NUM_MSIS);
80
- if (socket_count > 1) {
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
82
- imsic_num_bits(imsic_max_hart_per_socket));
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
84
- imsic_num_bits(socket_count));
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
87
- }
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
29
-
89
-
30
- gen_get_gpr(ctx, source, a->rs1);
90
- g_free(imsic_name);
31
+ TCGv dest = dest_gpr(ctx, a->rd);
91
32
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
92
- /* S-level IMSIC node */
33
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
34
- (*func)(source, source);
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
35
+ func(dest, src1);
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
36
96
- }
37
- gen_set_gpr(ctx, a->rd, source);
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
38
- tcg_temp_free(source);
98
imsic_max_hart_per_socket = 0;
39
+ gen_set_gpr(ctx, a->rd, dest);
99
for (socket = 0; socket < socket_count; socket++) {
40
return true;
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
101
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
102
+ imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
103
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
104
s->soc[socket].num_harts;
105
imsic_regs[socket * 4 + 0] = 0;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
107
imsic_max_hart_per_socket = s->soc[socket].num_harts;
108
}
109
}
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
112
+
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
116
- "riscv,imsics");
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
118
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
119
- FDT_IMSIC_INT_CELLS);
120
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
121
- NULL, 0);
122
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
123
- NULL, 0);
124
+ FDT_IMSIC_INT_CELLS);
125
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
126
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
127
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
128
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
129
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
130
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
131
- socket_count * sizeof(uint32_t) * 4);
132
+ socket_count * sizeof(uint32_t) * 4);
133
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
134
- VIRT_IRQCHIP_NUM_MSIS);
135
+ VIRT_IRQCHIP_NUM_MSIS);
136
+
137
if (imsic_guest_bits) {
138
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
139
- imsic_guest_bits);
140
+ imsic_guest_bits);
141
}
142
+
143
if (socket_count > 1) {
144
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
145
- imsic_num_bits(imsic_max_hart_per_socket));
146
+ imsic_num_bits(imsic_max_hart_per_socket));
147
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
148
- imsic_num_bits(socket_count));
149
+ imsic_num_bits(socket_count));
150
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
151
- IMSIC_MMIO_GROUP_MIN_SHIFT);
152
+ IMSIC_MMIO_GROUP_MIN_SHIFT);
153
}
154
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
155
- g_free(imsic_name);
156
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
157
158
+ g_free(imsic_name);
159
g_free(imsic_regs);
160
g_free(imsic_cells);
41
}
161
}
42
162
43
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
163
-static void create_fdt_socket_aplic(RISCVVirtState *s,
44
index XXXXXXX..XXXXXXX 100644
164
- const MemMapEntry *memmap, int socket,
45
--- a/target/riscv/insn_trans/trans_rvb.c.inc
165
- uint32_t msi_m_phandle,
46
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
166
- uint32_t msi_s_phandle,
47
@@ -XXX,XX +XXX,XX @@ static void gen_clz(TCGv ret, TCGv arg1)
167
- uint32_t *phandle,
48
static bool trans_clz(DisasContext *ctx, arg_clz *a)
168
- uint32_t *intc_phandles,
169
- uint32_t *aplic_phandles)
170
+static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
171
+ uint32_t *phandle, uint32_t *intc_phandles,
172
+ uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
173
+{
174
+ *msi_m_phandle = (*phandle)++;
175
+ *msi_s_phandle = (*phandle)++;
176
+
177
+ if (!kvm_enabled()) {
178
+ /* M-level IMSIC node */
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
180
+ *msi_m_phandle, true, 0);
181
+ }
182
+
183
+ /* S-level IMSIC node */
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
185
+ *msi_s_phandle, false,
186
+ imsic_num_bits(s->aia_guests + 1));
187
+
188
+}
189
+
190
+static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
191
+ unsigned long aplic_addr, uint32_t aplic_size,
192
+ uint32_t msi_phandle,
193
+ uint32_t *intc_phandles,
194
+ uint32_t aplic_phandle,
195
+ uint32_t aplic_child_phandle,
196
+ bool m_mode)
49
{
197
{
50
REQUIRE_EXT(ctx, RVB);
198
int cpu;
51
- return gen_unary(ctx, a, gen_clz);
199
char *aplic_name;
52
+ return gen_unary(ctx, a, EXT_ZERO, gen_clz);
200
uint32_t *aplic_cells;
201
- unsigned long aplic_addr;
202
MachineState *ms = MACHINE(s);
203
- uint32_t aplic_m_phandle, aplic_s_phandle;
204
205
- aplic_m_phandle = (*phandle)++;
206
- aplic_s_phandle = (*phandle)++;
207
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
208
209
- /* M-level APLIC node */
210
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
211
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
212
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
213
+ aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
214
}
215
- aplic_addr = memmap[VIRT_APLIC_M].base +
216
- (memmap[VIRT_APLIC_M].size * socket);
217
+
218
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
219
qemu_fdt_add_subnode(ms->fdt, aplic_name);
220
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
221
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
222
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
223
+ "#interrupt-cells", FDT_APLIC_INT_CELLS);
224
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
225
+
226
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
227
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
228
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
229
+ aplic_cells,
230
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
231
} else {
232
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
233
- msi_m_phandle);
234
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
235
}
236
+
237
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
238
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
239
+ 0x0, aplic_addr, 0x0, aplic_size);
240
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
241
- VIRT_IRQCHIP_NUM_SOURCES);
242
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
243
- aplic_s_phandle);
244
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
245
- aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
246
+ VIRT_IRQCHIP_NUM_SOURCES);
247
+
248
+ if (aplic_child_phandle) {
249
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
250
+ aplic_child_phandle);
251
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
252
+ aplic_child_phandle, 0x1,
253
+ VIRT_IRQCHIP_NUM_SOURCES);
254
+ }
255
+
256
riscv_socket_fdt_write_id(ms, aplic_name, socket);
257
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
258
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
259
+
260
g_free(aplic_name);
261
+ g_free(aplic_cells);
262
+}
263
264
- /* S-level APLIC node */
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
269
+ const MemMapEntry *memmap, int socket,
270
+ uint32_t msi_m_phandle,
271
+ uint32_t msi_s_phandle,
272
+ uint32_t *phandle,
273
+ uint32_t *intc_phandles,
274
+ uint32_t *aplic_phandles)
275
+{
276
+ char *aplic_name;
277
+ unsigned long aplic_addr;
278
+ MachineState *ms = MACHINE(s);
279
+ uint32_t aplic_m_phandle, aplic_s_phandle;
280
+
281
+ aplic_m_phandle = (*phandle)++;
282
+ aplic_s_phandle = (*phandle)++;
283
+
284
+ if (!kvm_enabled()) {
285
+ /* M-level APLIC node */
286
+ aplic_addr = memmap[VIRT_APLIC_M].base +
287
+ (memmap[VIRT_APLIC_M].size * socket);
288
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
289
+ msi_m_phandle, intc_phandles,
290
+ aplic_m_phandle, aplic_s_phandle,
291
+ true);
292
}
293
+
294
+ /* S-level APLIC node */
295
aplic_addr = memmap[VIRT_APLIC_S].base +
296
(memmap[VIRT_APLIC_S].size * socket);
297
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
298
+ msi_s_phandle, intc_phandles,
299
+ aplic_s_phandle, 0,
300
+ false);
301
+
302
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
303
- qemu_fdt_add_subnode(ms->fdt, aplic_name);
304
- qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
305
- qemu_fdt_setprop_cell(ms->fdt, aplic_name,
306
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
307
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
308
- if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
309
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
310
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
311
- } else {
312
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
313
- msi_s_phandle);
314
- }
315
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
316
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
317
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
318
- VIRT_IRQCHIP_NUM_SOURCES);
319
- riscv_socket_fdt_write_id(ms, aplic_name, socket);
320
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
321
322
if (!socket) {
323
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
324
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
325
326
g_free(aplic_name);
327
328
- g_free(aplic_cells);
329
aplic_phandles[socket] = aplic_s_phandle;
53
}
330
}
54
331
55
static void gen_ctz(TCGv ret, TCGv arg1)
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
56
@@ -XXX,XX +XXX,XX @@ static void gen_ctz(TCGv ret, TCGv arg1)
333
int i;
57
static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
334
hwaddr addr;
58
{
335
uint32_t guest_bits;
59
REQUIRE_EXT(ctx, RVB);
336
- DeviceState *aplic_m;
60
- return gen_unary(ctx, a, gen_ctz);
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
61
+ return gen_unary(ctx, a, EXT_ZERO, gen_ctz);
338
+ DeviceState *aplic_s = NULL;
339
+ DeviceState *aplic_m = NULL;
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
341
342
if (msimode) {
343
- /* Per-socket M-level IMSICs */
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
345
- for (i = 0; i < hart_count; i++) {
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
347
- base_hartid + i, true, 1,
348
- VIRT_IRQCHIP_NUM_MSIS);
349
+ if (!kvm_enabled()) {
350
+ /* Per-socket M-level IMSICs */
351
+ addr = memmap[VIRT_IMSIC_M].base +
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
353
+ for (i = 0; i < hart_count; i++) {
354
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
355
+ base_hartid + i, true, 1,
356
+ VIRT_IRQCHIP_NUM_MSIS);
357
+ }
358
}
359
360
/* Per-socket S-level IMSICs */
361
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
362
}
363
}
364
365
- /* Per-socket M-level APLIC */
366
- aplic_m = riscv_aplic_create(
367
- memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
368
- memmap[VIRT_APLIC_M].size,
369
- (msimode) ? 0 : base_hartid,
370
- (msimode) ? 0 : hart_count,
371
- VIRT_IRQCHIP_NUM_SOURCES,
372
- VIRT_IRQCHIP_NUM_PRIO_BITS,
373
- msimode, true, NULL);
374
-
375
- if (aplic_m) {
376
- /* Per-socket S-level APLIC */
377
- riscv_aplic_create(
378
- memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
379
- memmap[VIRT_APLIC_S].size,
380
- (msimode) ? 0 : base_hartid,
381
- (msimode) ? 0 : hart_count,
382
- VIRT_IRQCHIP_NUM_SOURCES,
383
- VIRT_IRQCHIP_NUM_PRIO_BITS,
384
- msimode, false, aplic_m);
385
+ if (!kvm_enabled()) {
386
+ /* Per-socket M-level APLIC */
387
+ aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
388
+ socket * memmap[VIRT_APLIC_M].size,
389
+ memmap[VIRT_APLIC_M].size,
390
+ (msimode) ? 0 : base_hartid,
391
+ (msimode) ? 0 : hart_count,
392
+ VIRT_IRQCHIP_NUM_SOURCES,
393
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
394
+ msimode, true, NULL);
395
}
396
397
- return aplic_m;
398
+ /* Per-socket S-level APLIC */
399
+ aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
400
+ socket * memmap[VIRT_APLIC_S].size,
401
+ memmap[VIRT_APLIC_S].size,
402
+ (msimode) ? 0 : base_hartid,
403
+ (msimode) ? 0 : hart_count,
404
+ VIRT_IRQCHIP_NUM_SOURCES,
405
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
406
+ msimode, false, aplic_m);
407
+
408
+ return kvm_enabled() ? aplic_s : aplic_m;
62
}
409
}
63
410
64
static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
65
{
66
REQUIRE_EXT(ctx, RVB);
67
- return gen_unary(ctx, a, tcg_gen_ctpop_tl);
68
+ return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
69
}
70
71
static bool trans_andn(DisasContext *ctx, arg_andn *a)
72
@@ -XXX,XX +XXX,XX @@ static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
73
static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
74
{
75
REQUIRE_EXT(ctx, RVB);
76
- return gen_unary(ctx, a, tcg_gen_ext8s_tl);
77
+ return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
78
}
79
80
static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
81
{
82
REQUIRE_EXT(ctx, RVB);
83
- return gen_unary(ctx, a, tcg_gen_ext16s_tl);
84
+ return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
85
}
86
87
static void gen_sbop_mask(TCGv ret, TCGv shamt)
88
@@ -XXX,XX +XXX,XX @@ GEN_TRANS_SHADD(3)
89
90
static void gen_clzw(TCGv ret, TCGv arg1)
91
{
92
- tcg_gen_ext32u_tl(ret, arg1);
93
tcg_gen_clzi_tl(ret, ret, 64);
94
tcg_gen_subi_tl(ret, ret, 32);
95
}
96
@@ -XXX,XX +XXX,XX @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
97
{
98
REQUIRE_64BIT(ctx);
99
REQUIRE_EXT(ctx, RVB);
100
- return gen_unary(ctx, a, gen_clzw);
101
+ return gen_unary(ctx, a, EXT_ZERO, gen_clzw);
102
}
103
104
static void gen_ctzw(TCGv ret, TCGv arg1)
105
@@ -XXX,XX +XXX,XX @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
106
{
107
REQUIRE_64BIT(ctx);
108
REQUIRE_EXT(ctx, RVB);
109
- return gen_unary(ctx, a, gen_ctzw);
110
-}
111
-
112
-static void gen_cpopw(TCGv ret, TCGv arg1)
113
-{
114
- tcg_gen_ext32u_tl(arg1, arg1);
115
- tcg_gen_ctpop_tl(ret, arg1);
116
+ return gen_unary(ctx, a, EXT_NONE, gen_ctzw);
117
}
118
119
static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
120
{
121
REQUIRE_64BIT(ctx);
122
REQUIRE_EXT(ctx, RVB);
123
- return gen_unary(ctx, a, gen_cpopw);
124
+ ctx->w = true;
125
+ return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
126
}
127
128
static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
129
--
412
--
130
2.31.1
413
2.41.0
131
132
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Utilize the condition in the movcond more; this allows some of
3
We check the in-kernel irqchip support when using KVM acceleration.
4
the setcond that were feeding into movcond to be removed.
5
Do not write into source1 and source2. Re-name "condN" to "tempN"
6
and use the temporaries for more than holding conditions.
7
4
8
Tested-by: Bin Meng <bmeng.cn@gmail.com>
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
9
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Message-id: 20210823195529.560295-4-richard.henderson@linaro.org
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
11
---
15
target/riscv/translate.c | 174 ++++++++++++++++++++-------------------
12
target/riscv/kvm.c | 10 +++++++++-
16
1 file changed, 91 insertions(+), 83 deletions(-)
13
1 file changed, 9 insertions(+), 1 deletion(-)
17
14
18
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/translate.c
17
--- a/target/riscv/kvm.c
21
+++ b/target/riscv/translate.c
18
+++ b/target/riscv/kvm.c
22
@@ -XXX,XX +XXX,XX @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
23
20
24
static void gen_div(TCGv ret, TCGv source1, TCGv source2)
21
int kvm_arch_irqchip_create(KVMState *s)
25
{
22
{
26
- TCGv cond1, cond2, zeroreg, resultopt1;
23
- return 0;
27
+ TCGv temp1, temp2, zero, one, mone, min;
24
+ if (kvm_kernel_irqchip_split()) {
28
+
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
29
+ temp1 = tcg_temp_new();
26
+ exit(1);
30
+ temp2 = tcg_temp_new();
27
+ }
31
+ zero = tcg_constant_tl(0);
32
+ one = tcg_constant_tl(1);
33
+ mone = tcg_constant_tl(-1);
34
+ min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
35
+
36
/*
37
- * Handle by altering args to tcg_gen_div to produce req'd results:
38
- * For overflow: want source1 in source1 and 1 in source2
39
- * For div by zero: want -1 in source1 and 1 in source2 -> -1 result
40
+ * If overflow, set temp2 to 1, else source2.
41
+ * This produces the required result of min.
42
*/
43
- cond1 = tcg_temp_new();
44
- cond2 = tcg_temp_new();
45
- zeroreg = tcg_constant_tl(0);
46
- resultopt1 = tcg_temp_new();
47
-
48
- tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
49
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)(~0L));
50
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
51
- ((target_ulong)1) << (TARGET_LONG_BITS - 1));
52
- tcg_gen_and_tl(cond1, cond1, cond2); /* cond1 = overflow */
53
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, 0); /* cond2 = div 0 */
54
- /* if div by zero, set source1 to -1, otherwise don't change */
55
- tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond2, zeroreg, source1,
56
- resultopt1);
57
- /* if overflow or div by zero, set source2 to 1, else don't change */
58
- tcg_gen_or_tl(cond1, cond1, cond2);
59
- tcg_gen_movi_tl(resultopt1, (target_ulong)1);
60
- tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
61
- resultopt1);
62
- tcg_gen_div_tl(ret, source1, source2);
63
-
64
- tcg_temp_free(cond1);
65
- tcg_temp_free(cond2);
66
- tcg_temp_free(resultopt1);
67
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
68
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
69
+ tcg_gen_and_tl(temp1, temp1, temp2);
70
+ tcg_gen_movcond_tl(TCG_COND_NE, temp2, temp1, zero, one, source2);
71
+
28
+
72
+ /*
29
+ /*
73
+ * If div by zero, set temp1 to -1 and temp2 to 1 to
30
+ * We can create the VAIA using the newer device control API.
74
+ * produce the required result of -1.
75
+ */
31
+ */
76
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, mone, source1);
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
77
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, temp2);
78
+
79
+ tcg_gen_div_tl(ret, temp1, temp2);
80
+
81
+ tcg_temp_free(temp1);
82
+ tcg_temp_free(temp2);
83
}
33
}
84
34
85
static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
35
int kvm_arch_process_async_events(CPUState *cs)
86
{
87
- TCGv cond1, zeroreg, resultopt1;
88
- cond1 = tcg_temp_new();
89
+ TCGv temp1, temp2, zero, one, max;
90
91
- zeroreg = tcg_constant_tl(0);
92
- resultopt1 = tcg_temp_new();
93
+ temp1 = tcg_temp_new();
94
+ temp2 = tcg_temp_new();
95
+ zero = tcg_constant_tl(0);
96
+ one = tcg_constant_tl(1);
97
+ max = tcg_constant_tl(~0);
98
99
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
100
- tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
101
- tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, source1,
102
- resultopt1);
103
- tcg_gen_movi_tl(resultopt1, (target_ulong)1);
104
- tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
105
- resultopt1);
106
- tcg_gen_divu_tl(ret, source1, source2);
107
+ /*
108
+ * If div by zero, set temp1 to max and temp2 to 1 to
109
+ * produce the required result of max.
110
+ */
111
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, max, source1);
112
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
113
+ tcg_gen_divu_tl(ret, temp1, temp2);
114
115
- tcg_temp_free(cond1);
116
- tcg_temp_free(resultopt1);
117
+ tcg_temp_free(temp1);
118
+ tcg_temp_free(temp2);
119
}
120
121
static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
122
{
123
- TCGv cond1, cond2, zeroreg, resultopt1;
124
-
125
- cond1 = tcg_temp_new();
126
- cond2 = tcg_temp_new();
127
- zeroreg = tcg_constant_tl(0);
128
- resultopt1 = tcg_temp_new();
129
-
130
- tcg_gen_movi_tl(resultopt1, 1L);
131
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)-1);
132
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
133
- (target_ulong)1 << (TARGET_LONG_BITS - 1));
134
- tcg_gen_and_tl(cond2, cond1, cond2); /* cond1 = overflow */
135
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0); /* cond2 = div 0 */
136
- /* if overflow or div by zero, set source2 to 1, else don't change */
137
- tcg_gen_or_tl(cond2, cond1, cond2);
138
- tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond2, zeroreg, source2,
139
- resultopt1);
140
- tcg_gen_rem_tl(resultopt1, source1, source2);
141
- /* if div by zero, just return the original dividend */
142
- tcg_gen_movcond_tl(TCG_COND_EQ, ret, cond1, zeroreg, resultopt1,
143
- source1);
144
-
145
- tcg_temp_free(cond1);
146
- tcg_temp_free(cond2);
147
- tcg_temp_free(resultopt1);
148
+ TCGv temp1, temp2, zero, one, mone, min;
149
+
150
+ temp1 = tcg_temp_new();
151
+ temp2 = tcg_temp_new();
152
+ zero = tcg_constant_tl(0);
153
+ one = tcg_constant_tl(1);
154
+ mone = tcg_constant_tl(-1);
155
+ min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
156
+
157
+ /*
158
+ * If overflow, set temp1 to 0, else source1.
159
+ * This avoids a possible host trap, and produces the required result of 0.
160
+ */
161
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
162
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
163
+ tcg_gen_and_tl(temp1, temp1, temp2);
164
+ tcg_gen_movcond_tl(TCG_COND_NE, temp1, temp1, zero, zero, source1);
165
+
166
+ /*
167
+ * If div by zero, set temp2 to 1, else source2.
168
+ * This avoids a possible host trap, but produces an incorrect result.
169
+ */
170
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
171
+
172
+ tcg_gen_rem_tl(temp1, temp1, temp2);
173
+
174
+ /* If div by zero, the required result is the original dividend. */
175
+ tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp1);
176
+
177
+ tcg_temp_free(temp1);
178
+ tcg_temp_free(temp2);
179
}
180
181
static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
182
{
183
- TCGv cond1, zeroreg, resultopt1;
184
- cond1 = tcg_temp_new();
185
- zeroreg = tcg_constant_tl(0);
186
- resultopt1 = tcg_temp_new();
187
-
188
- tcg_gen_movi_tl(resultopt1, (target_ulong)1);
189
- tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
190
- tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
191
- resultopt1);
192
- tcg_gen_remu_tl(resultopt1, source1, source2);
193
- /* if div by zero, just return the original dividend */
194
- tcg_gen_movcond_tl(TCG_COND_EQ, ret, cond1, zeroreg, resultopt1,
195
- source1);
196
-
197
- tcg_temp_free(cond1);
198
- tcg_temp_free(resultopt1);
199
+ TCGv temp, zero, one;
200
+
201
+ temp = tcg_temp_new();
202
+ zero = tcg_constant_tl(0);
203
+ one = tcg_constant_tl(1);
204
+
205
+ /*
206
+ * If div by zero, set temp to 1, else source2.
207
+ * This avoids a possible host trap, but produces an incorrect result.
208
+ */
209
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp, source2, zero, one, source2);
210
+
211
+ tcg_gen_remu_tl(temp, source1, temp);
212
+
213
+ /* If div by zero, the required result is the original dividend. */
214
+ tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp);
215
+
216
+ tcg_temp_free(temp);
217
}
218
219
static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
220
--
36
--
221
2.31.1
37
2.41.0
222
223
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Use ctx->w and the enhanced gen_arith function.
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
5
We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia"
6
parameter is passed along with --accel in QEMU command-line.
7
1) "riscv-aia=emul": IMSIC is emulated by hypervisor
8
2) "riscv-aia=hwaccel": use hardware guest IMSIC
9
3) "riscv-aia=auto": use the hardware guest IMSICs whenever available
10
otherwise we fallback to software emulation.
4
11
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-id: 20210823195529.560295-8-richard.henderson@linaro.org
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
18
---
11
target/riscv/translate.c | 42 -------------------------
19
target/riscv/kvm_riscv.h | 4 +
12
target/riscv/insn_trans/trans_rvm.c.inc | 16 +++++-----
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
13
2 files changed, 8 insertions(+), 50 deletions(-)
21
2 files changed, 190 insertions(+)
14
22
15
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/translate.c
25
--- a/target/riscv/kvm_riscv.h
18
+++ b/target/riscv/translate.c
26
+++ b/target/riscv/kvm_riscv.h
19
@@ -XXX,XX +XXX,XX @@ static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
27
@@ -XXX,XX +XXX,XX @@
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
33
+ uint64_t aplic_base, uint64_t imsic_base,
34
+ uint64_t guest_num);
35
36
#endif
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/kvm.c
40
+++ b/target/riscv/kvm.c
41
@@ -XXX,XX +XXX,XX @@
42
#include "exec/address-spaces.h"
43
#include "hw/boards.h"
44
#include "hw/irq.h"
45
+#include "hw/intc/riscv_imsic.h"
46
#include "qemu/log.h"
47
#include "hw/loader.h"
48
#include "kvm_riscv.h"
49
@@ -XXX,XX +XXX,XX @@
50
#include "chardev/char-fe.h"
51
#include "migration/migration.h"
52
#include "sysemu/runstate.h"
53
+#include "hw/riscv/numa.h"
54
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
56
uint64_t idx)
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
20
return true;
58
return true;
21
}
59
}
22
60
23
-static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
61
+static int aia_mode;
24
- void(*func)(TCGv, TCGv, TCGv))
62
+
25
-{
63
+static const char *kvm_aia_mode_str(uint64_t mode)
26
- TCGv source1, source2;
64
+{
27
- source1 = tcg_temp_new();
65
+ switch (mode) {
28
- source2 = tcg_temp_new();
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
29
-
67
+ return "emul";
30
- gen_get_gpr(ctx, source1, a->rs1);
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
31
- gen_get_gpr(ctx, source2, a->rs2);
69
+ return "hwaccel";
32
- tcg_gen_ext32s_tl(source1, source1);
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
33
- tcg_gen_ext32s_tl(source2, source2);
71
+ default:
34
-
72
+ return "auto";
35
- (*func)(source1, source1, source2);
73
+ };
36
-
74
+}
37
- tcg_gen_ext32s_tl(source1, source1);
75
+
38
- gen_set_gpr(ctx, a->rd, source1);
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
39
- tcg_temp_free(source1);
77
+{
40
- tcg_temp_free(source2);
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
41
- return true;
79
+}
42
-}
80
+
43
-
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
44
-static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
82
+{
45
- void(*func)(TCGv, TCGv, TCGv))
83
+ if (!strcmp(val, "emul")) {
46
-{
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
47
- TCGv source1, source2;
85
+ } else if (!strcmp(val, "hwaccel")) {
48
- source1 = tcg_temp_new();
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
49
- source2 = tcg_temp_new();
87
+ } else if (!strcmp(val, "auto")) {
50
-
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
51
- gen_get_gpr(ctx, source1, a->rs1);
89
+ } else {
52
- gen_get_gpr(ctx, source2, a->rs2);
90
+ error_setg(errp, "Invalid KVM AIA mode");
53
- tcg_gen_ext32u_tl(source1, source1);
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
54
- tcg_gen_ext32u_tl(source2, source2);
92
+ }
55
-
93
+}
56
- (*func)(source1, source1, source2);
94
+
57
-
95
void kvm_arch_accel_class_init(ObjectClass *oc)
58
- tcg_gen_ext32s_tl(source1, source1);
59
- gen_set_gpr(ctx, a->rd, source1);
60
- tcg_temp_free(source1);
61
- tcg_temp_free(source2);
62
- return true;
63
-}
64
-
65
static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
66
{
96
{
67
tcg_gen_deposit_tl(ret, arg1, arg2,
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
68
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
98
+ riscv_set_kvm_aia);
69
index XXXXXXX..XXXXXXX 100644
99
+ object_class_property_set_description(oc, "riscv-aia",
70
--- a/target/riscv/insn_trans/trans_rvm.c.inc
100
+ "Set KVM AIA mode. Valid values are "
71
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
101
+ "emul, hwaccel, and auto. Default "
72
@@ -XXX,XX +XXX,XX @@ static bool trans_divw(DisasContext *ctx, arg_divw *a)
102
+ "is auto.");
73
{
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
74
REQUIRE_64BIT(ctx);
104
+ "auto");
75
REQUIRE_EXT(ctx, RVM);
105
+}
76
-
106
+
77
- return gen_arith_div_w(ctx, a, &gen_div);
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
78
+ ctx->w = true;
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
79
+ return gen_arith(ctx, a, EXT_SIGN, gen_div);
109
+ uint64_t aplic_base, uint64_t imsic_base,
80
}
110
+ uint64_t guest_num)
81
111
+{
82
static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
112
+ int ret, i;
83
{
113
+ int aia_fd = -1;
84
REQUIRE_64BIT(ctx);
114
+ uint64_t default_aia_mode;
85
REQUIRE_EXT(ctx, RVM);
115
+ uint64_t socket_count = riscv_socket_count(machine);
86
-
116
+ uint64_t max_hart_per_socket = 0;
87
- return gen_arith_div_uw(ctx, a, &gen_divu);
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
88
+ ctx->w = true;
118
+ uint64_t socket_bits, hart_bits, guest_bits;
89
+ return gen_arith(ctx, a, EXT_ZERO, gen_divu);
119
+
90
}
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
91
121
+
92
static bool trans_remw(DisasContext *ctx, arg_remw *a)
122
+ if (aia_fd < 0) {
93
{
123
+ error_report("Unable to create in-kernel irqchip");
94
REQUIRE_64BIT(ctx);
124
+ exit(1);
95
REQUIRE_EXT(ctx, RVM);
125
+ }
96
-
126
+
97
- return gen_arith_div_w(ctx, a, &gen_rem);
127
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
98
+ ctx->w = true;
128
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
99
+ return gen_arith(ctx, a, EXT_SIGN, gen_rem);
129
+ &default_aia_mode, false, NULL);
100
}
130
+ if (ret < 0) {
101
131
+ error_report("KVM AIA: failed to get current KVM AIA mode");
102
static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
132
+ exit(1);
103
{
133
+ }
104
REQUIRE_64BIT(ctx);
134
+ qemu_log("KVM AIA: default mode is %s\n",
105
REQUIRE_EXT(ctx, RVM);
135
+ kvm_aia_mode_str(default_aia_mode));
106
-
136
+
107
- return gen_arith_div_uw(ctx, a, &gen_remu);
137
+ if (default_aia_mode != aia_mode) {
108
+ ctx->w = true;
138
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
109
+ return gen_arith(ctx, a, EXT_ZERO, gen_remu);
139
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
140
+ &aia_mode, true, NULL);
141
+ if (ret < 0)
142
+ warn_report("KVM AIA: failed to set KVM AIA mode");
143
+ else
144
+ qemu_log("KVM AIA: set current mode to %s\n",
145
+ kvm_aia_mode_str(aia_mode));
146
+ }
147
+
148
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
149
+ KVM_DEV_RISCV_AIA_CONFIG_SRCS,
150
+ &aia_irq_num, true, NULL);
151
+ if (ret < 0) {
152
+ error_report("KVM AIA: failed to set number of input irq lines");
153
+ exit(1);
154
+ }
155
+
156
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
157
+ KVM_DEV_RISCV_AIA_CONFIG_IDS,
158
+ &aia_msi_num, true, NULL);
159
+ if (ret < 0) {
160
+ error_report("KVM AIA: failed to set number of msi");
161
+ exit(1);
162
+ }
163
+
164
+ socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
165
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
166
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
167
+ &socket_bits, true, NULL);
168
+ if (ret < 0) {
169
+ error_report("KVM AIA: failed to set group_bits");
170
+ exit(1);
171
+ }
172
+
173
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
174
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
175
+ &group_shift, true, NULL);
176
+ if (ret < 0) {
177
+ error_report("KVM AIA: failed to set group_shift");
178
+ exit(1);
179
+ }
180
+
181
+ guest_bits = guest_num == 0 ? 0 :
182
+ find_last_bit(&guest_num, BITS_PER_LONG) + 1;
183
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
184
+ KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS,
185
+ &guest_bits, true, NULL);
186
+ if (ret < 0) {
187
+ error_report("KVM AIA: failed to set guest_bits");
188
+ exit(1);
189
+ }
190
+
191
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
192
+ KVM_DEV_RISCV_AIA_ADDR_APLIC,
193
+ &aplic_base, true, NULL);
194
+ if (ret < 0) {
195
+ error_report("KVM AIA: failed to set the base address of APLIC");
196
+ exit(1);
197
+ }
198
+
199
+ for (socket = 0; socket < socket_count; socket++) {
200
+ socket_imsic_base = imsic_base + socket * (1U << group_shift);
201
+ hart_count = riscv_socket_hart_count(machine, socket);
202
+ base_hart = riscv_socket_first_hartid(machine, socket);
203
+
204
+ if (max_hart_per_socket < hart_count) {
205
+ max_hart_per_socket = hart_count;
206
+ }
207
+
208
+ for (i = 0; i < hart_count; i++) {
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
211
+ KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart),
212
+ &imsic_addr, true, NULL);
213
+ if (ret < 0) {
214
+ error_report("KVM AIA: failed to set the IMSIC address for hart %d", i);
215
+ exit(1);
216
+ }
217
+ }
218
+ }
219
+
220
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
221
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
222
+ KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
223
+ &hart_bits, true, NULL);
224
+ if (ret < 0) {
225
+ error_report("KVM AIA: failed to set hart_bits");
226
+ exit(1);
227
+ }
228
+
229
+ if (kvm_has_gsi_routing()) {
230
+ for (uint64_t idx = 0; idx < aia_irq_num + 1; ++idx) {
231
+ /* KVM AIA only has one APLIC instance */
232
+ kvm_irqchip_add_irq_route(kvm_state, idx, 0, idx);
233
+ }
234
+ kvm_gsi_routing_allowed = true;
235
+ kvm_irqchip_commit_routes(kvm_state);
236
+ }
237
+
238
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL,
239
+ KVM_DEV_RISCV_AIA_CTRL_INIT,
240
+ NULL, true, NULL);
241
+ if (ret < 0) {
242
+ error_report("KVM AIA: initialized fail");
243
+ exit(1);
244
+ }
245
+
246
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
110
}
247
}
111
--
248
--
112
2.31.1
249
2.41.0
113
114
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Introduce get_gpr, dest_gpr, temp_new -- new helpers that do not force
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
tcg globals into temps, returning a constant 0 for $zero as source and
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
a new temp for $zero as destination.
5
mmio operations of APLIC when using KVM AIA and send wired interrupt
6
signal via KVM_IRQ_LINE API.
7
After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API
8
when the IMSICs receive mmio write requests.
6
9
7
Introduce ctx->w for simplifying word operations, such as addw.
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
12
Message-id: 20210823195529.560295-6-richard.henderson@linaro.org
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
16
---
15
target/riscv/translate.c | 97 +++++++++++++++++++++++++++++++++-------
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
16
1 file changed, 81 insertions(+), 16 deletions(-)
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
19
2 files changed, 61 insertions(+), 20 deletions(-)
17
20
18
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/translate.c
23
--- a/hw/intc/riscv_aplic.c
21
+++ b/target/riscv/translate.c
24
+++ b/hw/intc/riscv_aplic.c
22
@@ -XXX,XX +XXX,XX @@ static TCGv load_val;
25
@@ -XXX,XX +XXX,XX @@
23
26
#include "hw/irq.h"
24
#include "exec/gen-icount.h"
27
#include "target/riscv/cpu.h"
28
#include "sysemu/sysemu.h"
29
+#include "sysemu/kvm.h"
30
#include "migration/vmstate.h"
31
32
#define APLIC_MAX_IDC (1UL << 14)
33
@@ -XXX,XX +XXX,XX @@
34
35
#define APLIC_IDC_CLAIMI 0x1c
25
36
26
+/*
37
+/*
27
+ * If an operation is being performed on less than TARGET_LONG_BITS,
38
+ * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
28
+ * it may require the inputs to be sign- or zero-extended; which will
39
+ * APLIC Wired.
29
+ * depend on the exact operation being performed.
30
+ */
40
+ */
31
+typedef enum {
41
+static bool is_kvm_aia(bool msimode)
32
+ EXT_NONE,
33
+ EXT_SIGN,
34
+ EXT_ZERO,
35
+} DisasExtend;
36
+
37
typedef struct DisasContext {
38
DisasContextBase base;
39
/* pc_succ_insn points to the instruction following base.pc_next */
40
target_ulong pc_succ_insn;
41
target_ulong priv_ver;
42
- bool virt_enabled;
43
+ target_ulong misa;
44
uint32_t opcode;
45
uint32_t mstatus_fs;
46
- target_ulong misa;
47
uint32_t mem_idx;
48
/* Remember the rounding mode encoded in the previous fp instruction,
49
which we have already installed into env->fp_status. Or -1 for
50
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
51
to any system register, which includes CSR_FRM, so we do not have
52
to reset this known value. */
53
int frm;
54
+ bool w;
55
+ bool virt_enabled;
56
bool ext_ifencei;
57
bool hlsx;
58
/* vector extension */
59
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
60
uint16_t vlen;
61
uint16_t mlen;
62
bool vl_eq_vlmax;
63
+ uint8_t ntemp;
64
CPUState *cs;
65
+ TCGv zero;
66
+ /* Space for 3 operands plus 1 extra for address computation. */
67
+ TCGv temp[4];
68
} DisasContext;
69
70
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
71
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
72
}
73
}
74
75
-/* Wrapper for getting reg values - need to check of reg is zero since
76
- * cpu_gpr[0] is not actually allocated
77
+/*
78
+ * Wrappers for getting reg values.
79
+ *
80
+ * The $zero register does not have cpu_gpr[0] allocated -- we supply the
81
+ * constant zero as a source, and an uninitialized sink as destination.
82
+ *
83
+ * Further, we may provide an extension for word operations.
84
*/
85
-static void gen_get_gpr(DisasContext *ctx, TCGv t, int reg_num)
86
+static TCGv temp_new(DisasContext *ctx)
87
+{
42
+{
88
+ assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
43
+ return kvm_irqchip_in_kernel() && msimode;
89
+ return ctx->temp[ctx->ntemp++] = tcg_temp_new();
90
+}
44
+}
91
+
45
+
92
+static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
46
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
47
uint32_t word)
93
{
48
{
94
+ TCGv t;
49
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
95
+
50
return topi;
96
if (reg_num == 0) {
97
- tcg_gen_movi_tl(t, 0);
98
- } else {
99
- tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
100
+ return ctx->zero;
101
}
102
+
103
+ switch (ctx->w ? ext : EXT_NONE) {
104
+ case EXT_NONE:
105
+ return cpu_gpr[reg_num];
106
+ case EXT_SIGN:
107
+ t = temp_new(ctx);
108
+ tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
109
+ return t;
110
+ case EXT_ZERO:
111
+ t = temp_new(ctx);
112
+ tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
113
+ return t;
114
+ }
115
+ g_assert_not_reached();
116
}
51
}
117
52
118
-/* Wrapper for setting reg values - need to check of reg is zero since
53
+static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
119
- * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
120
- * since we usually avoid calling the OP_TYPE_gen function if we see a write to
121
- * $zero
122
- */
123
-static void gen_set_gpr(DisasContext *ctx, int reg_num_dst, TCGv t)
124
+static void gen_get_gpr(DisasContext *ctx, TCGv t, int reg_num)
125
+{
54
+{
126
+ tcg_gen_mov_tl(t, get_gpr(ctx, reg_num, EXT_NONE));
55
+ kvm_set_irq(kvm_state, irq, !!level);
127
+}
56
+}
128
+
57
+
129
+static TCGv __attribute__((unused)) dest_gpr(DisasContext *ctx, int reg_num)
58
static void riscv_aplic_request(void *opaque, int irq, int level)
130
+{
59
{
131
+ if (reg_num == 0 || ctx->w) {
60
bool update = false;
132
+ return temp_new(ctx);
61
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
62
uint32_t i;
63
RISCVAPLICState *aplic = RISCV_APLIC(dev);
64
65
- aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
66
- aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
67
- aplic->state = g_new0(uint32_t, aplic->num_irqs);
68
- aplic->target = g_new0(uint32_t, aplic->num_irqs);
69
- if (!aplic->msimode) {
70
- for (i = 0; i < aplic->num_irqs; i++) {
71
- aplic->target[i] = 1;
72
+ if (!is_kvm_aia(aplic->msimode)) {
73
+ aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
74
+ aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
75
+ aplic->state = g_new0(uint32_t, aplic->num_irqs);
76
+ aplic->target = g_new0(uint32_t, aplic->num_irqs);
77
+ if (!aplic->msimode) {
78
+ for (i = 0; i < aplic->num_irqs; i++) {
79
+ aplic->target[i] = 1;
80
+ }
81
}
82
- }
83
- aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
84
- aplic->iforce = g_new0(uint32_t, aplic->num_harts);
85
- aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
86
+ aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
87
+ aplic->iforce = g_new0(uint32_t, aplic->num_harts);
88
+ aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
89
90
- memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic,
91
- TYPE_RISCV_APLIC, aplic->aperture_size);
92
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
93
+ memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
94
+ aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
95
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
133
+ }
96
+ }
134
+ return cpu_gpr[reg_num];
97
135
+}
98
/*
136
+
99
* Only root APLICs have hardware IRQ lines. All non-root APLICs
137
+static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
100
* have IRQ lines delegated by their parent APLIC.
138
{
101
*/
139
- if (reg_num_dst != 0) {
102
if (!aplic->parent) {
140
- tcg_gen_mov_tl(cpu_gpr[reg_num_dst], t);
103
- qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
141
+ if (reg_num != 0) {
104
+ if (is_kvm_aia(aplic->msimode)) {
142
+ if (ctx->w) {
105
+ qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
143
+ tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
144
+ } else {
106
+ } else {
145
+ tcg_gen_mov_tl(cpu_gpr[reg_num], t);
107
+ qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
146
+ }
108
+ }
147
}
109
}
148
}
110
149
111
/* Create output IRQ lines for non-MSI mode */
150
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
151
ctx->mlen = 1 << (ctx->sew + 3 - ctx->lmul);
113
qdev_prop_set_bit(dev, "mmode", mmode);
152
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
114
153
ctx->cs = cs;
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
154
+ ctx->w = false;
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
155
+ ctx->ntemp = 0;
156
+ memset(ctx->temp, 0, sizeof(ctx->temp));
157
+
117
+
158
+ ctx->zero = tcg_constant_tl(0);
118
+ if (!is_kvm_aia(msimode)) {
159
}
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
160
120
+ }
161
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
121
162
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
122
if (parent) {
163
123
riscv_aplic_add_child(parent, dev);
164
decode_opc(env, ctx, opcode16);
124
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
165
ctx->base.pc_next = ctx->pc_succ_insn;
125
index XXXXXXX..XXXXXXX 100644
166
+ ctx->w = false;
126
--- a/hw/intc/riscv_imsic.c
127
+++ b/hw/intc/riscv_imsic.c
128
@@ -XXX,XX +XXX,XX @@
129
#include "target/riscv/cpu.h"
130
#include "target/riscv/cpu_bits.h"
131
#include "sysemu/sysemu.h"
132
+#include "sysemu/kvm.h"
133
#include "migration/vmstate.h"
134
135
#define IMSIC_MMIO_PAGE_LE 0x00
136
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value,
137
goto err;
138
}
139
140
+#if defined(CONFIG_KVM)
141
+ if (kvm_irqchip_in_kernel()) {
142
+ struct kvm_msi msi;
167
+
143
+
168
+ for (int i = ctx->ntemp - 1; i >= 0; --i) {
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
169
+ tcg_temp_free(ctx->temp[i]);
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
170
+ ctx->temp[i] = NULL;
146
+ msi.data = le32_to_cpu(value);
147
+
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
149
+
150
+ return;
171
+ }
151
+ }
172
+ ctx->ntemp = 0;
152
+#endif
173
153
+
174
if (ctx->base.is_jmp == DISAS_NEXT) {
154
/* Writes only supported for MSI little-endian registers */
175
target_ulong page_start;
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
156
if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) {
157
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
158
CPUState *cpu = cpu_by_arch_id(imsic->hartid);
159
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
160
161
- imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
162
- imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
163
- imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
164
- imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
165
+ if (!kvm_irqchip_in_kernel()) {
166
+ imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
167
+ imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
168
+ imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
169
+ imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
170
+ }
171
172
memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops,
173
imsic, TYPE_RISCV_IMSIC,
176
--
174
--
177
2.31.1
175
2.41.0
178
179
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
In the riscv virt machine init function, We assemble a string
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
plic_hart_config which is a comma-separated list of N copies of the
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
VIRT_PLIC_HART_CONFIG string. The code that does this has a
5
devices to KVM APLIC.
6
misunderstanding of the strncat() length argument. If the source
7
string is too large strncat() will write a maximum of length+1 bytes
8
(length bytes from the source string plus a trailing NUL), but the
9
code here assumes that it will write only length bytes at most.
10
6
11
This isn't an actual bug because the code has correctly precalculated
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
12
the amount of memory it needs to allocate so that it will never be
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
13
too small (i.e. we could have used plain old strcat()), but it does
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
mean that the code looks like it has a guard against accidental
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
overrun when it doesn't.
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
16
17
Rewrite the string handling here to use the glib g_strjoinv()
18
function, which means we don't need to do careful accountancy of
19
string lengths, and makes it clearer that what we're doing is
20
"create a comma-separated string".
21
22
Fixes: Coverity 1460752
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-id: 20210812144647.10516-1-peter.maydell@linaro.org
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
13
---
29
hw/riscv/virt.c | 33 ++++++++++++++++++++-------------
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
30
1 file changed, 20 insertions(+), 13 deletions(-)
15
1 file changed, 63 insertions(+), 31 deletions(-)
31
16
32
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/riscv/virt.c
19
--- a/hw/riscv/virt.c
35
+++ b/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static FWCfgState *create_fw_cfg(const MachineState *mc)
21
@@ -XXX,XX +XXX,XX @@
37
return fw_cfg;
22
#include "hw/riscv/virt.h"
38
}
23
#include "hw/riscv/boot.h"
39
24
#include "hw/riscv/numa.h"
40
+/*
25
+#include "kvm_riscv.h"
41
+ * Return the per-socket PLIC hart topology configuration string
26
#include "hw/intc/riscv_aclint.h"
42
+ * (caller must free with g_free())
27
#include "hw/intc/riscv_aplic.h"
43
+ */
28
#include "hw/intc/riscv_imsic.h"
44
+static char *plic_hart_config_string(int hart_count)
29
@@ -XXX,XX +XXX,XX @@
30
#error "Can't accommodate all IMSIC groups in address space"
31
#endif
32
33
+/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
34
+static bool virt_use_kvm_aia(RISCVVirtState *s)
45
+{
35
+{
46
+ g_autofree const char **vals = g_new(const char *, hart_count + 1);
36
+ return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
47
+ int i;
48
+
49
+ for (i = 0; i < hart_count; i++) {
50
+ vals[i] = VIRT_PLIC_HART_CONFIG;
51
+ }
52
+ vals[i] = NULL;
53
+
54
+ /* g_strjoinv() obliges us to cast away const here */
55
+ return g_strjoinv(",", (char **)vals);
56
+}
37
+}
57
+
38
+
58
static void virt_machine_init(MachineState *machine)
39
static const MemMapEntry virt_memmap[] = {
40
[VIRT_DEBUG] = { 0x0, 0x100 },
41
[VIRT_MROM] = { 0x1000, 0xf000 },
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
43
uint32_t *intc_phandles,
44
uint32_t aplic_phandle,
45
uint32_t aplic_child_phandle,
46
- bool m_mode)
47
+ bool m_mode, int num_harts)
59
{
48
{
60
const MemMapEntry *memmap = virt_memmap;
49
int cpu;
50
char *aplic_name;
51
uint32_t *aplic_cells;
52
MachineState *ms = MACHINE(s);
53
54
- aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
55
+ aplic_cells = g_new0(uint32_t, num_harts * 2);
56
57
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
58
+ for (cpu = 0; cpu < num_harts; cpu++) {
59
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
60
aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
61
}
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
63
64
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
65
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
66
- aplic_cells,
67
- s->soc[socket].num_harts * sizeof(uint32_t) * 2);
68
+ aplic_cells, num_harts * sizeof(uint32_t) * 2);
69
} else {
70
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
71
}
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
73
uint32_t msi_s_phandle,
74
uint32_t *phandle,
75
uint32_t *intc_phandles,
76
- uint32_t *aplic_phandles)
77
+ uint32_t *aplic_phandles,
78
+ int num_harts)
79
{
80
char *aplic_name;
81
unsigned long aplic_addr;
82
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
83
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
84
msi_m_phandle, intc_phandles,
85
aplic_m_phandle, aplic_s_phandle,
86
- true);
87
+ true, num_harts);
88
}
89
90
/* S-level APLIC node */
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
92
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
93
msi_s_phandle, intc_phandles,
94
aplic_s_phandle, 0,
95
- false);
96
+ false, num_harts);
97
98
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
99
100
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
101
*msi_pcie_phandle = msi_s_phandle;
102
}
103
104
- phandle_pos = ms->smp.cpus;
105
- for (socket = (socket_count - 1); socket >= 0; socket--) {
106
- phandle_pos -= s->soc[socket].num_harts;
107
-
108
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
109
- create_fdt_socket_plic(s, memmap, socket, phandle,
110
- &intc_phandles[phandle_pos], xplic_phandles);
111
- } else {
112
- create_fdt_socket_aplic(s, memmap, socket,
113
- msi_m_phandle, msi_s_phandle, phandle,
114
- &intc_phandles[phandle_pos], xplic_phandles);
115
+ /* KVM AIA only has one APLIC instance */
116
+ if (virt_use_kvm_aia(s)) {
117
+ create_fdt_socket_aplic(s, memmap, 0,
118
+ msi_m_phandle, msi_s_phandle, phandle,
119
+ &intc_phandles[0], xplic_phandles,
120
+ ms->smp.cpus);
121
+ } else {
122
+ phandle_pos = ms->smp.cpus;
123
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
124
+ phandle_pos -= s->soc[socket].num_harts;
125
+
126
+ if (s->aia_type == VIRT_AIA_TYPE_NONE) {
127
+ create_fdt_socket_plic(s, memmap, socket, phandle,
128
+ &intc_phandles[phandle_pos],
129
+ xplic_phandles);
130
+ } else {
131
+ create_fdt_socket_aplic(s, memmap, socket,
132
+ msi_m_phandle, msi_s_phandle, phandle,
133
+ &intc_phandles[phandle_pos],
134
+ xplic_phandles,
135
+ s->soc[socket].num_harts);
136
+ }
137
}
138
}
139
140
g_free(intc_phandles);
141
142
- for (socket = 0; socket < socket_count; socket++) {
143
- if (socket == 0) {
144
- *irq_mmio_phandle = xplic_phandles[socket];
145
- *irq_virtio_phandle = xplic_phandles[socket];
146
- *irq_pcie_phandle = xplic_phandles[socket];
147
- }
148
- if (socket == 1) {
149
- *irq_virtio_phandle = xplic_phandles[socket];
150
- *irq_pcie_phandle = xplic_phandles[socket];
151
- }
152
- if (socket == 2) {
153
- *irq_pcie_phandle = xplic_phandles[socket];
154
+ if (virt_use_kvm_aia(s)) {
155
+ *irq_mmio_phandle = xplic_phandles[0];
156
+ *irq_virtio_phandle = xplic_phandles[0];
157
+ *irq_pcie_phandle = xplic_phandles[0];
158
+ } else {
159
+ for (socket = 0; socket < socket_count; socket++) {
160
+ if (socket == 0) {
161
+ *irq_mmio_phandle = xplic_phandles[socket];
162
+ *irq_virtio_phandle = xplic_phandles[socket];
163
+ *irq_pcie_phandle = xplic_phandles[socket];
164
+ }
165
+ if (socket == 1) {
166
+ *irq_virtio_phandle = xplic_phandles[socket];
167
+ *irq_pcie_phandle = xplic_phandles[socket];
168
+ }
169
+ if (socket == 2) {
170
+ *irq_pcie_phandle = xplic_phandles[socket];
171
+ }
172
}
173
}
174
61
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
175
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
62
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
176
}
63
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
177
}
64
char *plic_hart_config, *soc_name;
178
65
- size_t plic_hart_config_len;
179
+ if (virt_use_kvm_aia(s)) {
66
target_ulong start_addr = memmap[VIRT_DRAM].base;
180
+ kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
67
target_ulong firmware_end_addr, kernel_start_addr;
181
+ VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
68
uint32_t fdt_load_addr;
182
+ memmap[VIRT_APLIC_S].base,
69
uint64_t kernel_entry;
183
+ memmap[VIRT_IMSIC_S].base,
70
DeviceState *mmio_plic, *virtio_plic, *pcie_plic;
184
+ s->aia_guests);
71
- int i, j, base_hartid, hart_count;
185
+ }
72
+ int i, base_hartid, hart_count;
186
+
73
187
if (riscv_is_32bit(&s->soc[0])) {
74
/* Check socket count limit */
188
#if HOST_LONG_BITS == 64
75
if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) {
189
/* limit RAM size in a 32-bit system */
76
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
77
SIFIVE_CLINT_TIMEBASE_FREQ, true);
78
79
/* Per-socket PLIC hart topology configuration string */
80
- plic_hart_config_len =
81
- (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count;
82
- plic_hart_config = g_malloc0(plic_hart_config_len);
83
- for (j = 0; j < hart_count; j++) {
84
- if (j != 0) {
85
- strncat(plic_hart_config, ",", plic_hart_config_len);
86
- }
87
- strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG,
88
- plic_hart_config_len);
89
- plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1);
90
- }
91
+ plic_hart_config = plic_hart_config_string(hart_count);
92
93
/* Per-socket PLIC */
94
s->plic[i] = sifive_plic_create(
95
--
190
--
96
2.31.1
191
2.41.0
97
98
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
The flash is not inside the SoC, so it's inappropriate to put it
3
On a dtb dumped from the virt machine, dt-validate complains:
4
under the /soc node. Move it to root instead.
4
soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'}
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
That's pretty cryptic, but running the dtb back through dtc produces
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
5
9
6
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
10
Moving the riscv,pmu node out of the soc bus solves the problem.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
9
Message-id: 20210807035641.22449-1-bmeng.cn@gmail.com
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
17
---
12
hw/riscv/virt.c | 2 +-
18
hw/riscv/virt.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
14
20
15
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/virt.c
23
--- a/hw/riscv/virt.c
18
+++ b/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
20
qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ);
26
MachineState *ms = MACHINE(s);
21
g_free(name);
27
RISCVCPU hart = s->soc[0].harts[0];
22
28
23
- name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase);
29
- pmu_name = g_strdup_printf("/soc/pmu");
24
+ name = g_strdup_printf("/flash@%" PRIx64, flashbase);
30
+ pmu_name = g_strdup_printf("/pmu");
25
qemu_fdt_add_subnode(mc->fdt, name);
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
26
qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
27
qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg",
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
28
--
34
--
29
2.31.1
35
2.41.0
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
We distinguish write-only by passing ret_value as NULL.
3
The Svadu specification updated the name of the *envcfg bit from
4
HADE to ADUE.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-id: 20210823195529.560295-17-richard.henderson@linaro.org
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
target/riscv/csr.c | 23 +++++++++++++++--------
12
target/riscv/cpu_bits.h | 8 ++++----
12
1 file changed, 15 insertions(+), 8 deletions(-)
13
target/riscv/cpu.c | 4 ++--
14
target/riscv/cpu_helper.c | 6 +++---
15
target/riscv/csr.c | 12 ++++++------
16
4 files changed, 15 insertions(+), 15 deletions(-)
13
17
18
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu_bits.h
21
+++ b/target/riscv/cpu_bits.h
22
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
23
#define MENVCFG_CBIE (3UL << 4)
24
#define MENVCFG_CBCFE BIT(6)
25
#define MENVCFG_CBZE BIT(7)
26
-#define MENVCFG_HADE (1ULL << 61)
27
+#define MENVCFG_ADUE (1ULL << 61)
28
#define MENVCFG_PBMTE (1ULL << 62)
29
#define MENVCFG_STCE (1ULL << 63)
30
31
/* For RV32 */
32
-#define MENVCFGH_HADE BIT(29)
33
+#define MENVCFGH_ADUE BIT(29)
34
#define MENVCFGH_PBMTE BIT(30)
35
#define MENVCFGH_STCE BIT(31)
36
37
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
38
#define HENVCFG_CBIE MENVCFG_CBIE
39
#define HENVCFG_CBCFE MENVCFG_CBCFE
40
#define HENVCFG_CBZE MENVCFG_CBZE
41
-#define HENVCFG_HADE MENVCFG_HADE
42
+#define HENVCFG_ADUE MENVCFG_ADUE
43
#define HENVCFG_PBMTE MENVCFG_PBMTE
44
#define HENVCFG_STCE MENVCFG_STCE
45
46
/* For RV32 */
47
-#define HENVCFGH_HADE MENVCFGH_HADE
48
+#define HENVCFGH_ADUE MENVCFGH_ADUE
49
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
50
#define HENVCFGH_STCE MENVCFGH_STCE
51
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
55
+++ b/target/riscv/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
57
env->two_stage_lookup = false;
58
59
env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
60
- (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0);
61
+ (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
62
env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
63
- (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0);
64
+ (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
65
66
/* Initialized default priorities of local interrupts. */
67
for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
72
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
73
}
74
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
76
- bool hade = env->menvcfg & MENVCFG_HADE;
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
78
79
if (first_stage && two_stage && env->virt_enabled) {
80
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
81
- hade = hade && (env->henvcfg & HENVCFG_HADE);
82
+ adue = adue && (env->henvcfg & HENVCFG_ADUE);
83
}
84
85
int ptshift = (levels - 1) * ptidxbits;
86
@@ -XXX,XX +XXX,XX @@ restart:
87
88
/* Page table updates need to be atomic with MTTCG enabled */
89
if (updated_pte != pte && !is_debug) {
90
- if (!hade) {
91
+ if (!adue) {
92
return TRANSLATE_FAIL;
93
}
94
14
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
95
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/csr.c
97
--- a/target/riscv/csr.c
17
+++ b/target/riscv/csr.c
98
+++ b/target/riscv/csr.c
18
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
19
/* Shift the S bits to their VS bit location in mip */
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
20
int ret = rmw_mip(env, 0, ret_value, new_value << 1,
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
21
(write_mask << 1) & vsip_writable_mask & env->hideleg);
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
22
- *ret_value &= VS_MODE_INTERRUPTS;
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
23
- /* Shift the VS bits to their S bit location in vsip */
104
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
24
- *ret_value >>= 1;
105
}
25
+
106
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
26
+ if (ret_value) {
107
27
+ *ret_value &= VS_MODE_INTERRUPTS;
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
28
+ /* Shift the VS bits to their S bit location in vsip */
109
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
29
+ *ret_value >>= 1;
110
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
30
+ }
111
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
31
return ret;
112
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
113
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
114
uint64_t valh = (uint64_t)val << 32;
115
116
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
117
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
118
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
119
* henvcfg.hade is read_only 0 when menvcfg.hade = 0
120
*/
121
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
122
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
123
env->menvcfg);
124
return RISCV_EXCP_NONE;
32
}
125
}
33
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
34
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_sip(CPURISCVState *env, int csrno,
35
write_mask & env->mideleg & sip_writable_mask);
36
}
127
}
37
128
38
- *ret_value &= env->mideleg;
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
39
+ if (ret_value) {
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
40
+ *ret_value &= env->mideleg;
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
41
+ }
132
}
42
return ret;
133
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
136
return ret;
137
}
138
139
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
140
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
141
env->menvcfg)) >> 32;
142
return RISCV_EXCP_NONE;
43
}
143
}
44
144
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
45
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
145
target_ulong val)
46
int ret = rmw_mip(env, 0, ret_value, new_value,
146
{
47
write_mask & hvip_writable_mask);
147
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
48
148
- HENVCFG_HADE);
49
- *ret_value &= hvip_writable_mask;
149
+ HENVCFG_ADUE);
50
-
150
uint64_t valh = (uint64_t)val << 32;
51
+ if (ret_value) {
151
RISCVException ret;
52
+ *ret_value &= hvip_writable_mask;
53
+ }
54
return ret;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno,
58
int ret = rmw_mip(env, 0, ret_value, new_value,
59
write_mask & hip_writable_mask);
60
61
- *ret_value &= hip_writable_mask;
62
-
63
+ if (ret_value) {
64
+ *ret_value &= hip_writable_mask;
65
+ }
66
return ret;
67
}
68
152
69
--
153
--
70
2.31.1
154
2.41.0
71
72
diff view generated by jsdifflib
1
From: David Hoppenbrouwers <david@salt-inc.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
`muldiv64` would overflow in cases where the final 96-bit value does not
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
fit in a `uint64_t`. This would result in small values that cause an
4
longer to boot than the 'rv64' KVM CPU.
5
interrupt to be triggered much sooner than intended.
6
5
7
The overflow can be detected in most cases by checking if the new value is
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
8
smaller than the previous value. If the final result is larger than
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
9
`diff` it is either correct or it doesn't matter as it is effectively
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
10
infinite anyways.
11
9
12
`next` is an `uint64_t` value, but `timer_mod` takes an `int64_t`. This
10
31 - __builtin_clz(map)
13
resulted in high values such as `UINT64_MAX` being converted to `-1`,
14
which caused an immediate timer interrupt.
15
11
16
By limiting `next` to `INT64_MAX` no overflow will happen while the
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
17
timer will still be effectively set to "infinitely" far in the future.
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
14
set it to UINT_MAX (4294967295). After that, if the user didn't set a
15
satp_mode, set_satp_mode_default_map(cpu) will make
18
16
19
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/493
17
cfg.satp_mode.map = cfg.satp_mode.supported
20
Signed-off-by: David Hoppenbrouwers <david@salt-inc.org>
18
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
So satp_mode.map = 0. And then satp_mode_map_max will be set to
22
Message-id: 20210827152324.5201-1-david@salt-inc.org
20
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
21
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
22
here since both are UINT_MAX.
23
24
And finally we have 2 loops:
25
26
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
27
28
Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
29
extra delay when booting the 'host' CPU is coming from.
30
31
Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
32
in a different manner. We're doing the same here. If supported == 0,
33
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
34
satp_mode_finalize().
35
36
We'll also put a guard in satp_mode_max_from_map() to assert out if map
37
is 0 since the function is not ready to deal with it.
38
39
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
40
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
45
---
25
hw/intc/sifive_clint.c | 25 +++++++++++++++++++++++--
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
26
1 file changed, 23 insertions(+), 2 deletions(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
27
48
28
diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
29
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/intc/sifive_clint.c
51
--- a/target/riscv/cpu.c
31
+++ b/hw/intc/sifive_clint.c
52
+++ b/target/riscv/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
33
riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
54
34
diff = cpu->env.timecmp - rtc_r;
55
uint8_t satp_mode_max_from_map(uint32_t map)
35
/* back to ns (note args switched in muldiv64) */
56
{
36
- next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
57
+ /*
37
- muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
58
+ * 'map = 0' will make us return (31 - 32), which C will
38
+ uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
59
+ * happily overflow to UINT_MAX. There's no good result to
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
61
+ * with the result for 'map = 1').
62
+ *
63
+ * Assert out if map = 0. Callers will have to deal with
64
+ * it outside of this function.
65
+ */
66
+ g_assert(map > 0);
39
+
67
+
40
+ /*
68
/* map here has at least one bit set, so no problem with clz */
41
+ * check if ns_diff overflowed and check if the addition would potentially
69
return 31 - __builtin_clz(map);
42
+ * overflow
70
}
43
+ */
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
44
+ if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) ||
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
45
+ ns_diff > INT64_MAX) {
73
{
46
+ next = INT64_MAX;
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
47
+ } else {
75
- uint8_t satp_mode_map_max;
48
+ /*
76
- uint8_t satp_mode_supported_max =
49
+ * as it is very unlikely qemu_clock_get_ns will return a value
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
50
+ * greater than INT64_MAX, no additional check is needed for an
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
51
+ * unsigned integer overflow.
79
+
52
+ */
80
+ /* The CPU wants the OS to decide which satp mode to use */
53
+ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff;
81
+ if (cpu->cfg.satp_mode.supported == 0) {
54
+ /*
82
+ return;
55
+ * if ns_diff is INT64_MAX next may still be outside the range
56
+ * of a signed integer.
57
+ */
58
+ next = MIN(next, INT64_MAX);
59
+ }
83
+ }
60
+
84
+
61
timer_mod(cpu->env.timer, next);
85
+ satp_mode_supported_max =
62
}
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
63
87
88
if (cpu->cfg.satp_mode.map == 0) {
89
if (cpu->cfg.satp_mode.init == 0) {
64
--
90
--
65
2.31.1
91
2.41.0
66
67
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
If we have a field that's wider than 32-bits, we need a data type wide enough to
3
zicond is now codegen supported in both llvm and gcc.
4
be able to create the bitfield used to deposit the value.
5
4
6
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
5
This change allows seamless enabling/testing of zicond in downstream
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
7
to create a cmdline for qemu but fails short of enabling it because of
8
the "x-" prefix.
9
10
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
11
Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1626805903-162860-3-git-send-email-joe.komlodi@xilinx.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
include/hw/registerfields.h | 2 +-
15
target/riscv/cpu.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
14
17
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/registerfields.h
20
--- a/target/riscv/cpu.c
18
+++ b/include/hw/registerfields.h
21
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
20
_d; })
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
21
#define FIELD_DP64(storage, reg, field, val) ({ \
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
22
struct { \
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
23
- unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
24
+ uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
27
25
} _v = { .v = val }; \
28
/* Vendor-specific custom extensions */
26
uint64_t _d; \
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
27
_d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
31
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
32
33
/* These are experimental so mark with 'x-' */
34
- DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
35
36
/* ePMP 0.9.3 */
37
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
28
--
38
--
29
2.31.1
39
2.41.0
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Narrow the scope of t0 in trans_jalr.
3
A build with --enable-debug and without KVM will fail as follows:
4
4
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Message-id: 20210823195529.560295-15-richard.henderson@linaro.org
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
9
being ignored by the debug build, resulting in an undefined reference to
10
a KVM only function.
11
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
15
virt_use_kvm_aia() won't fix the build because this function would need
16
to be inlined multiple times to make the compiler zero out the entire
17
block.
18
19
While we're at it, use kvm_enabled() in all instances where
20
virt_use_kvm_aia() is checked to allow the compiler to elide these other
21
kvm-only instances as well.
22
23
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
24
Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine")
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
31
---
11
target/riscv/insn_trans/trans_rvi.c.inc | 25 ++++++++++---------------
32
hw/riscv/virt.c | 6 +++---
12
1 file changed, 10 insertions(+), 15 deletions(-)
33
1 file changed, 3 insertions(+), 3 deletions(-)
13
34
14
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvi.c.inc
37
--- a/hw/riscv/virt.c
17
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
38
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
19
20
static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
21
{
22
- /* no chaining with JALR */
23
TCGLabel *misaligned = NULL;
24
- TCGv t0 = tcg_temp_new();
25
-
26
27
- gen_get_gpr(ctx, cpu_pc, a->rs1);
28
- tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
29
+ tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
30
tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
31
32
if (!has_ext(ctx, RVC)) {
33
+ TCGv t0 = tcg_temp_new();
34
+
35
misaligned = gen_new_label();
36
tcg_gen_andi_tl(t0, cpu_pc, 0x2);
37
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
38
+ tcg_temp_free(t0);
39
}
40
}
40
41
41
if (a->rd != 0) {
42
/* KVM AIA only has one APLIC instance */
42
tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
43
- if (virt_use_kvm_aia(s)) {
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
45
create_fdt_socket_aplic(s, memmap, 0,
46
msi_m_phandle, msi_s_phandle, phandle,
47
&intc_phandles[0], xplic_phandles,
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
49
50
g_free(intc_phandles);
51
52
- if (virt_use_kvm_aia(s)) {
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
54
*irq_mmio_phandle = xplic_phandles[0];
55
*irq_virtio_phandle = xplic_phandles[0];
56
*irq_pcie_phandle = xplic_phandles[0];
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
58
}
43
}
59
}
44
+
60
45
+ /* No chaining with JALR. */
61
- if (virt_use_kvm_aia(s)) {
46
lookup_and_goto_ptr(ctx);
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
47
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
48
if (misaligned) {
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
65
memmap[VIRT_APLIC_S].base,
50
}
51
ctx->base.is_jmp = DISAS_NORETURN;
52
53
- tcg_temp_free(t0);
54
return true;
55
}
56
57
static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
58
{
59
TCGLabel *l = gen_new_label();
60
- TCGv source1, source2;
61
- source1 = tcg_temp_new();
62
- source2 = tcg_temp_new();
63
- gen_get_gpr(ctx, source1, a->rs1);
64
- gen_get_gpr(ctx, source2, a->rs2);
65
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
66
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
67
68
- tcg_gen_brcond_tl(cond, source1, source2, l);
69
+ tcg_gen_brcond_tl(cond, src1, src2, l);
70
gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
71
+
72
gen_set_label(l); /* branch taken */
73
74
if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
75
@@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
76
}
77
ctx->base.is_jmp = DISAS_NORETURN;
78
79
- tcg_temp_free(source1);
80
- tcg_temp_free(source2);
81
-
82
return true;
83
}
84
85
--
66
--
86
2.31.1
67
2.41.0
87
68
88
69
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Move these helpers near their use by the trans_*
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
functions within insn_trans/trans_rvm.c.inc.
4
environment with the following error:
5
5
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
collect2: error: ld returned 1 exit status
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
10
Message-id: 20210823195529.560295-10-richard.henderson@linaro.org
10
This happens because the debug build will poke into the
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
12
the KVM only function riscv_kvm_aplic_request().
13
14
There are multiple solutions to fix this. We'll go with the same
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
17
is a local function that would end up being used if the compiler crops
18
the block, and this won't work. Quoting Richard Henderson's explanation
19
in [1]:
20
21
"(...) the compiler won't eliminate entire unused functions with -O0"
22
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
24
declaration in kvm_riscv.h, where all other KVM specific public
25
functions are already declared. Other archs handles KVM specific code in
26
this manner and we expect to do the same from now on.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
29
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
36
---
13
target/riscv/translate.c | 127 ------------------------
37
target/riscv/kvm_riscv.h | 1 +
14
target/riscv/insn_trans/trans_rvm.c.inc | 127 ++++++++++++++++++++++++
38
hw/intc/riscv_aplic.c | 8 ++------
15
2 files changed, 127 insertions(+), 127 deletions(-)
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
16
41
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
18
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/translate.c
44
--- a/target/riscv/kvm_riscv.h
20
+++ b/target/riscv/translate.c
45
+++ b/target/riscv/kvm_riscv.h
21
@@ -XXX,XX +XXX,XX @@ static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
22
}
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
48
uint64_t aplic_base, uint64_t imsic_base,
49
uint64_t guest_num);
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
51
52
#endif
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/riscv_aplic.c
56
+++ b/hw/intc/riscv_aplic.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "target/riscv/cpu.h"
59
#include "sysemu/sysemu.h"
60
#include "sysemu/kvm.h"
61
+#include "kvm_riscv.h"
62
#include "migration/vmstate.h"
63
64
#define APLIC_MAX_IDC (1UL << 14)
65
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
66
return topi;
23
}
67
}
24
68
25
-static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
26
-{
70
-{
27
- TCGv rl = tcg_temp_new();
71
- kvm_set_irq(kvm_state, irq, !!level);
28
- TCGv rh = tcg_temp_new();
29
-
30
- tcg_gen_mulu2_tl(rl, rh, arg1, arg2);
31
- /* fix up for one negative */
32
- tcg_gen_sari_tl(rl, arg1, TARGET_LONG_BITS - 1);
33
- tcg_gen_and_tl(rl, rl, arg2);
34
- tcg_gen_sub_tl(ret, rh, rl);
35
-
36
- tcg_temp_free(rl);
37
- tcg_temp_free(rh);
38
-}
72
-}
39
-
73
-
40
-static void gen_div(TCGv ret, TCGv source1, TCGv source2)
74
static void riscv_aplic_request(void *opaque, int irq, int level)
41
-{
42
- TCGv temp1, temp2, zero, one, mone, min;
43
-
44
- temp1 = tcg_temp_new();
45
- temp2 = tcg_temp_new();
46
- zero = tcg_constant_tl(0);
47
- one = tcg_constant_tl(1);
48
- mone = tcg_constant_tl(-1);
49
- min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
50
-
51
- /*
52
- * If overflow, set temp2 to 1, else source2.
53
- * This produces the required result of min.
54
- */
55
- tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
56
- tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
57
- tcg_gen_and_tl(temp1, temp1, temp2);
58
- tcg_gen_movcond_tl(TCG_COND_NE, temp2, temp1, zero, one, source2);
59
-
60
- /*
61
- * If div by zero, set temp1 to -1 and temp2 to 1 to
62
- * produce the required result of -1.
63
- */
64
- tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, mone, source1);
65
- tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, temp2);
66
-
67
- tcg_gen_div_tl(ret, temp1, temp2);
68
-
69
- tcg_temp_free(temp1);
70
- tcg_temp_free(temp2);
71
-}
72
-
73
-static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
74
-{
75
- TCGv temp1, temp2, zero, one, max;
76
-
77
- temp1 = tcg_temp_new();
78
- temp2 = tcg_temp_new();
79
- zero = tcg_constant_tl(0);
80
- one = tcg_constant_tl(1);
81
- max = tcg_constant_tl(~0);
82
-
83
- /*
84
- * If div by zero, set temp1 to max and temp2 to 1 to
85
- * produce the required result of max.
86
- */
87
- tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, max, source1);
88
- tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
89
- tcg_gen_divu_tl(ret, temp1, temp2);
90
-
91
- tcg_temp_free(temp1);
92
- tcg_temp_free(temp2);
93
-}
94
-
95
-static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
96
-{
97
- TCGv temp1, temp2, zero, one, mone, min;
98
-
99
- temp1 = tcg_temp_new();
100
- temp2 = tcg_temp_new();
101
- zero = tcg_constant_tl(0);
102
- one = tcg_constant_tl(1);
103
- mone = tcg_constant_tl(-1);
104
- min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
105
-
106
- /*
107
- * If overflow, set temp1 to 0, else source1.
108
- * This avoids a possible host trap, and produces the required result of 0.
109
- */
110
- tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
111
- tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
112
- tcg_gen_and_tl(temp1, temp1, temp2);
113
- tcg_gen_movcond_tl(TCG_COND_NE, temp1, temp1, zero, zero, source1);
114
-
115
- /*
116
- * If div by zero, set temp2 to 1, else source2.
117
- * This avoids a possible host trap, but produces an incorrect result.
118
- */
119
- tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
120
-
121
- tcg_gen_rem_tl(temp1, temp1, temp2);
122
-
123
- /* If div by zero, the required result is the original dividend. */
124
- tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp1);
125
-
126
- tcg_temp_free(temp1);
127
- tcg_temp_free(temp2);
128
-}
129
-
130
-static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
131
-{
132
- TCGv temp, zero, one;
133
-
134
- temp = tcg_temp_new();
135
- zero = tcg_constant_tl(0);
136
- one = tcg_constant_tl(1);
137
-
138
- /*
139
- * If div by zero, set temp to 1, else source2.
140
- * This avoids a possible host trap, but produces an incorrect result.
141
- */
142
- tcg_gen_movcond_tl(TCG_COND_EQ, temp, source2, zero, one, source2);
143
-
144
- tcg_gen_remu_tl(temp, source1, temp);
145
-
146
- /* If div by zero, the required result is the original dividend. */
147
- tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp);
148
-
149
- tcg_temp_free(temp);
150
-}
151
-
152
static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
153
{
75
{
154
target_ulong next_pc;
76
bool update = false;
155
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
* have IRQ lines delegated by their parent APLIC.
79
*/
80
if (!aplic->parent) {
81
- if (is_kvm_aia(aplic->msimode)) {
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
84
} else {
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
156
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/insn_trans/trans_rvm.c.inc
88
--- a/target/riscv/kvm.c
158
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
89
+++ b/target/riscv/kvm.c
159
@@ -XXX,XX +XXX,XX @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
90
@@ -XXX,XX +XXX,XX @@
160
return gen_arith(ctx, a, EXT_NONE, gen_mulh);
91
#include "sysemu/runstate.h"
161
}
92
#include "hw/riscv/numa.h"
162
93
163
+static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
94
+void riscv_kvm_aplic_request(void *opaque, int irq, int level)
164
+{
95
+{
165
+ TCGv rl = tcg_temp_new();
96
+ kvm_set_irq(kvm_state, irq, !!level);
166
+ TCGv rh = tcg_temp_new();
167
+
168
+ tcg_gen_mulu2_tl(rl, rh, arg1, arg2);
169
+ /* fix up for one negative */
170
+ tcg_gen_sari_tl(rl, arg1, TARGET_LONG_BITS - 1);
171
+ tcg_gen_and_tl(rl, rl, arg2);
172
+ tcg_gen_sub_tl(ret, rh, rl);
173
+
174
+ tcg_temp_free(rl);
175
+ tcg_temp_free(rh);
176
+}
97
+}
177
+
98
+
178
static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
100
uint64_t idx)
179
{
101
{
180
REQUIRE_EXT(ctx, RVM);
181
@@ -XXX,XX +XXX,XX @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
182
return gen_arith(ctx, a, EXT_NONE, gen_mulhu);
183
}
184
185
+static void gen_div(TCGv ret, TCGv source1, TCGv source2)
186
+{
187
+ TCGv temp1, temp2, zero, one, mone, min;
188
+
189
+ temp1 = tcg_temp_new();
190
+ temp2 = tcg_temp_new();
191
+ zero = tcg_constant_tl(0);
192
+ one = tcg_constant_tl(1);
193
+ mone = tcg_constant_tl(-1);
194
+ min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
195
+
196
+ /*
197
+ * If overflow, set temp2 to 1, else source2.
198
+ * This produces the required result of min.
199
+ */
200
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
201
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
202
+ tcg_gen_and_tl(temp1, temp1, temp2);
203
+ tcg_gen_movcond_tl(TCG_COND_NE, temp2, temp1, zero, one, source2);
204
+
205
+ /*
206
+ * If div by zero, set temp1 to -1 and temp2 to 1 to
207
+ * produce the required result of -1.
208
+ */
209
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, mone, source1);
210
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, temp2);
211
+
212
+ tcg_gen_div_tl(ret, temp1, temp2);
213
+
214
+ tcg_temp_free(temp1);
215
+ tcg_temp_free(temp2);
216
+}
217
+
218
static bool trans_div(DisasContext *ctx, arg_div *a)
219
{
220
REQUIRE_EXT(ctx, RVM);
221
return gen_arith(ctx, a, EXT_SIGN, gen_div);
222
}
223
224
+static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
225
+{
226
+ TCGv temp1, temp2, zero, one, max;
227
+
228
+ temp1 = tcg_temp_new();
229
+ temp2 = tcg_temp_new();
230
+ zero = tcg_constant_tl(0);
231
+ one = tcg_constant_tl(1);
232
+ max = tcg_constant_tl(~0);
233
+
234
+ /*
235
+ * If div by zero, set temp1 to max and temp2 to 1 to
236
+ * produce the required result of max.
237
+ */
238
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp1, source2, zero, max, source1);
239
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
240
+ tcg_gen_divu_tl(ret, temp1, temp2);
241
+
242
+ tcg_temp_free(temp1);
243
+ tcg_temp_free(temp2);
244
+}
245
+
246
static bool trans_divu(DisasContext *ctx, arg_divu *a)
247
{
248
REQUIRE_EXT(ctx, RVM);
249
return gen_arith(ctx, a, EXT_ZERO, gen_divu);
250
}
251
252
+static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
253
+{
254
+ TCGv temp1, temp2, zero, one, mone, min;
255
+
256
+ temp1 = tcg_temp_new();
257
+ temp2 = tcg_temp_new();
258
+ zero = tcg_constant_tl(0);
259
+ one = tcg_constant_tl(1);
260
+ mone = tcg_constant_tl(-1);
261
+ min = tcg_constant_tl(1ull << (TARGET_LONG_BITS - 1));
262
+
263
+ /*
264
+ * If overflow, set temp1 to 0, else source1.
265
+ * This avoids a possible host trap, and produces the required result of 0.
266
+ */
267
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp1, source1, min);
268
+ tcg_gen_setcond_tl(TCG_COND_EQ, temp2, source2, mone);
269
+ tcg_gen_and_tl(temp1, temp1, temp2);
270
+ tcg_gen_movcond_tl(TCG_COND_NE, temp1, temp1, zero, zero, source1);
271
+
272
+ /*
273
+ * If div by zero, set temp2 to 1, else source2.
274
+ * This avoids a possible host trap, but produces an incorrect result.
275
+ */
276
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp2, source2, zero, one, source2);
277
+
278
+ tcg_gen_rem_tl(temp1, temp1, temp2);
279
+
280
+ /* If div by zero, the required result is the original dividend. */
281
+ tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp1);
282
+
283
+ tcg_temp_free(temp1);
284
+ tcg_temp_free(temp2);
285
+}
286
+
287
static bool trans_rem(DisasContext *ctx, arg_rem *a)
288
{
289
REQUIRE_EXT(ctx, RVM);
290
return gen_arith(ctx, a, EXT_SIGN, gen_rem);
291
}
292
293
+static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
294
+{
295
+ TCGv temp, zero, one;
296
+
297
+ temp = tcg_temp_new();
298
+ zero = tcg_constant_tl(0);
299
+ one = tcg_constant_tl(1);
300
+
301
+ /*
302
+ * If div by zero, set temp to 1, else source2.
303
+ * This avoids a possible host trap, but produces an incorrect result.
304
+ */
305
+ tcg_gen_movcond_tl(TCG_COND_EQ, temp, source2, zero, one, source2);
306
+
307
+ tcg_gen_remu_tl(temp, source1, temp);
308
+
309
+ /* If div by zero, the required result is the original dividend. */
310
+ tcg_gen_movcond_tl(TCG_COND_EQ, ret, source2, zero, source1, temp);
311
+
312
+ tcg_temp_free(temp);
313
+}
314
+
315
static bool trans_remu(DisasContext *ctx, arg_remu *a)
316
{
317
REQUIRE_EXT(ctx, RVM);
318
--
102
--
319
2.31.1
103
2.41.0
320
104
321
105
diff view generated by jsdifflib
New patch
1
From: Robbin Ehn <rehn@rivosinc.com>
1
2
3
This patch adds the new extensions in
4
linux 6.5 to the hwprobe syscall.
5
6
And fixes RVC check to OR with correct value.
7
The previous variable contains 0 therefore it
8
did work.
9
10
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
linux-user/syscall.c | 14 +++++++++++++-
17
1 file changed, 13 insertions(+), 1 deletion(-)
18
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/syscall.c
22
+++ b/linux-user/syscall.c
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
31
32
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
33
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
34
@@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
35
riscv_has_ext(env, RVD) ?
36
RISCV_HWPROBE_IMA_FD : 0;
37
value |= riscv_has_ext(env, RVC) ?
38
- RISCV_HWPROBE_IMA_C : pair->value;
39
+ RISCV_HWPROBE_IMA_C : 0;
40
+ value |= riscv_has_ext(env, RVV) ?
41
+ RISCV_HWPROBE_IMA_V : 0;
42
+ value |= cfg->ext_zba ?
43
+ RISCV_HWPROBE_EXT_ZBA : 0;
44
+ value |= cfg->ext_zbb ?
45
+ RISCV_HWPROBE_EXT_ZBB : 0;
46
+ value |= cfg->ext_zbs ?
47
+ RISCV_HWPROBE_EXT_ZBS : 0;
48
__put_user(value, &pair->value);
49
break;
50
case RISCV_HWPROBE_KEY_CPUPERF_0:
51
--
52
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Split out gen_mulh and gen_mulhu and use the common helper.
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
4
implement the first half of the key schedule derivation. This does not
5
actually involve shifting rows, so clone the same value into all four
6
columns of the AES vector to counter that operation.
4
7
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Cc: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
8
Message-id: 20210823195529.560295-9-richard.henderson@linaro.org
11
Cc: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
17
---
11
target/riscv/insn_trans/trans_rvm.c.inc | 40 +++++++++++--------------
18
target/riscv/crypto_helper.c | 17 +++++------------
12
1 file changed, 18 insertions(+), 22 deletions(-)
19
1 file changed, 5 insertions(+), 12 deletions(-)
13
20
14
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvm.c.inc
23
--- a/target/riscv/crypto_helper.c
17
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
24
+++ b/target/riscv/crypto_helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_mul(DisasContext *ctx, arg_mul *a)
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
19
return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl);
26
27
uint8_t enc_rnum = rnum;
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
29
- uint8_t rcon_ = 0;
30
- target_ulong result;
31
+ AESState t, rc = {};
32
33
if (enc_rnum != 0xA) {
34
temp = ror32(temp, 8); /* Rotate right by 8 */
35
- rcon_ = round_consts[enc_rnum];
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
37
}
38
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
45
46
- temp ^= rcon_;
47
-
48
- result = ((uint64_t)temp << 32) | temp;
49
-
50
- return result;
51
+ return t.d[0];
20
}
52
}
21
53
22
-static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
54
target_ulong HELPER(aes64im)(target_ulong rs1)
23
+static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
24
{
25
- REQUIRE_EXT(ctx, RVM);
26
- TCGv source1 = tcg_temp_new();
27
- TCGv source2 = tcg_temp_new();
28
- gen_get_gpr(ctx, source1, a->rs1);
29
- gen_get_gpr(ctx, source2, a->rs2);
30
+ TCGv discard = tcg_temp_new();
31
32
- tcg_gen_muls2_tl(source2, source1, source1, source2);
33
+ tcg_gen_muls2_tl(discard, ret, s1, s2);
34
+ tcg_temp_free(discard);
35
+}
36
37
- gen_set_gpr(ctx, a->rd, source1);
38
- tcg_temp_free(source1);
39
- tcg_temp_free(source2);
40
- return true;
41
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
42
+{
43
+ REQUIRE_EXT(ctx, RVM);
44
+ return gen_arith(ctx, a, EXT_NONE, gen_mulh);
45
}
46
47
static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
48
@@ -XXX,XX +XXX,XX @@ static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
49
return gen_arith(ctx, a, EXT_NONE, gen_mulhsu);
50
}
51
52
-static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
53
+static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
54
{
55
- REQUIRE_EXT(ctx, RVM);
56
- TCGv source1 = tcg_temp_new();
57
- TCGv source2 = tcg_temp_new();
58
- gen_get_gpr(ctx, source1, a->rs1);
59
- gen_get_gpr(ctx, source2, a->rs2);
60
+ TCGv discard = tcg_temp_new();
61
62
- tcg_gen_mulu2_tl(source2, source1, source1, source2);
63
+ tcg_gen_mulu2_tl(discard, ret, s1, s2);
64
+ tcg_temp_free(discard);
65
+}
66
67
- gen_set_gpr(ctx, a->rd, source1);
68
- tcg_temp_free(source1);
69
- tcg_temp_free(source2);
70
- return true;
71
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
72
+{
73
+ REQUIRE_EXT(ctx, RVM);
74
+ return gen_arith(ctx, a, EXT_NONE, gen_mulhu);
75
}
76
77
static bool trans_div(DisasContext *ctx, arg_div *a)
78
--
55
--
79
2.31.1
56
2.41.0
80
57
81
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Always use tcg_gen_deposit_z_tl; the special case for
3
riscv_trigger_init() had been called on reset events that can happen
4
shamt >= 32 is handled there.
4
several times for a CPU and it allocated timers for itrigger. If old
5
timers were present, they were simply overwritten by the new timers,
6
resulting in a memory leak.
5
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Divide riscv_trigger_init() into two functions, namely
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
10
appropriate timing. The timer allocation will happen only once for a
11
CPU in riscv_trigger_realize().
12
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210823195529.560295-21-richard.henderson@linaro.org
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
20
---
11
target/riscv/insn_trans/trans_rvb.c.inc | 19 ++++++-------------
21
target/riscv/debug.h | 3 ++-
12
1 file changed, 6 insertions(+), 13 deletions(-)
22
target/riscv/cpu.c | 8 +++++++-
23
target/riscv/debug.c | 15 ++++++++++++---
24
3 files changed, 21 insertions(+), 5 deletions(-)
13
25
14
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
15
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvb.c.inc
28
--- a/target/riscv/debug.h
17
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
29
+++ b/target/riscv/debug.h
18
@@ -XXX,XX +XXX,XX @@ static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
19
return gen_arith(ctx, a, EXT_NONE, gen_add_uw);
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
33
34
-void riscv_trigger_init(CPURISCVState *env);
35
+void riscv_trigger_realize(CPURISCVState *env);
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
37
38
bool riscv_itrigger_enabled(CPURISCVState *env);
39
void riscv_itrigger_update_priv(CPURISCVState *env);
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu.c
43
+++ b/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
45
46
#ifndef CONFIG_USER_ONLY
47
if (cpu->cfg.debug) {
48
- riscv_trigger_init(env);
49
+ riscv_trigger_reset_hold(env);
50
}
51
52
if (kvm_enabled()) {
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
54
55
riscv_cpu_register_gdb_regs_for_features(cs);
56
57
+#ifndef CONFIG_USER_ONLY
58
+ if (cpu->cfg.debug) {
59
+ riscv_trigger_realize(&cpu->env);
60
+ }
61
+#endif
62
+
63
qemu_init_vcpu(cs);
64
cpu_reset(cs);
65
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/debug.c
69
+++ b/target/riscv/debug.c
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
71
return false;
20
}
72
}
21
73
22
+static void gen_slli_uw(TCGv dest, TCGv src, target_long shamt)
74
-void riscv_trigger_init(CPURISCVState *env)
75
+void riscv_trigger_realize(CPURISCVState *env)
23
+{
76
+{
24
+ tcg_gen_deposit_z_tl(dest, src, shamt, MIN(32, TARGET_LONG_BITS - shamt));
77
+ int i;
78
+
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
81
+ riscv_itrigger_timer_cb, env);
82
+ }
25
+}
83
+}
26
+
84
+
27
static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
28
{
86
{
29
REQUIRE_64BIT(ctx);
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
30
REQUIRE_EXT(ctx, RVB);
88
int i;
31
-
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
32
- TCGv source1 = tcg_temp_new();
90
env->tdata3[i] = 0;
33
- gen_get_gpr(ctx, source1, a->rs1);
91
env->cpu_breakpoint[i] = NULL;
34
-
92
env->cpu_watchpoint[i] = NULL;
35
- if (a->shamt < 32) {
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
36
- tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
94
- riscv_itrigger_timer_cb, env);
37
- } else {
95
+ timer_del(env->itrigger_timer[i]);
38
- tcg_gen_shli_tl(source1, source1, a->shamt);
96
}
39
- }
40
-
41
- gen_set_gpr(ctx, a->rd, source1);
42
- tcg_temp_free(source1);
43
- return true;
44
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw);
45
}
97
}
46
--
98
--
47
2.31.1
99
2.41.0
48
100
49
101
diff view generated by jsdifflib
New patch
1
From: Leon Schuermann <leons@opentitan.org>
1
2
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
configuration lock bits must not apply. While this behavior is
5
implemented for the pmpcfgX CSRs, this bit is not respected for
6
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
7
writes work even on locked regions when the global rule-lock bypass is
8
enabled.
9
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/pmp.c | 4 ++++
17
1 file changed, 4 insertions(+)
18
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.c
22
+++ b/target/riscv/pmp.c
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
24
*/
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
26
{
27
+ /* mseccfg.RLB is set */
28
+ if (MSECCFG_RLB_ISSET(env)) {
29
+ return 0;
30
+ }
31
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
33
return 1;
34
--
35
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
When privilege check fails, RISCV_EXCP_ILLEGAL_INST is returned,
3
According to the new spec, when vsiselect has a reserved value, attempts
4
not -1 (RISCV_EXCP_NONE).
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
sireg, should preferably raise an illegal instruction exception.
5
6
6
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Message-id: 20210807141025.31808-1-bmeng.cn@gmail.com
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
target/riscv/csr.c | 2 +-
12
target/riscv/csr.c | 7 +++++--
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 5 insertions(+), 2 deletions(-)
13
14
14
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/csr.c
17
--- a/target/riscv/csr.c
17
+++ b/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
18
@@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
19
target_ulong old_value;
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
20
RISCVCPU *cpu = env_archcpu(env);
21
target_ulong new_val, target_ulong wr_mask)
21
22
{
22
- /* check privileges and return -1 if check fails */
23
- bool virt;
23
+ /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
24
+ bool virt, isel_reserved;
24
#if !defined(CONFIG_USER_ONLY)
25
uint8_t *iprio;
25
int effective_priv = env->priv;
26
int ret = -EINVAL;
26
int read_only = get_field(csrno, 0xC00) == 3;
27
target_ulong priv, isel, vgein;
28
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
29
30
/* Decode register details from CSR number */
31
virt = false;
32
+ isel_reserved = false;
33
switch (csrno) {
34
case CSR_MIREG:
35
iprio = env->miprio;
36
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
37
riscv_cpu_mxl_bits(env)),
38
val, new_val, wr_mask);
39
}
40
+ } else {
41
+ isel_reserved = true;
42
}
43
44
done:
45
if (ret) {
46
- return (env->virt_enabled && virt) ?
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
49
}
50
return RISCV_EXCP_NONE;
27
--
51
--
28
2.31.1
52
2.41.0
29
30
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
For U-mode CSRs, read-only check is also needed.
3
As per ISA:
4
4
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
shall not cause any of the side effects that might occur on a CSR read."
7
Message-id: 20210810014552.4884-1-zhiwei_liu@c-sky.com
7
8
trans_csrrwi() and trans_csrrw() call do_csrw() if rd=x0, do_csrw() calls
9
riscv_csrrw_do64(), via helper_csrw() passing NULL as *ret_value.
10
11
Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
15
---
10
target/riscv/csr.c | 8 +++++---
16
target/riscv/csr.c | 24 +++++++++++++++---------
11
1 file changed, 5 insertions(+), 3 deletions(-)
17
1 file changed, 15 insertions(+), 9 deletions(-)
12
18
13
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/csr.c
21
--- a/target/riscv/csr.c
16
+++ b/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
17
@@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
24
target_ulong write_mask)
25
{
18
RISCVException ret;
26
RISCVException ret;
19
target_ulong old_value;
27
- target_ulong old_value;
20
RISCVCPU *cpu = env_archcpu(env);
28
+ target_ulong old_value = 0;
21
+ int read_only = get_field(csrno, 0xC00) == 3;
29
22
30
/* execute combined read/write operation if it exists */
23
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
31
if (csr_ops[csrno].op) {
24
#if !defined(CONFIG_USER_ONLY)
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
25
int effective_priv = env->priv;
26
- int read_only = get_field(csrno, 0xC00) == 3;
27
28
if (riscv_has_ext(env, RVH) &&
29
env->priv == PRV_S &&
30
@@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
31
effective_priv++;
32
}
33
}
33
34
34
- if ((write_mask && read_only) ||
35
- /* if no accessor exists then return failure */
35
- (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
36
- if (!csr_ops[csrno].read) {
36
+ if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) {
37
- return RISCV_EXCP_ILLEGAL_INST;
37
return RISCV_EXCP_ILLEGAL_INST;
38
- }
39
- /* read old value */
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
41
- if (ret != RISCV_EXCP_NONE) {
42
- return ret;
43
+ /*
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
45
+ * and we can't throw side effects caused by CSR reads.
46
+ */
47
+ if (ret_value) {
48
+ /* if no accessor exists then return failure */
49
+ if (!csr_ops[csrno].read) {
50
+ return RISCV_EXCP_ILLEGAL_INST;
51
+ }
52
+ /* read old value */
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
54
+ if (ret != RISCV_EXCP_NONE) {
55
+ return ret;
56
+ }
38
}
57
}
39
#endif
58
40
+ if (write_mask && read_only) {
59
/* write value if writable and write mask set, otherwise drop writes */
41
+ return RISCV_EXCP_ILLEGAL_INST;
42
+ }
43
44
/* ensure the CSR extension is enabled. */
45
if (!cpu->cfg.ext_icsr) {
46
--
60
--
47
2.31.1
61
2.41.0
48
49
diff view generated by jsdifflib