1
The following changes since commit fea445e8fe9acea4f775a832815ee22bdf2b0222:
1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
2
2
3
Merge tag 'pull-maintainer-final-for-real-this-time-200324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-21 10:31:56 +0000)
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240322
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
8
8
9
for you to fetch changes up to 385e575cd5ab2436c123e4b7f8c9b383a64c0dbe:
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
10
10
11
target/riscv/kvm: fix timebase-frequency when using KVM acceleration (2024-03-22 15:41:01 +1000)
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 9.0
14
RISC-V PR for 9.1
15
15
16
* Do not enable all named features by default
16
* APLICs add child earlier than realize
17
* A range of Vector fixes
17
* Fix exposure of Zkr
18
* Update APLIC IDC after claiming iforce register
18
* Raise exceptions on wrs.nto
19
* Remove the dependency of Zvfbfmin to Zfbfmin
19
* Implement SBI debug console (DBCN) calls for KVM
20
* Fix mode in riscv_tlb_fill
20
* Support 64-bit addresses for initrd
21
* Fix timebase-frequency when using KVM acceleration
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
22
* Tolerate KVM disable ext errors
23
* Set tval in breakpoints
24
* Add support for Zve32x extension
25
* Add support for Zve64x extension
26
* Relax vector register check in RISCV gdbstub
27
* Fix the element agnostic Vector function problem
28
* Fix Zvkb extension config
29
* Implement dynamic establishment of custom decoder
30
* Add th.sxstatus CSR emulation
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
32
* Check single width operator for vector fp widen instructions
33
* Check single width operator for vfncvt.rod.f.f.w
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
35
* Prioritize pmp errors in raise_mmu_exception()
36
* Do not set mtval2 for non guest-page faults
37
* Remove experimental prefix from "B" extension
38
* Fixup CBO extension register calculation
39
* Fix the hart bit setting of AIA
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
22
43
23
----------------------------------------------------------------
44
----------------------------------------------------------------
24
Daniel Henrique Barboza (10):
45
Alexei Filippov (1):
25
target/riscv: do not enable all named features by default
46
target/riscv: do not set mtval2 for non guest-page faults
26
target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
27
trans_rvv.c.inc: set vstart = 0 in int scalar move insns
28
target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
29
target/riscv: always clear vstart in whole vec move insns
30
target/riscv: always clear vstart for ldst_whole insns
31
target/riscv/vector_helpers: do early exit when vstart >= vl
32
target/riscv: remove 'over' brconds from vector trans
33
trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
34
target/riscv/vector_helper.c: optimize loops in ldst helpers
35
47
36
Frank Chang (1):
48
Alistair Francis (2):
37
hw/intc: Update APLIC IDC after claiming iforce register
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
38
51
39
Irina Ryapolova (1):
52
Andrew Jones (2):
40
target/riscv: Fix mode in riscv_tlb_fill
53
target/riscv/kvm: Fix exposure of Zkr
54
target/riscv: Raise exceptions on wrs.nto
41
55
42
Ivan Klokov (1):
56
Cheng Yang (1):
43
target/riscv: enable 'vstart_eq_zero' in the end of insns
57
hw/riscv/boot.c: Support 64-bit address for initrd
44
58
45
Max Chou (1):
59
Christoph Müllner (1):
46
target/riscv: rvv: Remove the dependency of Zvfbfmin to Zfbfmin
60
riscv: thead: Add th.sxstatus CSR emulation
61
62
Clément Léger (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
64
65
Daniel Henrique Barboza (6):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
67
target/riscv/kvm: tolerate KVM disable ext errors
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
73
Huang Tao (2):
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
76
77
Jason Chien (3):
78
target/riscv: Add support for Zve32x extension
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
81
82
Max Chou (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
87
88
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
90
91
Yangyu Chen (1):
92
target/riscv/cpu.c: fix Zvkb extension config
47
93
48
Yong-Xuan Wang (1):
94
Yong-Xuan Wang (1):
49
target/riscv/kvm: fix timebase-frequency when using KVM acceleration
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
50
96
51
target/riscv/cpu_cfg.h | 8 +-
97
Yu-Ming Chang (1):
52
target/riscv/kvm/kvm_riscv.h | 1 +
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
53
target/riscv/vector_internals.h | 9 ++
99
54
hw/intc/riscv_aplic.c | 1 +
100
yang.zhang (1):
55
hw/riscv/virt.c | 2 +
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
56
target/riscv/cpu.c | 40 ++---
102
57
target/riscv/cpu_helper.c | 2 +-
103
MAINTAINERS | 1 +
58
target/riscv/kvm/kvm-cpu.c | 9 ++
104
target/riscv/cpu.h | 11 ++
59
target/riscv/tcg/tcg-cpu.c | 19 ++-
105
target/riscv/cpu_bits.h | 2 +-
60
target/riscv/translate.c | 6 +
106
target/riscv/cpu_cfg.h | 2 +
61
target/riscv/vcrypto_helper.c | 32 ++++
107
target/riscv/helper.h | 1 +
62
target/riscv/vector_helper.c | 93 ++++++++++-
108
target/riscv/sbi_ecall_interface.h | 17 +++
63
target/riscv/vector_internals.c | 4 +
109
target/riscv/tcg/tcg-cpu.h | 15 +++
64
target/riscv/insn_trans/trans_rvbf16.c.inc | 18 +--
110
disas/riscv.c | 65 +++++++++-
65
target/riscv/insn_trans/trans_rvv.c.inc | 244 +++++++++--------------------
111
hw/intc/riscv_aplic.c | 8 +-
66
target/riscv/insn_trans/trans_rvvk.c.inc | 30 +---
112
hw/riscv/boot.c | 4 +-
67
16 files changed, 259 insertions(+), 259 deletions(-)
113
target/riscv/cpu.c | 10 +-
114
target/riscv/cpu_helper.c | 37 +++---
115
target/riscv/csr.c | 71 +++++++++--
116
target/riscv/debug.c | 3 +
117
target/riscv/gdbstub.c | 8 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
119
target/riscv/op_helper.c | 17 ++-
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
121
target/riscv/th_csr.c | 79 +++++++++++++
122
target/riscv/translate.c | 31 +++--
123
target/riscv/vector_internals.c | 22 ++++
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
128
target/riscv/meson.build | 1 +
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: "yang.zhang" <yang.zhang@hexintek.com>
2
2
3
Currently, QEMU only sets the iforce register to 0 and returns early
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
when claiming the iforce register. However, this may leave mip.meip
4
be initialized first.
5
remains at 1 if a spurious external interrupt triggered by iforce
6
register is the only pending interrupt to be claimed, and the interrupt
7
cannot be lowered as expected.
8
5
9
This commit fixes this issue by calling riscv_aplic_idc_update() to
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
10
update the IDC status after the iforce register is claimed.
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
12
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-ID: <20240321104951.12104-1-frank.chang@sifive.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
12
---
18
hw/intc/riscv_aplic.c | 1 +
13
hw/intc/riscv_aplic.c | 8 ++++----
19
1 file changed, 1 insertion(+)
14
1 file changed, 4 insertions(+), 4 deletions(-)
20
15
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/riscv_aplic.c
18
--- a/hw/intc/riscv_aplic.c
24
+++ b/hw/intc/riscv_aplic.c
19
+++ b/hw/intc/riscv_aplic.c
25
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
26
21
qdev_prop_set_bit(dev, "msimode", msimode);
27
if (!topi) {
22
qdev_prop_set_bit(dev, "mmode", mmode);
28
aplic->iforce[idc] = 0;
23
29
+ riscv_aplic_idc_update(aplic, idc);
24
+ if (parent) {
30
return 0;
25
+ riscv_aplic_add_child(parent, dev);
26
+ }
27
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
29
30
if (!is_kvm_aia(msimode)) {
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
31
}
32
}
32
33
34
- if (parent) {
35
- riscv_aplic_add_child(parent, dev);
36
- }
37
-
38
if (!msimode) {
39
for (i = 0; i < num_harts; i++) {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
33
--
41
--
34
2.44.0
42
2.45.1
diff view generated by jsdifflib
New patch
1
From: Andrew Jones <ajones@ventanamicro.com>
1
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
4
implements the SEED CSR. Use the same implementation as TCG.
5
6
Without this patch, running with a KVM which does not forward the
7
SEED CSR access to QEMU will result in an ILL exception being
8
injected into the guest (this results in Linux guests crashing on
9
boot). And, when running with a KVM which does forward the access,
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
target/riscv/cpu.h | 3 +++
20
target/riscv/csr.c | 18 ++++++++++++++----
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
22
3 files changed, 42 insertions(+), 4 deletions(-)
23
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
29
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
31
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
33
+ target_ulong write_mask);
34
+
35
uint8_t satp_mode_max_from_map(uint32_t map);
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
43
#endif
44
45
/* Crypto Extension */
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
- target_ulong *ret_value,
48
- target_ulong new_value,
49
- target_ulong write_mask)
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
51
+ target_ulong write_mask)
52
{
53
uint16_t random_v;
54
Error *random_e = NULL;
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
56
rval = random_v | SEED_OPST_ES16;
57
}
58
59
+ return rval;
60
+}
61
+
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
63
+ target_ulong *ret_value,
64
+ target_ulong new_value,
65
+ target_ulong write_mask)
66
+{
67
+ target_ulong rval;
68
+
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
70
+
71
if (ret_value) {
72
*ret_value = rval;
73
}
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
79
return ret;
80
}
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
83
+{
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
85
+ target_ulong new_value = run->riscv_csr.new_value;
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
100
+
101
+ return ret;
102
+}
103
+
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
117
--
118
2.45.1
diff view generated by jsdifflib
New patch
1
From: Andrew Jones <ajones@ventanamicro.com>
1
2
3
Implementing wrs.nto to always just return is consistent with the
4
specification, as the instruction is permitted to terminate the
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
13
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
21
target/riscv/helper.h | 1 +
22
target/riscv/op_helper.c | 11 ++++++++
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
24
3 files changed, 32 insertions(+), 9 deletions(-)
25
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
31
DEF_HELPER_1(sret, tl, env)
32
DEF_HELPER_1(mret, tl, env)
33
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
37
/* Native Debug */
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
43
}
44
}
45
46
+void helper_wrs_nto(CPURISCVState *env)
47
+{
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
+ }
55
+}
56
+
57
void helper_tlb_flush(CPURISCVState *env)
58
{
59
CPUState *cs = env_cpu(env);
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
64
@@ -XXX,XX +XXX,XX @@
65
* this program. If not, see <http://www.gnu.org/licenses/>.
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
75
}
76
77
-#define GEN_TRANS_WRS(insn) \
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
84
+{
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
101
+
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
103
+ return trans_wrs_sto(ctx, NULL);
104
+}
105
--
106
2.45.1
107
108
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Commit 8ff8ac6329 added a conditional to guard the vext_ldst_whole()
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
4
helper if vstart >= evl. But by skipping the helper we're also not
4
the legacy console putchar and getchar SBI extensions.
5
setting vstart = 0 at the end of the insns, which is incorrect.
5
6
6
The appeal of the DBCN extension is that it allows multiple bytes to be
7
We'll move the conditional to vext_ldst_whole(), following in line with
7
read/written in the SBI console in a single SBI call.
8
the removal of all brconds vstart >= vl that the next patch will do. The
8
9
idea is to make the helpers responsible for their own vstart management.
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
10
module to userspace. But this will only happens if the KVM module
11
Fix ldst_whole isns by:
11
actually supports this SBI extension and we activate it.
12
12
13
- remove the brcond that skips the helper if vstart is >= evl;
13
We'll check for DBCN support during init time, checking if get-reg-list
14
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
- vext_ldst_whole() now does an early exit with the same check, where
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
evl = (vlenb * nf) >> log2_esz, but the early exit will also clear
16
17
vstart.
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
18
18
SBI_EXT_DBCN, reading and writing as required.
19
The 'width' param is now unneeded in ldst_whole_trans() and is also
19
20
removed. It was used for the evl calculation for the brcond and has no
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
21
other use now. The 'width' is reflected in vext_ldst_whole() via
21
host, takes around 20 seconds to boot without using DBCN. With this
22
log2_esz, which is encoded by GEN_VEXT_LD_WHOLE() as
22
patch we're taking around 14 seconds to boot due to the speed-up in the
23
"ctzl(sizeof(ETYPE))".
23
terminal output. There's no change in boot time if the guest isn't
24
24
using earlycon.
25
Suggested-by: Max Chou <max.chou@sifive.com>
25
26
Fixes: 8ff8ac6329 ("target/riscv: rvv: Add missing early exit condition for whole register load/store")
27
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
28
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
29
Reviewed-by: Max Chou <max.chou@sifive.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
30
Message-ID: <20240314175704.478276-6-dbarboza@ventanamicro.com>
31
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
---
30
---
33
target/riscv/vector_helper.c | 5 +++
31
target/riscv/sbi_ecall_interface.h | 17 +++++
34
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
35
2 files changed, 28 insertions(+), 29 deletions(-)
33
2 files changed, 128 insertions(+)
36
34
37
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
38
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/vector_helper.c
37
--- a/target/riscv/sbi_ecall_interface.h
40
+++ b/target/riscv/vector_helper.c
38
+++ b/target/riscv/sbi_ecall_interface.h
41
@@ -XXX,XX +XXX,XX @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
39
@@ -XXX,XX +XXX,XX @@
42
uint32_t vlenb = riscv_cpu_cfg(env)->vlenb;
40
43
uint32_t max_elems = vlenb >> log2_esz;
41
/* clang-format off */
44
42
45
+ if (env->vstart >= ((vlenb * nf) >> log2_esz)) {
43
+#define SBI_SUCCESS 0
46
+ env->vstart = 0;
44
+#define SBI_ERR_FAILED -1
47
+ return;
45
+#define SBI_ERR_NOT_SUPPORTED -2
46
+#define SBI_ERR_INVALID_PARAM -3
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
59
#define SBI_EXT_RFENCE 0x52464E43
60
#define SBI_EXT_HSM 0x48534D
61
+#define SBI_EXT_DBCN 0x4442434E
62
63
/* SBI function IDs for BASE extension */
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
65
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
68
69
+/* SBI function IDs for DBCN extension */
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
73
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
95
return 0;
96
}
97
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
101
+{
102
+ struct kvm_reg_list *reg_search;
103
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
48
+ }
109
+ }
49
+
110
+}
50
k = env->vstart / max_elems;
111
+
51
off = env->vstart % max_elems;
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
52
113
struct kvm_reg_list *reglist)
53
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
114
{
54
index XXXXXXX..XXXXXXX 100644
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
55
--- a/target/riscv/insn_trans/trans_rvv.c.inc
116
if (riscv_has_ext(&cpu->env, RVV)) {
56
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
57
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check)
118
}
58
typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32);
119
+
59
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
60
static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
121
}
61
- uint32_t width, gen_helper_ldst_whole *fn,
122
62
+ gen_helper_ldst_whole *fn,
123
static void riscv_init_kvm_registers(Object *cpu_obj)
63
DisasContext *s)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
64
{
125
return ret;
65
- uint32_t evl = s->cfg_ptr->vlenb * nf / width;
126
}
66
- TCGLabel *over = gen_new_label();
127
67
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over);
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
68
-
129
+{
69
TCGv_ptr dest;
130
+ target_ulong reg = 1;
70
TCGv base;
131
+
71
TCGv_i32 desc;
132
+ if (!kvm_sbi_dbcn.supported) {
72
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
133
+ return 0;
73
134
+ }
74
fn(dest, base, tcg_env, desc);
135
+
75
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
76
- gen_set_label(over);
137
+}
77
-
138
+
139
int kvm_arch_init_vcpu(CPUState *cs)
140
{
141
int ret = 0;
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
145
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
147
+
148
return ret;
149
}
150
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
78
return true;
152
return true;
79
}
153
}
80
154
81
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
82
* load and store whole register instructions ignore vtype and vl setting.
156
+{
83
* Thus, we don't need to check vill bit. (Section 7.9)
157
+ g_autofree uint8_t *buf = NULL;
84
*/
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
85
-#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, WIDTH) \
159
+ target_ulong num_bytes;
86
+#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF) \
160
+ uint64_t addr;
87
static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
161
+ unsigned char ch;
88
{ \
162
+ int ret;
89
if (require_rvv(s) && \
163
+
90
QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \
164
+ switch (run->riscv_sbi.function_id) {
91
- return ldst_whole_trans(a->rd, a->rs1, ARG_NF, WIDTH, \
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
92
+ return ldst_whole_trans(a->rd, a->rs1, ARG_NF, \
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
93
gen_helper_##NAME, s); \
167
+ num_bytes = run->riscv_sbi.args[0];
94
} \
168
+
95
return false; \
169
+ if (num_bytes == 0) {
96
}
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
97
171
+ run->riscv_sbi.ret[1] = 0;
98
-GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, 1)
172
+ break;
99
-GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, 2)
173
+ }
100
-GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, 4)
174
+
101
-GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, 8)
175
+ addr = run->riscv_sbi.args[1];
102
-GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, 1)
176
+
103
-GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, 2)
177
+ /*
104
-GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, 4)
178
+ * Handle the case where a 32 bit CPU is running in a
105
-GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, 8)
179
+ * 64 bit addressing env.
106
-GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, 1)
180
+ */
107
-GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, 2)
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
108
-GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, 4)
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
109
-GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, 8)
183
+ }
110
-GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, 1)
184
+
111
-GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, 2)
185
+ buf = g_malloc0(num_bytes);
112
-GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, 4)
186
+
113
-GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, 8)
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
114
+GEN_LDST_WHOLE_TRANS(vl1re8_v, 1)
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
115
+GEN_LDST_WHOLE_TRANS(vl1re16_v, 1)
189
+ if (ret < 0) {
116
+GEN_LDST_WHOLE_TRANS(vl1re32_v, 1)
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
117
+GEN_LDST_WHOLE_TRANS(vl1re64_v, 1)
191
+ "reading chardev");
118
+GEN_LDST_WHOLE_TRANS(vl2re8_v, 2)
192
+ exit(1);
119
+GEN_LDST_WHOLE_TRANS(vl2re16_v, 2)
193
+ }
120
+GEN_LDST_WHOLE_TRANS(vl2re32_v, 2)
194
+
121
+GEN_LDST_WHOLE_TRANS(vl2re64_v, 2)
195
+ cpu_physical_memory_write(addr, buf, ret);
122
+GEN_LDST_WHOLE_TRANS(vl4re8_v, 4)
196
+ } else {
123
+GEN_LDST_WHOLE_TRANS(vl4re16_v, 4)
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
124
+GEN_LDST_WHOLE_TRANS(vl4re32_v, 4)
198
+
125
+GEN_LDST_WHOLE_TRANS(vl4re64_v, 4)
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
126
+GEN_LDST_WHOLE_TRANS(vl8re8_v, 8)
200
+ if (ret < 0) {
127
+GEN_LDST_WHOLE_TRANS(vl8re16_v, 8)
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
128
+GEN_LDST_WHOLE_TRANS(vl8re32_v, 8)
202
+ "writing chardev");
129
+GEN_LDST_WHOLE_TRANS(vl8re64_v, 8)
203
+ exit(1);
130
204
+ }
131
/*
205
+ }
132
* The vector whole register store instructions are encoded similar to
206
+
133
* unmasked unit-stride store of elements with EEW=8.
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
134
*/
208
+ run->riscv_sbi.ret[1] = ret;
135
-GEN_LDST_WHOLE_TRANS(vs1r_v, 1, 1)
209
+ break;
136
-GEN_LDST_WHOLE_TRANS(vs2r_v, 2, 1)
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
137
-GEN_LDST_WHOLE_TRANS(vs4r_v, 4, 1)
211
+ ch = run->riscv_sbi.args[0];
138
-GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1)
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
139
+GEN_LDST_WHOLE_TRANS(vs1r_v, 1)
213
+
140
+GEN_LDST_WHOLE_TRANS(vs2r_v, 2)
214
+ if (ret < 0) {
141
+GEN_LDST_WHOLE_TRANS(vs4r_v, 4)
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
142
+GEN_LDST_WHOLE_TRANS(vs8r_v, 8)
216
+ "writing chardev");
143
217
+ exit(1);
144
/*
218
+ }
145
*** Vector Integer Arithmetic Instructions
219
+
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
221
+ run->riscv_sbi.ret[1] = 0;
222
+ break;
223
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
225
+ }
226
+}
227
+
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
229
{
230
int ret = 0;
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
232
}
233
ret = 0;
234
break;
235
+ case SBI_EXT_DBCN:
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
237
+ break;
238
default:
239
qemu_log_mask(LOG_UNIMP,
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
146
--
241
--
147
2.44.0
242
2.45.1
diff view generated by jsdifflib
New patch
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
4
to set the address of initrd in FDT to support 64-bit address.
5
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/boot.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
20
if (fdt) {
21
end = start + size;
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
26
}
27
}
28
29
--
30
2.45.1
diff view generated by jsdifflib
New patch
1
From: Clément Léger <cleger@rivosinc.com>
1
2
3
The current semihost exception number (16) is a reserved number (range
4
[16-17]). The upcoming double trap specification uses that number for
5
the double trap exception. Since the privileged spec (Table 22) defines
6
ranges for custom uses change the semihosting exception number to 63
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
9
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
11
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/cpu_bits.h | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_bits.h
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
27
- RISCV_EXCP_SEMIHOST = 0x10,
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
33
} RISCVException;
34
35
#define RISCV_EXCP_INT_FLAG 0x80000000
36
--
37
2.45.1
38
39
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
enabled, will fail with a kernel oops SIGILL right at the start. The
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
9
In hindsight this is too strict. If we keep proceeding, despite not
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
15
Change our current logic to not error out if we fail to disable an
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
17
is important to throw a warning because we must make the user aware that
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
37
1 file changed, 8 insertions(+), 4 deletions(-)
38
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
45
ret = kvm_set_one_reg(cs, id, &reg);
46
if (ret != 0) {
47
- error_report("Unable to %s extension %s in KVM, error %d",
48
- reg ? "enable" : "disable",
49
- multi_ext_cfg->name, ret);
50
- exit(EXIT_FAILURE);
51
+ if (!reg && ret == -EINVAL) {
52
+ warn_report("KVM cannot disable extension %s",
53
+ multi_ext_cfg->name);
54
+ } else {
55
+ error_report("Unable to enable extension %s in KVM, error %d",
56
+ multi_ext_cfg->name, ret);
57
+ exit(EXIT_FAILURE);
58
+ }
59
}
60
}
61
}
62
--
63
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The helper isn't setting env->vstart = 0 after its execution, as it is
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
expected from every vector instruction that completes successfully.
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
5.7.12, "Match Control Type 6":
6
7
"The Privileged Spec says that breakpoint exceptions that occur on
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
5
24
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-ID: <20240314175704.478276-2-dbarboza@ventanamicro.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
30
---
13
target/riscv/vector_helper.c | 1 +
31
target/riscv/cpu_helper.c | 1 +
14
1 file changed, 1 insertion(+)
32
target/riscv/debug.c | 3 +++
33
2 files changed, 4 insertions(+)
15
34
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/vector_helper.c
37
--- a/target/riscv/cpu_helper.c
19
+++ b/target/riscv/vector_helper.c
38
+++ b/target/riscv/cpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
21
} \
40
tval = env->bins;
22
*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \
41
break;
23
} \
42
case RISCV_EXCP_BREAKPOINT:
24
+ env->vstart = 0; \
43
+ tval = env->badaddr;
25
/* set tail elements to 1s */ \
44
if (cs->watchpoint_hit) {
26
vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \
45
tval = cs->watchpoint_hit->hitaddr;
27
}
46
cs->watchpoint_hit = NULL;
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
53
/* check U/S/M bit against current privilege level */
54
if ((ctrl >> 3) & BIT(env->priv)) {
55
+ env->badaddr = pc;
56
return true;
57
}
58
}
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
60
if (env->virt_enabled) {
61
/* check VU/VS bit against current privilege level */
62
if ((ctrl >> 23) & BIT(env->priv)) {
63
+ env->badaddr = pc;
64
return true;
65
}
66
} else {
67
/* check U/S/M bit against current privilege level */
68
if ((ctrl >> 3) & BIT(env->priv)) {
69
+ env->badaddr = pc;
70
return true;
71
}
72
}
28
--
73
--
29
2.44.0
74
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
These insns have 2 paths: we'll either have vstart already cleared if
3
Privileged spec section 4.1.9 mentions:
4
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
5
the 'vmvr_v' helper. The helper will clear vstart if it executes until
6
the end, or if vstart >= vl.
7
4
8
For starters, the check itself is wrong: we're checking vstart >= maxsz,
5
"When a trap is taken into S-mode, stval is written with
9
when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is
6
exception-specific information to assist software in handling the trap.
10
calling, to do the comparison. But even after fixing the comparison we'll
7
(...)
11
still need to clear vstart in the end, which isn't happening too.
12
8
13
We want to make the helpers responsible to manage vstart, including
9
If stval is written with a nonzero value when a breakpoint,
14
these corner cases, precisely to avoid these situations:
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
15
13
16
- remove the wrong vstart >= maxsz cond from the translation;
14
A similar text is found for mtval in section 3.1.16.
17
- add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that
18
happens.
19
15
20
This way we're now sure that vstart is being cleared in the end of the
16
Setting mtval/stval in this scenario is optional, but some softwares read
21
execution, regardless of the path taken.
17
these regs when handling ebreaks.
22
18
23
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Message-ID: <20240314175704.478276-5-dbarboza@ventanamicro.com>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
28
---
31
target/riscv/vector_helper.c | 5 +++++
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
32
target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
30
1 file changed, 2 insertions(+)
33
2 files changed, 5 insertions(+), 3 deletions(-)
34
31
35
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
36
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/vector_helper.c
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
38
+++ b/target/riscv/vector_helper.c
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
39
@@ -XXX,XX +XXX,XX @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
40
uint32_t startb = env->vstart * sewb;
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
41
uint32_t i = startb;
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
42
39
} else {
43
+ if (startb >= maxsz) {
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
44
+ env->vstart = 0;
41
+ offsetof(CPURISCVState, badaddr));
45
+ return;
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
46
+ }
43
}
47
+
44
return true;
48
if (HOST_BIG_ENDIAN && i % 8 != 0) {
49
uint32_t j = ROUND_UP(i, 8);
50
memcpy((uint8_t *)vd + H1(j - 1),
51
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/insn_trans/trans_rvv.c.inc
54
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
56
vreg_ofs(s, a->rs2), maxsz, maxsz); \
57
mark_vs_dirty(s); \
58
} else { \
59
- TCGLabel *over = gen_new_label(); \
60
- tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \
61
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
62
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
63
mark_vs_dirty(s); \
64
- gen_set_label(over); \
65
} \
66
return true; \
67
} \
68
--
45
--
69
2.44.0
46
2.45.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
According to the Zvfbfmin definition in the RISC-V BF16 extensions spec,
3
Add support for Zve32x extension and replace some checks for Zve32f with
4
the Zvfbfmin extension only requires either the V extension or the
4
Zve32x, since Zve32f depends on Zve32x.
5
Zve32f extension.
6
5
7
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Message-ID: <20240321170929.1162507-1-max.chou@sifive.com>
8
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/tcg/tcg-cpu.c | 5 -----
13
target/riscv/cpu_cfg.h | 1 +
13
1 file changed, 5 deletions(-)
14
target/riscv/cpu.c | 2 ++
15
target/riscv/cpu_helper.c | 2 +-
16
target/riscv/csr.c | 2 +-
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
19
6 files changed, 15 insertions(+), 12 deletions(-)
14
20
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
28
bool ext_zve32f;
29
+ bool ext_zve32x;
30
bool ext_zve64f;
31
bool ext_zve64d;
32
bool ext_zvbb;
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
59
*cs_base = 0;
60
61
- if (cpu->cfg.ext_zve32f) {
62
+ if (cpu->cfg.ext_zve32x) {
63
/*
64
* If env->vl equals to VLMAX, we can use generic vector operation
65
* expanders (GVEC) to accerlate the vector operations.
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
71
72
static RISCVException vs(CPURISCVState *env, int csrno)
73
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
76
#if !defined(CONFIG_USER_ONLY)
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
78
return RISCV_EXCP_ILLEGAL_INST;
15
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
16
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/tcg/tcg-cpu.c
81
--- a/target/riscv/tcg/tcg-cpu.c
18
+++ b/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
19
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
20
return;
84
return;
21
}
85
}
22
86
23
- if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zfbfmin) {
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
24
- error_setg(errp, "Zvfbfmin extension depends on Zfbfmin extension");
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
25
- return;
89
- return;
26
- }
90
+ /* The Zve32f extension depends on the Zve32x extension */
27
-
91
+ if (cpu->cfg.ext_zve32f) {
28
if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
29
error_setg(errp, "Zvfbfmin extension depends on Zve32f extension");
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
97
}
98
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
30
return;
114
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
120
{
121
TCGv s1, dst;
122
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
130
TCGv dst;
131
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
134
return false;
135
}
136
31
--
137
--
32
2.44.0
138
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Commit 3b8022269c added the capability of named features/profile
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
4
extensions to be added in riscv,isa. To do that we had to assign priv
4
enabling Zve64x enables Zve32x according to their dependency.
5
versions for each one of them in isa_edata_arr[]. But this resulted in a
6
side-effect: vendor CPUs that aren't running priv_version_latest started
7
to experience warnings for these profile extensions [1]:
8
5
9
| $ qemu-system-riscv32 -M sifive_e
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
10
| qemu-system-riscv32: warning: disabling zic64b extension for hart
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
11
0x00000000 because privilege spec version does not match
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
12
| qemu-system-riscv32: warning: disabling ziccamoa extension for
9
Reviewed-by: Max Chou <max.chou@sifive.com>
13
hart 0x00000000 because privilege spec version does not match
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
15
This is benign as far as the CPU behavior is concerned since disabling
16
both extensions is a no-op (aside from riscv,isa). But the warnings are
17
unpleasant to deal with, especially because we're sending user warnings
18
for extensions that users can't enable/disable.
19
20
Instead of enabling all named features all the time, separate them by
21
priv version. During finalize() time, after we decided which
22
priv_version the CPU is running, enable/disable all the named extensions
23
based on the priv spec chosen. This will be enough for a bug fix, but as
24
a future work we should look into how we can name these extensions in a
25
way that we don't need an explicit ext_name => priv_ver as we're doing
26
here.
27
28
The named extensions being added in isa_edata_arr[] that will be
29
enabled/disabled based solely on priv version can be removed from
30
riscv_cpu_named_features[]. 'zic64b' is an extension that can be
31
disabled based on block sizes so it'll retain its own flag and entry.
32
33
[1] https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg02592.html
34
35
Reported-by: Clément Chigot <chigot@adacore.com>
36
Fixes: 3b8022269c ("target/riscv: add riscv,isa to named features")
37
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
38
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
39
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
40
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
41
Tested-by: Clément Chigot <chigot@adacore.com>
42
Message-ID: <20240312203214.350980-1-dbarboza@ventanamicro.com>
43
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
---
13
---
45
target/riscv/cpu_cfg.h | 8 +++++---
14
target/riscv/cpu_cfg.h | 1 +
46
target/riscv/cpu.c | 40 +++++++++-----------------------------
15
target/riscv/cpu.c | 2 ++
47
target/riscv/tcg/tcg-cpu.c | 14 ++++++++++---
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
48
3 files changed, 25 insertions(+), 37 deletions(-)
17
3 files changed, 14 insertions(+), 6 deletions(-)
49
18
50
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
51
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu_cfg.h
21
--- a/target/riscv/cpu_cfg.h
53
+++ b/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
54
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
55
bool ext_zic64b;
24
bool ext_zve32x;
56
25
bool ext_zve64f;
57
/*
26
bool ext_zve64d;
58
- * Always 'true' boolean for named features
27
+ bool ext_zve64x;
59
- * TCG always implement/can't be disabled.
28
bool ext_zvbb;
60
+ * Always 'true' booleans for named features
29
bool ext_zvbc;
61
+ * TCG always implement/can't be user disabled,
30
bool ext_zvkb;
62
+ * based on spec version.
63
*/
64
- bool ext_always_enabled;
65
+ bool has_priv_1_12;
66
+ bool has_priv_1_11;
67
68
/* Vendor-specific custom extensions */
69
bool ext_xtheadba;
70
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
71
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
73
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
74
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
75
ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
76
ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
77
ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
78
- ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, ext_always_enabled),
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
79
- ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, ext_always_enabled),
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
80
- ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, ext_always_enabled),
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
81
- ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, ext_always_enabled),
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
82
+ ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, has_priv_1_11),
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
83
+ ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, has_priv_1_11),
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
84
+ ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, has_priv_1_11),
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
85
+ ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, has_priv_1_11),
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
86
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
87
ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
88
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
89
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
90
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
91
ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
92
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
93
- ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, ext_always_enabled),
94
+ ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
95
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
96
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
97
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
98
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
99
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
100
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
101
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
102
- ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, ext_always_enabled),
103
+ ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
104
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
105
- ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, ext_always_enabled),
106
+ ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
107
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
108
- ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, ext_always_enabled),
109
- ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, ext_always_enabled),
110
+ ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
111
+ ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
112
ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
113
ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
114
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
115
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
119
-#define ALWAYS_ENABLED_FEATURE(_name) \
120
- {.name = _name, \
121
- .offset = CPU_CFG_OFFSET(ext_always_enabled), \
122
- .enabled = true}
123
-
124
/*
125
* 'Named features' is the name we give to extensions that we
126
* don't want to expose to users. They are either immutable
127
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
128
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
129
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
130
131
- /*
132
- * cache-related extensions that are always enabled
133
- * in TCG since QEMU RISC-V does not have a cache
134
- * model.
135
- */
136
- ALWAYS_ENABLED_FEATURE("za64rs"),
137
- ALWAYS_ENABLED_FEATURE("ziccif"),
138
- ALWAYS_ENABLED_FEATURE("ziccrse"),
139
- ALWAYS_ENABLED_FEATURE("ziccamoa"),
140
- ALWAYS_ENABLED_FEATURE("zicclsm"),
141
- ALWAYS_ENABLED_FEATURE("ssccptr"),
142
-
143
- /* Other named features that TCG always implements */
144
- ALWAYS_ENABLED_FEATURE("sstvecd"),
145
- ALWAYS_ENABLED_FEATURE("sstvala"),
146
- ALWAYS_ENABLED_FEATURE("sscounterenw"),
147
-
148
DEFINE_PROP_END_OF_LIST(),
149
};
150
151
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
152
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
153
--- a/target/riscv/tcg/tcg-cpu.c
53
--- a/target/riscv/tcg/tcg-cpu.c
154
+++ b/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
155
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
156
56
157
static void riscv_cpu_update_named_features(RISCVCPU *cpu)
57
/* The Zve64d extension depends on the Zve64f extension */
158
{
58
if (cpu->cfg.ext_zve64d) {
159
+ if (cpu->env.priv_ver >= PRIV_VERSION_1_11_0) {
59
+ if (!riscv_has_ext(env, RVD)) {
160
+ cpu->cfg.has_priv_1_11 = true;
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
161
+ }
61
+ return;
162
+
62
+ }
163
+ if (cpu->env.priv_ver >= PRIV_VERSION_1_12_0) {
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
164
+ cpu->cfg.has_priv_1_12 = true;
64
}
165
+ }
65
166
+
66
- /* The Zve64f extension depends on the Zve32f extension */
167
+ /* zic64b is 1.12 or later */
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
168
cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
68
if (cpu->cfg.ext_zve64f) {
169
cpu->cfg.cbop_blocksize == 64 &&
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
170
- cpu->cfg.cboz_blocksize == 64;
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
171
+ cpu->cfg.cboz_blocksize == 64 &&
71
}
172
+ cpu->cfg.has_priv_1_12;
72
173
}
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
174
74
- error_setg(errp, "Zve64d/V extensions require D extension");
175
static void riscv_cpu_validate_g(RISCVCPU *cpu)
75
- return;
176
@@ -XXX,XX +XXX,XX @@ static void riscv_tcg_cpu_instance_init(CPUState *cs)
76
+ /* The Zve64x extension depends on the Zve32x extension */
177
RISCVCPU *cpu = RISCV_CPU(cs);
77
+ if (cpu->cfg.ext_zve64x) {
178
Object *obj = OBJECT(cpu);
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
179
79
}
180
- cpu->cfg.ext_always_enabled = true;
80
181
-
81
/* The Zve32f extension depends on the Zve32x extension */
182
misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
183
multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
83
return;
184
riscv_cpu_add_user_properties(obj);
84
}
85
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
185
--
95
--
186
2.44.0
96
2.45.1
187
188
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
In current implementation, the gdbstub allows reading vector registers
4
only if V extension is supported. However, all vector extensions and
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/gdbstub.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
20
+++ b/target/riscv/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
23
0);
24
}
25
- if (env->misa_ext & RVV) {
26
+ if (cpu->cfg.ext_zve32x) {
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
28
riscv_gdb_set_vector,
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
30
--
31
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
We're going to make changes that will required each helper to be
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
4
responsible for the 'vstart' management, i.e. we will relieve the
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
5
'vstart < vl' assumption that helpers have today.
5
agnostic policy.
6
6
7
Helpers are usually able to deal with vstart >= vl, i.e. doing nothing
7
However, this function can't deal the big endian situation. This patch fixes
8
aside from setting vstart = 0 at the end, but the tail update functions
8
the problem by adding handling of such case.
9
will update the tail regardless of vstart being valid or not. Unifying
10
the tail update process in a single function that would handle the
11
vstart >= vl case isn't trivial (see [1] for more info).
12
9
13
This patch takes a blunt approach: do an early exit in every single
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
14
vector helper if vstart >= vl, unless the helper is guarded with
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
15
vstart_eq_zero in the translation. For those cases the helper is ready
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
16
to deal with cases where vl might be zero, i.e. throwing exceptions
13
Cc: qemu-stable <qemu-stable@nongnu.org>
17
based on it like vcpop_m() and first_m().
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
18
19
Helpers that weren't changed:
20
21
- vcpop_m(), vfirst_m(), vmsetm(), GEN_VEXT_VIOTA_M(): these are guarded
22
directly with vstart_eq_zero;
23
24
- GEN_VEXT_VCOMPRESS_VM(): guarded with vcompress_vm_check() that checks
25
vstart_eq_zero;
26
27
- GEN_VEXT_RED(): guarded with either reduction_check() or
28
reduction_widen_check(), both check vstart_eq_zero;
29
30
- GEN_VEXT_FRED(): guarded with either freduction_check() or
31
freduction_widen_check(), both check vstart_eq_zero.
32
33
Another exception is vext_ldst_whole(), who operates on effective vector
34
length regardless of the current settings in vtype and vl.
35
36
[1] https://lore.kernel.org/qemu-riscv/1590234b-0291-432a-a0fa-c5a6876097bc@linux.alibaba.com/
37
38
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
39
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Acked-by: Alistair Francis <alistair.francis@wdc.com>
42
Message-ID: <20240314175704.478276-7-dbarboza@ventanamicro.com>
43
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
---
16
---
45
target/riscv/vector_internals.h | 9 +++++
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
46
target/riscv/vcrypto_helper.c | 32 ++++++++++++++++
18
1 file changed, 22 insertions(+)
47
target/riscv/vector_helper.c | 66 +++++++++++++++++++++++++++++++++
48
target/riscv/vector_internals.c | 4 ++
49
4 files changed, 111 insertions(+)
50
19
51
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/vector_internals.h
54
+++ b/target/riscv/vector_internals.h
55
@@ -XXX,XX +XXX,XX @@
56
#include "tcg/tcg-gvec-desc.h"
57
#include "internals.h"
58
59
+#define VSTART_CHECK_EARLY_EXIT(env) do { \
60
+ if (env->vstart >= env->vl) { \
61
+ env->vstart = 0; \
62
+ return; \
63
+ } \
64
+} while (0)
65
+
66
static inline uint32_t vext_nf(uint32_t desc)
67
{
68
return FIELD_EX32(simd_data(desc), VDATA, NF);
69
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
70
uint32_t vma = vext_vma(desc); \
71
uint32_t i; \
72
\
73
+ VSTART_CHECK_EARLY_EXIT(env); \
74
+ \
75
for (i = env->vstart; i < vl; i++) { \
76
if (!vm && !vext_elem_mask(v0, i)) { \
77
/* set masked-off elements to 1s */ \
78
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/vcrypto_helper.c
81
+++ b/target/riscv/vcrypto_helper.c
82
@@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key)
83
uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
84
uint32_t vta = vext_vta(desc); \
85
\
86
+ VSTART_CHECK_EARLY_EXIT(env); \
87
+ \
88
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
89
AESState round_key; \
90
round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
91
@@ -XXX,XX +XXX,XX @@ static inline void xor_round_key(AESState *round_state, AESState *round_key)
92
uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
93
uint32_t vta = vext_vta(desc); \
94
\
95
+ VSTART_CHECK_EARLY_EXIT(env); \
96
+ \
97
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
98
AESState round_key; \
99
round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
100
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
101
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
102
uint32_t vta = vext_vta(desc);
103
104
+ VSTART_CHECK_EARLY_EXIT(env);
105
+
106
uimm &= 0b1111;
107
if (uimm > 10 || uimm == 0) {
108
uimm ^= 0b1000;
109
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
110
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
111
uint32_t vta = vext_vta(desc);
112
113
+ VSTART_CHECK_EARLY_EXIT(env);
114
+
115
uimm &= 0b1111;
116
if (uimm > 14 || uimm < 2) {
117
uimm ^= 0b1000;
118
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
119
uint32_t total_elems;
120
uint32_t vta = vext_vta(desc);
121
122
+ VSTART_CHECK_EARLY_EXIT(env);
123
+
124
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
125
if (sew == MO_32) {
126
vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
127
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
128
uint32_t total_elems;
129
uint32_t vta = vext_vta(desc);
130
131
+ VSTART_CHECK_EARLY_EXIT(env);
132
+
133
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
134
vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
135
((uint32_t *)vs1) + 4 * i + 2);
136
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
137
uint32_t total_elems;
138
uint32_t vta = vext_vta(desc);
139
140
+ VSTART_CHECK_EARLY_EXIT(env);
141
+
142
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
143
vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
144
((uint64_t *)vs1) + 4 * i + 2);
145
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
146
uint32_t total_elems;
147
uint32_t vta = vext_vta(desc);
148
149
+ VSTART_CHECK_EARLY_EXIT(env);
150
+
151
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
152
vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
153
(((uint32_t *)vs1) + 4 * i));
154
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
155
uint32_t total_elems;
156
uint32_t vta = vext_vta(desc);
157
158
+ VSTART_CHECK_EARLY_EXIT(env);
159
+
160
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
161
vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
162
(((uint64_t *)vs1) + 4 * i));
163
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
164
uint32_t *vs1 = vs1_vptr;
165
uint32_t *vs2 = vs2_vptr;
166
167
+ VSTART_CHECK_EARLY_EXIT(env);
168
+
169
for (int i = env->vstart / 8; i < env->vl / 8; i++) {
170
uint32_t w[24];
171
for (int j = 0; j < 8; j++) {
172
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
173
uint32_t *vs2 = vs2_vptr;
174
uint32_t v1[8], v2[8], v3[8];
175
176
+ VSTART_CHECK_EARLY_EXIT(env);
177
+
178
for (int i = env->vstart / 8; i < env->vl / 8; i++) {
179
for (int k = 0; k < 8; k++) {
180
v2[k] = bswap32(vd[H4(i * 8 + k)]);
181
@@ -XXX,XX +XXX,XX @@ void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
182
uint32_t vta = vext_vta(desc);
183
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
184
185
+ VSTART_CHECK_EARLY_EXIT(env);
186
+
187
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
188
uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
189
uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
190
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
191
uint32_t vta = vext_vta(desc);
192
uint32_t total_elems = vext_get_total_elems(env, desc, 4);
193
194
+ VSTART_CHECK_EARLY_EXIT(env);
195
+
196
for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
197
uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
198
uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
199
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
200
uint32_t esz = sizeof(uint32_t);
201
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
202
203
+ VSTART_CHECK_EARLY_EXIT(env);
204
+
205
for (uint32_t i = group_start; i < group_end; ++i) {
206
uint32_t vstart = i * egs;
207
uint32_t vend = (i + 1) * egs;
208
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
209
uint32_t esz = sizeof(uint32_t);
210
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
211
212
+ VSTART_CHECK_EARLY_EXIT(env);
213
+
214
for (uint32_t i = group_start; i < group_end; ++i) {
215
uint32_t vstart = i * egs;
216
uint32_t vend = (i + 1) * egs;
217
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
218
uint32_t esz = sizeof(uint32_t);
219
uint32_t total_elems = vext_get_total_elems(env, desc, esz);
220
221
+ VSTART_CHECK_EARLY_EXIT(env);
222
+
223
for (uint32_t i = group_start; i < group_end; ++i) {
224
uint32_t vstart = i * egs;
225
uint32_t vend = (i + 1) * egs;
226
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/riscv/vector_helper.c
229
+++ b/target/riscv/vector_helper.c
230
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
231
uint32_t esz = 1 << log2_esz;
232
uint32_t vma = vext_vma(desc);
233
234
+ VSTART_CHECK_EARLY_EXIT(env);
235
+
236
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
237
k = 0;
238
while (k < nf) {
239
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
240
uint32_t max_elems = vext_max_elems(desc, log2_esz);
241
uint32_t esz = 1 << log2_esz;
242
243
+ VSTART_CHECK_EARLY_EXIT(env);
244
+
245
/* load bytes from guest memory */
246
for (i = env->vstart; i < evl; i++, env->vstart++) {
247
k = 0;
248
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
249
uint32_t esz = 1 << log2_esz;
250
uint32_t vma = vext_vma(desc);
251
252
+ VSTART_CHECK_EARLY_EXIT(env);
253
+
254
/* load bytes from guest memory */
255
for (i = env->vstart; i < env->vl; i++, env->vstart++) {
256
k = 0;
257
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
258
target_ulong addr, offset, remain;
259
int mmu_index = riscv_env_mmu_index(env, false);
260
261
+ VSTART_CHECK_EARLY_EXIT(env);
262
+
263
/* probe every access */
264
for (i = env->vstart; i < env->vl; i++) {
265
if (!vm && !vext_elem_mask(v0, i)) {
266
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
267
uint32_t vta = vext_vta(desc); \
268
uint32_t i; \
269
\
270
+ VSTART_CHECK_EARLY_EXIT(env); \
271
+ \
272
for (i = env->vstart; i < vl; i++) { \
273
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
274
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
275
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
276
uint32_t vta = vext_vta(desc); \
277
uint32_t i; \
278
\
279
+ VSTART_CHECK_EARLY_EXIT(env); \
280
+ \
281
for (i = env->vstart; i < vl; i++) { \
282
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
283
ETYPE carry = vext_elem_mask(v0, i); \
284
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
285
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
286
uint32_t i; \
287
\
288
+ VSTART_CHECK_EARLY_EXIT(env); \
289
+ \
290
for (i = env->vstart; i < vl; i++) { \
291
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
292
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
293
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
294
uint32_t vta_all_1s = vext_vta_all_1s(desc); \
295
uint32_t i; \
296
\
297
+ VSTART_CHECK_EARLY_EXIT(env); \
298
+ \
299
for (i = env->vstart; i < vl; i++) { \
300
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
301
ETYPE carry = !vm && vext_elem_mask(v0, i); \
302
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
303
uint32_t vma = vext_vma(desc); \
304
uint32_t i; \
305
\
306
+ VSTART_CHECK_EARLY_EXIT(env); \
307
+ \
308
for (i = env->vstart; i < vl; i++) { \
309
if (!vm && !vext_elem_mask(v0, i)) { \
310
/* set masked-off elements to 1s */ \
311
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
312
uint32_t vma = vext_vma(desc); \
313
uint32_t i; \
314
\
315
+ VSTART_CHECK_EARLY_EXIT(env); \
316
+ \
317
for (i = env->vstart; i < vl; i++) { \
318
if (!vm && !vext_elem_mask(v0, i)) { \
319
/* set masked-off elements to 1s */ \
320
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
321
uint32_t vma = vext_vma(desc); \
322
uint32_t i; \
323
\
324
+ VSTART_CHECK_EARLY_EXIT(env); \
325
+ \
326
for (i = env->vstart; i < vl; i++) { \
327
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
328
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
329
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
330
uint32_t vma = vext_vma(desc); \
331
uint32_t i; \
332
\
333
+ VSTART_CHECK_EARLY_EXIT(env); \
334
+ \
335
for (i = env->vstart; i < vl; i++) { \
336
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
337
if (!vm && !vext_elem_mask(v0, i)) { \
338
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env, \
339
uint32_t vta = vext_vta(desc); \
340
uint32_t i; \
341
\
342
+ VSTART_CHECK_EARLY_EXIT(env); \
343
+ \
344
for (i = env->vstart; i < vl; i++) { \
345
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
346
*((ETYPE *)vd + H(i)) = s1; \
347
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env, \
348
uint32_t vta = vext_vta(desc); \
349
uint32_t i; \
350
\
351
+ VSTART_CHECK_EARLY_EXIT(env); \
352
+ \
353
for (i = env->vstart; i < vl; i++) { \
354
*((ETYPE *)vd + H(i)) = (ETYPE)s1; \
355
} \
356
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
357
uint32_t vta = vext_vta(desc); \
358
uint32_t i; \
359
\
360
+ VSTART_CHECK_EARLY_EXIT(env); \
361
+ \
362
for (i = env->vstart; i < vl; i++) { \
363
ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \
364
*((ETYPE *)vd + H(i)) = *(vt + H(i)); \
365
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
366
uint32_t vta = vext_vta(desc); \
367
uint32_t i; \
368
\
369
+ VSTART_CHECK_EARLY_EXIT(env); \
370
+ \
371
for (i = env->vstart; i < vl; i++) { \
372
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
373
ETYPE d = (!vext_elem_mask(v0, i) ? s2 : \
374
@@ -XXX,XX +XXX,XX @@ vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
375
uint32_t vl, uint32_t vm, int vxrm,
376
opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
377
{
378
+ VSTART_CHECK_EARLY_EXIT(env);
379
+
380
for (uint32_t i = env->vstart; i < vl; i++) {
381
if (!vm && !vext_elem_mask(v0, i)) {
382
/* set masked-off elements to 1s */
383
@@ -XXX,XX +XXX,XX @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
384
uint32_t vl, uint32_t vm, int vxrm,
385
opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
386
{
387
+ VSTART_CHECK_EARLY_EXIT(env);
388
+
389
for (uint32_t i = env->vstart; i < vl; i++) {
390
if (!vm && !vext_elem_mask(v0, i)) {
391
/* set masked-off elements to 1s */
392
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
393
uint32_t vma = vext_vma(desc); \
394
uint32_t i; \
395
\
396
+ VSTART_CHECK_EARLY_EXIT(env); \
397
+ \
398
for (i = env->vstart; i < vl; i++) { \
399
if (!vm && !vext_elem_mask(v0, i)) { \
400
/* set masked-off elements to 1s */ \
401
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \
402
uint32_t vma = vext_vma(desc); \
403
uint32_t i; \
404
\
405
+ VSTART_CHECK_EARLY_EXIT(env); \
406
+ \
407
for (i = env->vstart; i < vl; i++) { \
408
if (!vm && !vext_elem_mask(v0, i)) { \
409
/* set masked-off elements to 1s */ \
410
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
411
uint32_t vma = vext_vma(desc); \
412
uint32_t i; \
413
\
414
+ VSTART_CHECK_EARLY_EXIT(env); \
415
+ \
416
if (vl == 0) { \
417
return; \
418
} \
419
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
420
uint32_t vma = vext_vma(desc); \
421
uint32_t i; \
422
\
423
+ VSTART_CHECK_EARLY_EXIT(env); \
424
+ \
425
for (i = env->vstart; i < vl; i++) { \
426
ETYPE s1 = *((ETYPE *)vs1 + H(i)); \
427
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
428
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
429
uint32_t vma = vext_vma(desc); \
430
uint32_t i; \
431
\
432
+ VSTART_CHECK_EARLY_EXIT(env); \
433
+ \
434
for (i = env->vstart; i < vl; i++) { \
435
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
436
if (!vm && !vext_elem_mask(v0, i)) { \
437
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
438
uint32_t vta = vext_vta(desc); \
439
uint32_t i; \
440
\
441
+ VSTART_CHECK_EARLY_EXIT(env); \
442
+ \
443
for (i = env->vstart; i < vl; i++) { \
444
ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
445
*((ETYPE *)vd + H(i)) = \
446
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
447
uint32_t i; \
448
int a, b; \
449
\
450
+ VSTART_CHECK_EARLY_EXIT(env); \
451
+ \
452
for (i = env->vstart; i < vl; i++) { \
453
a = vext_elem_mask(vs1, i); \
454
b = vext_elem_mask(vs2, i); \
455
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \
456
uint32_t vma = vext_vma(desc); \
457
int i; \
458
\
459
+ VSTART_CHECK_EARLY_EXIT(env); \
460
+ \
461
for (i = env->vstart; i < vl; i++) { \
462
if (!vm && !vext_elem_mask(v0, i)) { \
463
/* set masked-off elements to 1s */ \
464
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
465
uint32_t vma = vext_vma(desc); \
466
target_ulong offset = s1, i_min, i; \
467
\
468
+ VSTART_CHECK_EARLY_EXIT(env); \
469
+ \
470
i_min = MAX(env->vstart, offset); \
471
for (i = i_min; i < vl; i++) { \
472
if (!vm && !vext_elem_mask(v0, i)) { \
473
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
474
uint32_t vma = vext_vma(desc); \
475
target_ulong i_max, i_min, i; \
476
\
477
+ VSTART_CHECK_EARLY_EXIT(env); \
478
+ \
479
i_min = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \
480
i_max = MAX(i_min, env->vstart); \
481
for (i = env->vstart; i < i_max; ++i) { \
482
@@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1, \
483
uint32_t vma = vext_vma(desc); \
484
uint32_t i; \
485
\
486
+ VSTART_CHECK_EARLY_EXIT(env); \
487
+ \
488
for (i = env->vstart; i < vl; i++) { \
489
if (!vm && !vext_elem_mask(v0, i)) { \
490
/* set masked-off elements to 1s */ \
491
@@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1, \
492
uint32_t vma = vext_vma(desc); \
493
uint32_t i; \
494
\
495
+ VSTART_CHECK_EARLY_EXIT(env); \
496
+ \
497
for (i = env->vstart; i < vl; i++) { \
498
if (!vm && !vext_elem_mask(v0, i)) { \
499
/* set masked-off elements to 1s */ \
500
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
501
uint64_t index; \
502
uint32_t i; \
503
\
504
+ VSTART_CHECK_EARLY_EXIT(env); \
505
+ \
506
for (i = env->vstart; i < vl; i++) { \
507
if (!vm && !vext_elem_mask(v0, i)) { \
508
/* set masked-off elements to 1s */ \
509
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
510
uint64_t index = s1; \
511
uint32_t i; \
512
\
513
+ VSTART_CHECK_EARLY_EXIT(env); \
514
+ \
515
for (i = env->vstart; i < vl; i++) { \
516
if (!vm && !vext_elem_mask(v0, i)) { \
517
/* set masked-off elements to 1s */ \
518
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \
519
uint32_t vma = vext_vma(desc); \
520
uint32_t i; \
521
\
522
+ VSTART_CHECK_EARLY_EXIT(env); \
523
+ \
524
for (i = env->vstart; i < vl; i++) { \
525
if (!vm && !vext_elem_mask(v0, i)) { \
526
/* set masked-off elements to 1s */ \
527
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
528
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
529
--- a/target/riscv/vector_internals.c
22
--- a/target/riscv/vector_internals.c
530
+++ b/target/riscv/vector_internals.c
23
+++ b/target/riscv/vector_internals.c
531
@@ -XXX,XX +XXX,XX @@ void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
532
uint32_t vma = vext_vma(desc);
25
if (tot - cnt == 0) {
533
uint32_t i;
26
return ;
534
27
}
535
+ VSTART_CHECK_EARLY_EXIT(env);
536
+
28
+
537
for (i = env->vstart; i < vl; i++) {
29
+ if (HOST_BIG_ENDIAN) {
538
if (!vm && !vext_elem_mask(v0, i)) {
30
+ /*
539
/* set masked-off elements to 1s */
31
+ * Deal the situation when the elements are insdie
540
@@ -XXX,XX +XXX,XX @@ void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
32
+ * only one uint64 block including setting the
541
uint32_t vma = vext_vma(desc);
33
+ * masked-off element.
542
uint32_t i;
34
+ */
543
35
+ if (((tot - 1) ^ cnt) < 8) {
544
+ VSTART_CHECK_EARLY_EXIT(env);
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
545
+
37
+ return;
546
for (i = env->vstart; i < vl; i++) {
38
+ }
547
if (!vm && !vext_elem_mask(v0, i)) {
39
+ /*
548
/* set masked-off elements to 1s */
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
52
549
--
53
--
550
2.44.0
54
2.45.1
diff view generated by jsdifflib
New patch
1
From: Yangyu Chen <cyy@cyyself.name>
1
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
4
enable zvkb through the config. This patch gets this fixed.
5
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/cpu.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
24
/* Vector cryptography extensions */
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
32
--
33
2.45.1
34
35
diff view generated by jsdifflib
New patch
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
2
3
In this patch, we modify the decoder to be a freely composable data
4
structure instead of a hardcoded one. It can be dynamically builded up
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
29
target/riscv/cpu.h | 1 +
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
31
target/riscv/cpu.c | 1 +
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
41
uint32_t pmu_avail_ctrs;
42
/* Mapping of events to counters */
43
GHashTable *pmu_event_ctr_map;
44
+ const GPtrArray *decoders;
45
};
46
47
/**
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/tcg/tcg-cpu.h
51
+++ b/target/riscv/tcg/tcg-cpu.h
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
55
56
+struct DisasContext;
57
+struct RISCVCPUConfig;
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
62
+
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
64
+
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
77
error_propagate(errp, local_err);
78
return;
79
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
81
} else if (kvm_enabled()) {
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
83
if (local_err != NULL) {
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/riscv/tcg/tcg-cpu.c
87
+++ b/target/riscv/tcg/tcg-cpu.c
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
89
}
90
}
91
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
93
+{
94
+ GPtrArray *dynamic_decoders;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
97
+ if (decoder_table[i].guard_func &&
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
99
+ g_ptr_array_add(dynamic_decoders,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
101
+ }
102
+ }
103
+
104
+ cpu->decoders = dynamic_decoders;
105
+}
106
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
108
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/riscv/translate.c
113
+++ b/target/riscv/translate.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "exec/helper-info.c.inc"
116
#undef HELPER_H
117
118
+#include "tcg/tcg-cpu.h"
119
+
120
/* global register indices */
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
124
/* FRM is known to contain a valid value. */
125
bool frm_valid;
126
bool insn_start_updated;
127
+ const GPtrArray *decoders;
128
} DisasContext;
129
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
132
return (first_word & 3) == 3 ? 4 : 2;
133
}
134
135
+const RISCVDecoder decoder_table[] = {
136
+ { always_true_p, decode_insn32 },
137
+ { has_xthead_p, decode_xthead},
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
139
+};
140
+
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
142
+
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
144
{
145
- /*
146
- * A table with predicate (i.e., guard) functions and decoder functions
147
- * that are tested in-order until a decoder matches onto the opcode.
148
- */
149
- static const struct {
150
- bool (*guard_func)(const RISCVCPUConfig *);
151
- bool (*decode_func)(DisasContext *, uint32_t);
152
- } decoders[] = {
153
- { always_true_p, decode_insn32 },
154
- { has_xthead_p, decode_xthead },
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
156
- };
157
-
158
ctx->virt_inst_excp = false;
159
ctx->cur_insn_len = insn_len(opcode);
160
/* Check for compressed insn */
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
162
ctx->base.pc_next + 2));
163
ctx->opcode = opcode32;
164
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
167
- decoders[i].decode_func(ctx, opcode32)) {
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
170
+ if (func(ctx, opcode32)) {
171
return;
172
}
173
}
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
176
ctx->zero = tcg_constant_tl(0);
177
ctx->virt_inst_excp = false;
178
+ ctx->decoders = cpu->decoders;
179
}
180
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
182
--
183
2.45.1
diff view generated by jsdifflib
New patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
2
3
The th.sxstatus CSR can be used to identify available custom extension
4
on T-Head CPUs. The CSR is documented here:
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
6
7
An important property of this patch is, that the th.sxstatus MAEE field
8
is not set (indicating that XTheadMae is not available).
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
16
17
Further context can be found on the list:
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
MAINTAINERS | 1 +
27
target/riscv/cpu.h | 3 ++
28
target/riscv/cpu.c | 1 +
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
30
target/riscv/meson.build | 1 +
31
5 files changed, 85 insertions(+)
32
create mode 100644 target/riscv/th_csr.c
33
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
51
uint8_t satp_mode_max_from_map(uint32_t map);
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
53
54
+/* Implemented in th_csr.c */
55
+void th_register_custom_csrs(RISCVCPU *cpu);
56
+
57
#endif /* RISCV_CPU_H */
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
64
#ifndef CONFIG_USER_ONLY
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+ th_register_custom_csrs(cpu);
67
#endif
68
69
/* inherited from parent obj via riscv_cpu_init() */
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
71
new file mode 100644
72
index XXXXXXX..XXXXXXX
73
--- /dev/null
74
+++ b/target/riscv/th_csr.c
75
@@ -XXX,XX +XXX,XX @@
76
+/*
77
+ * T-Head-specific CSRs.
78
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
80
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
82
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
85
+ * This program is distributed in the hope it will be useful, but WITHOUT
86
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
87
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
88
+ * more details.
89
+ *
90
+ * You should have received a copy of the GNU General Public License along with
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "cpu.h"
96
+#include "cpu_vendorid.h"
97
+
98
+#define CSR_TH_SXSTATUS 0x5c0
99
+
100
+/* TH_SXSTATUS bits */
101
+#define TH_SXSTATUS_UCME BIT(16)
102
+#define TH_SXSTATUS_MAEE BIT(21)
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
104
+
105
+typedef struct {
106
+ int csrno;
107
+ int (*insertion_test)(RISCVCPU *cpu);
108
+ riscv_csr_operations csr_ops;
109
+} riscv_csr;
110
+
111
+static RISCVException smode(CPURISCVState *env, int csrno)
112
+{
113
+ if (riscv_has_ext(env, RVS)) {
114
+ return RISCV_EXCP_NONE;
115
+ }
116
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
118
+}
119
+
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
121
+{
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
123
+ return -1;
124
+ }
125
+
126
+ return 0;
127
+}
128
+
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
130
+ target_ulong *val)
131
+{
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
134
+ return RISCV_EXCP_NONE;
135
+}
136
+
137
+static riscv_csr th_csr_list[] = {
138
+ {
139
+ .csrno = CSR_TH_SXSTATUS,
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
142
+ }
143
+};
144
+
145
+void th_register_custom_csrs(RISCVCPU *cpu)
146
+{
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
148
+ int csrno = th_csr_list[i].csrno;
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
152
+ }
153
+ }
154
+}
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
160
'monitor.c',
161
'machine.c',
162
'pmu.c',
163
+ 'th_csr.c',
164
'time_helper.c',
165
'riscv-qmp-cmds.c',
166
))
167
--
168
2.45.1
169
170
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
4
instructions will be affected by Zvfhmin extension.
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
conversions of
7
8
* From 1*SEW(16/32) to 2*SEW(32/64)
9
* From 2*SEW(32/64) to 1*SEW(16/32)
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
18
1 file changed, 18 insertions(+), 2 deletions(-)
19
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
25
}
26
}
27
28
+static bool require_rvfmin(DisasContext *s)
29
+{
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
31
+ return false;
32
+ }
33
+
34
+ switch (s->sew) {
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
42
+}
43
+
44
static bool require_scale_rvf(DisasContext *s)
45
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
48
}
49
50
switch (s->sew) {
51
- case MO_8:
52
- return s->cfg_ptr->ext_zvfhmin;
53
case MO_16:
54
return s->cfg_ptr->ext_zve32f;
55
case MO_32:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
63
}
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
66
{
67
return opfv_narrow_check(s, a) &&
68
+ require_rvfmin(s) &&
69
require_scale_rvfmin(s) &&
70
(s->sew != MO_8);
71
}
72
--
73
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
trans_vmv_v_i , trans_vfmv_v_f and the trans_##NAME macro from
3
The require_scale_rvf function only checks the double width operator for
4
GEN_VMV_WHOLE_TRANS() are calling mark_vs_dirty() in both branches of
4
the vector floating point widen instructions, so most of the widen
5
their 'ifs'. conditionals.
5
checking functions need to add require_rvf for single width operator.
6
6
7
Call it just once in the end like other functions are doing.
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
8
integer to double width float, so the opfxv_widen_check function doesn’t
9
need require_rvf for the single width operator(integer).
8
10
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
13
Message-ID: <20240314175704.478276-9-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
---
16
target/riscv/insn_trans/trans_rvv.c.inc | 11 +++--------
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
17
1 file changed, 3 insertions(+), 8 deletions(-)
18
1 file changed, 5 insertions(+)
18
19
19
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/insn_trans/trans_rvv.c.inc
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
22
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
23
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
24
if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
25
tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd),
26
{
26
MAXSZ(s), MAXSZ(s), simm);
27
return require_rvv(s) &&
27
- mark_vs_dirty(s);
28
+ require_rvf(s) &&
28
} else {
29
require_scale_rvf(s) &&
29
TCGv_i32 desc;
30
(s->sew != MO_8) &&
30
TCGv_i64 s1;
31
vext_check_isa_ill(s) &&
31
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
32
s->cfg_ptr->vlenb, data));
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
33
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
34
{
34
fns[s->sew](dest, s1, tcg_env, desc);
35
return require_rvv(s) &&
35
-
36
+ require_rvf(s) &&
36
- mark_vs_dirty(s);
37
require_scale_rvf(s) &&
37
}
38
(s->sew != MO_8) &&
38
+ mark_vs_dirty(s);
39
vext_check_isa_ill(s) &&
39
return true;
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
40
}
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
41
return false;
42
{
42
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
43
return require_rvv(s) &&
43
44
+ require_rvf(s) &&
44
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
45
require_scale_rvf(s) &&
45
MAXSZ(s), MAXSZ(s), t1);
46
(s->sew != MO_8) &&
46
- mark_vs_dirty(s);
47
vext_check_isa_ill(s) &&
47
} else {
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
48
TCGv_ptr dest;
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
49
TCGv_i32 desc;
50
{
50
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
51
return require_rvv(s) &&
51
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
52
+ require_rvf(s) &&
52
53
require_scale_rvf(s) &&
53
fns[s->sew - 1](dest, t1, tcg_env, desc);
54
(s->sew != MO_8) &&
54
-
55
vext_check_isa_ill(s) &&
55
- mark_vs_dirty(s);
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
56
}
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
57
+ mark_vs_dirty(s);
58
{
58
return true;
59
return reduction_widen_check(s, a) &&
59
}
60
+ require_rvf(s) &&
60
return false;
61
require_scale_rvf(s) &&
61
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
62
(s->sew != MO_8);
62
if (s->vstart_eq_zero) { \
63
}
63
tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd), \
64
vreg_ofs(s, a->rs2), maxsz, maxsz); \
65
- mark_vs_dirty(s); \
66
} else { \
67
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
68
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
69
- mark_vs_dirty(s); \
70
} \
71
+ mark_vs_dirty(s); \
72
return true; \
73
} \
74
return false; \
75
--
64
--
76
2.44.0
65
2.45.1
77
66
78
67
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
trans_vmv_x_s, trans_vmv_s_x, trans_vfmv_f_s and trans_vfmv_s_f aren't
3
The opfv_narrow_check needs to check the single width float operator by
4
setting vstart = 0 after execution. This is usually done by a helper in
4
require_rvf.
5
vector_helper.c but these functions don't use helpers.
6
5
7
We'll set vstart after any potential 'over' brconds, and that will also
6
Signed-off-by: Max Chou <max.chou@sifive.com>
8
mandate a mark_vs_dirty() too.
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
8
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Fixes: dedc53cbc9 ("target/riscv: rvv-1.0: integer scalar move instructions")
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240314175704.478276-3-dbarboza@ventanamicro.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
11
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 10 ++++++++--
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
18
1 file changed, 8 insertions(+), 2 deletions(-)
13
1 file changed, 1 insertion(+)
19
14
20
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
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
25
vec_element_loadi(s, t1, a->rs2, 0, true);
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
26
tcg_gen_trunc_i64_tl(dest, t1);
21
{
27
gen_set_gpr(s, a->rd, dest);
22
return opfv_narrow_check(s, a) &&
28
+ tcg_gen_movi_tl(cpu_vstart, 0);
23
+ require_rvf(s) &&
29
+ mark_vs_dirty(s);
24
require_scale_rvf(s) &&
30
return true;
25
(s->sew != MO_8);
31
}
26
}
32
return false;
33
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
34
s1 = get_gpr(s, a->rs1, EXT_NONE);
35
tcg_gen_ext_tl_i64(t1, s1);
36
vec_element_storei(s, a->rd, 0, t1);
37
- mark_vs_dirty(s);
38
gen_set_label(over);
39
+ tcg_gen_movi_tl(cpu_vstart, 0);
40
+ mark_vs_dirty(s);
41
return true;
42
}
43
return false;
44
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
45
}
46
47
mark_fs_dirty(s);
48
+ tcg_gen_movi_tl(cpu_vstart, 0);
49
+ mark_vs_dirty(s);
50
return true;
51
}
52
return false;
53
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
54
do_nanbox(s, t1, cpu_fpr[a->rs1]);
55
56
vec_element_storei(s, a->rd, 0, t1);
57
- mark_vs_dirty(s);
58
gen_set_label(over);
59
+ tcg_gen_movi_tl(cpu_vstart, 0);
60
+ mark_vs_dirty(s);
61
return true;
62
}
63
return false;
64
--
27
--
65
2.44.0
28
2.45.1
diff view generated by jsdifflib
1
From: Ivan Klokov <ivan.klokov@syntacore.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
The vstart_eq_zero flag is updated at the beginning of the translation
3
If the checking functions check both the single and double width
4
phase from the env->vstart variable. During the execution phase all
4
operators at the same time, then the single width operator checking
5
functions will set env->vstart = 0 after a successful execution, but the
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
vstart_eq_zero flag remains the same as at the start of the block. This
7
will wrongly cause SIGILLs in translations that requires env->vstart = 0
8
and might be reading vstart_eq_zero = false.
9
6
10
This patch adds a new finalize_rvv_inst() helper that is called at the
7
Signed-off-by: Max Chou <max.chou@sifive.com>
11
end of each vector instruction that will both update vstart_eq_zero and
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
do a mark_vs_dirty().
9
Cc: qemu-stable <qemu-stable@nongnu.org>
13
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
14
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1976
15
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-ID: <20240314175704.478276-10-dbarboza@ventanamicro.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
12
---
22
target/riscv/translate.c | 6 ++
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
23
target/riscv/insn_trans/trans_rvbf16.c.inc | 6 +-
14
1 file changed, 4 insertions(+), 12 deletions(-)
24
target/riscv/insn_trans/trans_rvv.c.inc | 83 ++++++++++++----------
25
target/riscv/insn_trans/trans_rvvk.c.inc | 12 ++--
26
4 files changed, 59 insertions(+), 48 deletions(-)
27
15
28
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/translate.c
31
+++ b/target/riscv/translate.c
32
@@ -XXX,XX +XXX,XX @@ static void mark_vs_dirty(DisasContext *ctx)
33
static inline void mark_vs_dirty(DisasContext *ctx) { }
34
#endif
35
36
+static void finalize_rvv_inst(DisasContext *ctx)
37
+{
38
+ mark_vs_dirty(ctx);
39
+ ctx->vstart_eq_zero = true;
40
+}
41
+
42
static void gen_set_rm(DisasContext *ctx, int rm)
43
{
44
if (ctx->frm == rm) {
45
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
48
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
49
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
50
ctx->cfg_ptr->vlenb,
51
ctx->cfg_ptr->vlenb, data,
52
gen_helper_vfncvtbf16_f_f_w);
53
- mark_vs_dirty(ctx);
54
+ finalize_rvv_inst(ctx);
55
return true;
56
}
57
return false;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
59
ctx->cfg_ptr->vlenb,
60
ctx->cfg_ptr->vlenb, data,
61
gen_helper_vfwcvtbf16_f_f_v);
62
- mark_vs_dirty(ctx);
63
+ finalize_rvv_inst(ctx);
64
return true;
65
}
66
return false;
67
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
68
ctx->cfg_ptr->vlenb,
69
ctx->cfg_ptr->vlenb, data,
70
gen_helper_vfwmaccbf16_vv);
71
- mark_vs_dirty(ctx);
72
+ finalize_rvv_inst(ctx);
73
return true;
74
}
75
return false;
76
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
77
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
79
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
80
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
81
21
return require_rvv(s) &&
82
gen_helper_vsetvl(dst, tcg_env, s1, s2);
22
require_rvf(s) &&
83
gen_set_gpr(s, rd, dst);
23
require_scale_rvf(s) &&
84
- mark_vs_dirty(s);
24
- (s->sew != MO_8) &&
85
+ finalize_rvv_inst(s);
25
vext_check_isa_ill(s) &&
86
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
87
gen_update_pc(s, s->cur_insn_len);
88
lookup_and_goto_ptr(s);
89
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
90
91
gen_helper_vsetvl(dst, tcg_env, s1, s2);
92
gen_set_gpr(s, rd, dst);
93
- mark_vs_dirty(s);
94
+ finalize_rvv_inst(s);
95
gen_update_pc(s, s->cur_insn_len);
96
lookup_and_goto_ptr(s);
97
s->base.is_jmp = DISAS_NORETURN;
98
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
99
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
100
}
101
102
+ finalize_rvv_inst(s);
103
return true;
104
}
27
}
105
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
106
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
29
return require_rvv(s) &&
107
30
require_rvf(s) &&
108
fn(dest, mask, base, stride, tcg_env, desc);
31
require_scale_rvf(s) &&
109
32
- (s->sew != MO_8) &&
110
+ finalize_rvv_inst(s);
33
vext_check_isa_ill(s) &&
111
return true;
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
112
}
35
}
113
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
114
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
37
return require_rvv(s) &&
115
38
require_rvf(s) &&
116
fn(dest, mask, base, index, tcg_env, desc);
39
require_scale_rvf(s) &&
117
40
- (s->sew != MO_8) &&
118
+ finalize_rvv_inst(s);
41
vext_check_isa_ill(s) &&
119
return true;
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
120
}
43
}
121
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
122
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
45
return require_rvv(s) &&
123
46
require_rvf(s) &&
124
fn(dest, mask, base, tcg_env, desc);
47
require_scale_rvf(s) &&
125
48
- (s->sew != MO_8) &&
126
- mark_vs_dirty(s);
49
vext_check_isa_ill(s) &&
127
+ finalize_rvv_inst(s);
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
128
return true;
129
}
51
}
130
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
131
@@ -XXX,XX +XXX,XX @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
53
{
132
54
return opfv_widen_check(s, a) &&
133
fn(dest, base, tcg_env, desc);
55
require_rvfmin(s) &&
134
56
- require_scale_rvfmin(s) &&
135
+ finalize_rvv_inst(s);
57
- (s->sew != MO_8);
136
return true;
58
+ require_scale_rvfmin(s);
137
}
59
}
138
60
139
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
140
tcg_env, s->cfg_ptr->vlenb,
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
141
s->cfg_ptr->vlenb, data, fn);
63
{
142
}
64
return opfv_narrow_check(s, a) &&
143
- mark_vs_dirty(s);
65
require_rvfmin(s) &&
144
+ finalize_rvv_inst(s);
66
- require_scale_rvfmin(s) &&
145
return true;
67
- (s->sew != MO_8);
68
+ require_scale_rvfmin(s);
146
}
69
}
147
70
148
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
149
72
{
150
fn(dest, mask, src1, src2, tcg_env, desc);
73
return opfv_narrow_check(s, a) &&
151
74
require_rvf(s) &&
152
- mark_vs_dirty(s);
75
- require_scale_rvf(s) &&
153
+ finalize_rvv_inst(s);
76
- (s->sew != MO_8);
154
return true;
77
+ require_scale_rvf(s);
155
}
78
}
156
79
157
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
158
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
159
src1, MAXSZ(s), MAXSZ(s));
82
{
160
83
return reduction_widen_check(s, a) &&
161
- mark_vs_dirty(s);
84
require_rvf(s) &&
162
+ finalize_rvv_inst(s);
85
- require_scale_rvf(s) &&
163
return true;
86
- (s->sew != MO_8);
164
}
87
+ require_scale_rvf(s);
165
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
166
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
167
168
fn(dest, mask, src1, src2, tcg_env, desc);
169
170
- mark_vs_dirty(s);
171
+ finalize_rvv_inst(s);
172
return true;
173
}
88
}
174
89
175
@@ -XXX,XX +XXX,XX @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
176
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
177
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
178
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
179
- mark_vs_dirty(s);
180
+ finalize_rvv_inst(s);
181
return true;
182
}
183
return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode);
184
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
185
tcg_env, s->cfg_ptr->vlenb,
186
s->cfg_ptr->vlenb,
187
data, fn);
188
- mark_vs_dirty(s);
189
+ finalize_rvv_inst(s);
190
return true;
191
}
192
return false;
193
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
194
vreg_ofs(s, a->rs2),
195
tcg_env, s->cfg_ptr->vlenb,
196
s->cfg_ptr->vlenb, data, fn);
197
- mark_vs_dirty(s);
198
+ finalize_rvv_inst(s);
199
return true;
200
}
201
return false;
202
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
203
tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
204
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
205
s->cfg_ptr->vlenb, data, fn);
206
- mark_vs_dirty(s);
207
+ finalize_rvv_inst(s);
208
return true;
209
}
210
211
@@ -XXX,XX +XXX,XX @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
212
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
213
src1, MAXSZ(s), MAXSZ(s));
214
215
- mark_vs_dirty(s);
216
+ finalize_rvv_inst(s);
217
return true;
218
}
219
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
220
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
221
s->cfg_ptr->vlenb, \
222
s->cfg_ptr->vlenb, data, \
223
fns[s->sew]); \
224
- mark_vs_dirty(s); \
225
+ finalize_rvv_inst(s); \
226
return true; \
227
} \
228
return false; \
229
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
230
s->cfg_ptr->vlenb, data,
231
fns[s->sew]);
232
}
233
- mark_vs_dirty(s);
234
+ finalize_rvv_inst(s);
235
return true;
236
}
237
return false;
238
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
239
fns[s->sew](dest, s1_i64, tcg_env, desc);
240
}
241
242
- mark_vs_dirty(s);
243
+ finalize_rvv_inst(s);
244
return true;
245
}
246
return false;
247
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
248
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
249
fns[s->sew](dest, s1, tcg_env, desc);
250
}
251
- mark_vs_dirty(s);
252
+ finalize_rvv_inst(s);
253
return true;
254
}
255
return false;
256
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
257
s->cfg_ptr->vlenb, \
258
s->cfg_ptr->vlenb, data, \
259
fns[s->sew - 1]); \
260
- mark_vs_dirty(s); \
261
+ finalize_rvv_inst(s); \
262
return true; \
263
} \
264
return false; \
265
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
266
267
fn(dest, mask, t1, src2, tcg_env, desc);
268
269
- mark_vs_dirty(s);
270
+ finalize_rvv_inst(s);
271
return true;
272
}
273
274
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
275
s->cfg_ptr->vlenb, \
276
s->cfg_ptr->vlenb, data, \
277
fns[s->sew - 1]); \
278
- mark_vs_dirty(s); \
279
+ finalize_rvv_inst(s); \
280
return true; \
281
} \
282
return false; \
283
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
284
s->cfg_ptr->vlenb, \
285
s->cfg_ptr->vlenb, data, \
286
fns[s->sew - 1]); \
287
- mark_vs_dirty(s); \
288
+ finalize_rvv_inst(s); \
289
return true; \
290
} \
291
return false; \
292
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
293
vreg_ofs(s, a->rs2), tcg_env,
294
s->cfg_ptr->vlenb,
295
s->cfg_ptr->vlenb, data, fn);
296
- mark_vs_dirty(s);
297
+ finalize_rvv_inst(s);
298
return true;
299
}
300
return false;
301
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
302
303
fns[s->sew - 1](dest, t1, tcg_env, desc);
304
}
305
- mark_vs_dirty(s);
306
+ finalize_rvv_inst(s);
307
return true;
308
}
309
return false;
310
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
311
s->cfg_ptr->vlenb, \
312
s->cfg_ptr->vlenb, data, \
313
fns[s->sew - 1]); \
314
- mark_vs_dirty(s); \
315
+ finalize_rvv_inst(s); \
316
return true; \
317
} \
318
return false; \
319
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
320
s->cfg_ptr->vlenb, \
321
s->cfg_ptr->vlenb, data, \
322
fns[s->sew]); \
323
- mark_vs_dirty(s); \
324
+ finalize_rvv_inst(s); \
325
return true; \
326
} \
327
return false; \
328
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
329
s->cfg_ptr->vlenb, \
330
s->cfg_ptr->vlenb, data, \
331
fns[s->sew - 1]); \
332
- mark_vs_dirty(s); \
333
+ finalize_rvv_inst(s); \
334
return true; \
335
} \
336
return false; \
337
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
338
s->cfg_ptr->vlenb, \
339
s->cfg_ptr->vlenb, data, \
340
fns[s->sew]); \
341
- mark_vs_dirty(s); \
342
+ finalize_rvv_inst(s); \
343
return true; \
344
} \
345
return false; \
346
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
347
vreg_ofs(s, a->rs2), tcg_env, \
348
s->cfg_ptr->vlenb, \
349
s->cfg_ptr->vlenb, data, fn); \
350
- mark_vs_dirty(s); \
351
+ finalize_rvv_inst(s); \
352
return true; \
353
} \
354
return false; \
355
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
356
tcg_env, s->cfg_ptr->vlenb, \
357
s->cfg_ptr->vlenb, \
358
data, fn); \
359
- mark_vs_dirty(s); \
360
+ finalize_rvv_inst(s); \
361
return true; \
362
} \
363
return false; \
364
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
365
vreg_ofs(s, a->rs2), tcg_env,
366
s->cfg_ptr->vlenb,
367
s->cfg_ptr->vlenb, data, fns[s->sew]);
368
- mark_vs_dirty(s);
369
+ finalize_rvv_inst(s);
370
return true;
371
}
372
return false;
373
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
374
tcg_env, s->cfg_ptr->vlenb,
375
s->cfg_ptr->vlenb,
376
data, fns[s->sew]);
377
- mark_vs_dirty(s);
378
+ finalize_rvv_inst(s);
379
return true;
380
}
381
return false;
382
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
383
tcg_gen_trunc_i64_tl(dest, t1);
384
gen_set_gpr(s, a->rd, dest);
385
tcg_gen_movi_tl(cpu_vstart, 0);
386
- mark_vs_dirty(s);
387
+ finalize_rvv_inst(s);
388
return true;
389
}
390
return false;
391
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
392
vec_element_storei(s, a->rd, 0, t1);
393
gen_set_label(over);
394
tcg_gen_movi_tl(cpu_vstart, 0);
395
- mark_vs_dirty(s);
396
+ finalize_rvv_inst(s);
397
return true;
398
}
399
return false;
400
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
401
402
mark_fs_dirty(s);
403
tcg_gen_movi_tl(cpu_vstart, 0);
404
- mark_vs_dirty(s);
405
+ finalize_rvv_inst(s);
406
return true;
407
}
408
return false;
409
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
410
do_nanbox(s, t1, cpu_fpr[a->rs1]);
411
412
vec_element_storei(s, a->rd, 0, t1);
413
+
414
gen_set_label(over);
415
tcg_gen_movi_tl(cpu_vstart, 0);
416
- mark_vs_dirty(s);
417
+ finalize_rvv_inst(s);
418
return true;
419
}
420
return false;
421
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
422
423
tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
424
MAXSZ(s), MAXSZ(s), dest);
425
- mark_vs_dirty(s);
426
+ finalize_rvv_inst(s);
427
} else {
428
static gen_helper_opivx * const fns[4] = {
429
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
430
@@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
431
endian_ofs(s, a->rs2, a->rs1),
432
MAXSZ(s), MAXSZ(s));
433
}
434
- mark_vs_dirty(s);
435
+ finalize_rvv_inst(s);
436
} else {
437
static gen_helper_opivx * const fns[4] = {
438
gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
439
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
440
tcg_env, s->cfg_ptr->vlenb,
441
s->cfg_ptr->vlenb, data,
442
fns[s->sew]);
443
- mark_vs_dirty(s);
444
+ finalize_rvv_inst(s);
445
return true;
446
}
447
return false;
448
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
449
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
450
tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
451
} \
452
- mark_vs_dirty(s); \
453
+ finalize_rvv_inst(s); \
454
return true; \
455
} \
456
return false; \
457
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
458
s->cfg_ptr->vlenb,
459
s->cfg_ptr->vlenb, data, fn);
460
461
- mark_vs_dirty(s);
462
+ finalize_rvv_inst(s);
463
return true;
464
}
465
466
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
467
index XXXXXXX..XXXXXXX 100644
468
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
469
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
470
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
471
vreg_ofs(s, a->rs2), tcg_env, \
472
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
473
data, fns[s->sew]); \
474
- mark_vs_dirty(s); \
475
+ finalize_rvv_inst(s); \
476
return true; \
477
} \
478
return false; \
479
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
480
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
481
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
482
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
483
- mark_vs_dirty(s); \
484
+ finalize_rvv_inst(s); \
485
return true; \
486
} \
487
return false; \
488
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
489
tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); \
490
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
491
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
492
- mark_vs_dirty(s); \
493
+ finalize_rvv_inst(s); \
494
return true; \
495
} \
496
return false; \
497
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
498
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
499
data, gen_helper_##NAME); \
500
\
501
- mark_vs_dirty(s); \
502
+ finalize_rvv_inst(s); \
503
return true; \
504
} \
505
return false; \
506
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
507
s->sew == MO_32 ?
508
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
509
510
- mark_vs_dirty(s);
511
+ finalize_rvv_inst(s);
512
return true;
513
}
514
return false;
515
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
516
s->sew == MO_32 ?
517
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
518
519
- mark_vs_dirty(s);
520
+ finalize_rvv_inst(s);
521
return true;
522
}
523
return false;
524
--
91
--
525
2.44.0
92
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
vmvr_v isn't handling the case where the host might be big endian and
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
the bytes to be copied aren't sequential.
4
checking first if virt_enabled && !first_stage, and then considering the
5
regular inst/load/store faults.
5
6
6
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
7
There's no mention in the spec about guest page fault being a higher
7
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
9
10
"Attempting to fetch an instruction from a PMP region that does not have
11
execute permissions raises an instruction access-fault exception.
12
Attempting to execute a load or load-reserved instruction which accesses
13
a physical address within a PMP region without read permissions raises a
14
load access-fault exception. Attempting to execute a store,
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
20
regardless of also being a first or second stage fault.
21
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
8
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240314175704.478276-4-dbarboza@ventanamicro.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
34
---
15
target/riscv/vector_helper.c | 10 +++++++++-
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
16
1 file changed, 9 insertions(+), 1 deletion(-)
36
1 file changed, 12 insertions(+), 10 deletions(-)
17
37
18
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/vector_helper.c
40
--- a/target/riscv/cpu_helper.c
21
+++ b/target/riscv/vector_helper.c
41
+++ b/target/riscv/cpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
23
uint32_t startb = env->vstart * sewb;
43
24
uint32_t i = startb;
44
switch (access_type) {
25
45
case MMU_INST_FETCH:
26
+ if (HOST_BIG_ENDIAN && i % 8 != 0) {
46
- if (env->virt_enabled && !first_stage) {
27
+ uint32_t j = ROUND_UP(i, 8);
47
+ if (pmp_violation) {
28
+ memcpy((uint8_t *)vd + H1(j - 1),
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
29
+ (uint8_t *)vs2 + H1(j - 1),
49
+ } else if (env->virt_enabled && !first_stage) {
30
+ j - i);
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
31
+ i = j;
51
} else {
32
+ }
52
- cs->exception_index = pmp_violation ?
33
+
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
34
memcpy((uint8_t *)vd + H1(i),
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
35
(uint8_t *)vs2 + H1(i),
55
}
36
- maxsz - startb);
56
break;
37
+ maxsz - i);
57
case MMU_DATA_LOAD:
38
58
- if (two_stage && !first_stage) {
39
env->vstart = 0;
59
+ if (pmp_violation) {
40
}
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
63
} else {
64
- cs->exception_index = pmp_violation ?
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
68
break;
69
case MMU_DATA_STORE:
70
- if (two_stage && !first_stage) {
71
+ if (pmp_violation) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
75
} else {
76
- cs->exception_index = pmp_violation ?
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
78
- RISCV_EXCP_STORE_PAGE_FAULT;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
80
}
81
break;
82
default:
41
--
83
--
42
2.44.0
84
2.45.1
diff view generated by jsdifflib
1
From: Irina Ryapolova <irina.ryapolova@syntacore.com>
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
2
2
3
Need to convert mmu_idx to privilege mode for PMP function.
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
5
translation part, mtval2 will be set in case of successes 2 stage translation but
6
failed pmp check.
4
7
5
Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
6
Fixes: b297129ae1 ("target/riscv: propagate PMP permission to TLB page")
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
13
is set to zero...*
14
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
9
Message-ID: <20240320172828.23965-1-irina.ryapolova@syntacore.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
21
---
12
target/riscv/cpu_helper.c | 2 +-
22
target/riscv/cpu_helper.c | 12 ++++++------
13
1 file changed, 1 insertion(+), 1 deletion(-)
23
1 file changed, 6 insertions(+), 6 deletions(-)
14
24
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
27
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
bool two_stage_lookup = mmuidx_2stage(mmu_idx);
30
__func__, pa, ret, prot_pmp, tlb_size);
21
bool two_stage_indirect_error = false;
31
22
int ret = TRANSLATE_FAIL;
32
prot &= prot_pmp;
23
- int mode = mmu_idx;
33
- }
24
+ int mode = mmuidx_priv(mmu_idx);
34
-
25
/* default TLB page size */
35
- if (ret != TRANSLATE_SUCCESS) {
26
target_ulong tlb_size = TARGET_PAGE_SIZE;
36
+ } else {
27
37
/*
38
* Guest physical address translation failed, this is a HS
39
* level exception
40
*/
41
first_stage_error = false;
42
- env->guest_phys_fault_addr = (im_address |
43
- (address &
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
45
+ if (ret != TRANSLATE_PMP_FAIL) {
46
+ env->guest_phys_fault_addr = (im_address |
47
+ (address &
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
49
+ }
50
}
51
}
52
} else {
28
--
53
--
29
2.44.0
54
2.45.1
diff view generated by jsdifflib
New patch
1
From: Rob Bradford <rbradford@rivosinc.com>
1
2
3
This extension has now been ratified:
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
5
removed.
6
7
Since this is now a ratified extension add it to the list of extensions
8
included in the "max" CPU variant.
9
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu.c | 2 +-
19
target/riscv/tcg/tcg-cpu.c | 2 +-
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
32
};
33
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
40
const RISCVCPUMultiExtConfig *prop;
41
42
/* Enable RVG, RVJ and RVV that are disabled by default */
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
48
--
49
2.45.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
All helpers that rely on vstart >= vl are now doing early exits using
3
When running the instruction
4
the VSTART_CHECK_EARLY_EXIT() macro. This macro will not only exit the
5
helper but also clear vstart.
6
4
7
We're still left with brconds that are skipping the helper, which is the
5
```
8
only place where we're clearing vstart. The pattern goes like this:
6
cbo.flush 0(x0)
7
```
9
8
10
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
9
QEMU would segfault.
11
(... calls helper that clears vstart ...)
12
gen_set_label(over);
13
return true;
14
10
15
This means that every time we jump to 'over' we're not clearing vstart,
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
16
which is an oversight that we're doing across the board.
12
allocated.
17
13
18
Instead of setting vstart = 0 manually after each 'over' jump, remove
14
In order to fix this let's use the existing get_address()
19
those brconds that are skipping helpers. The exception will be
15
helper. This also has the benefit of performing pointer mask
20
trans_vmv_s_x() and trans_vfmv_s_f(): they don't use a helper and are
16
calculations on the address specified in rs1.
21
already clearing vstart manually in the 'over' label.
22
17
23
While we're at it, remove the (vl == 0) brconds from trans_rvbf16.c.inc
18
The pointer masking specificiation specifically states:
24
too since they're unneeded.
25
19
26
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
20
"""
27
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
30
Message-ID: <20240314175704.478276-8-dbarboza@ventanamicro.com>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
31
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
---
34
---
33
target/riscv/insn_trans/trans_rvbf16.c.inc | 12 ---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
34
target/riscv/insn_trans/trans_rvv.c.inc | 99 ----------------------
36
1 file changed, 12 insertions(+), 4 deletions(-)
35
target/riscv/insn_trans/trans_rvvk.c.inc | 18 ----
36
3 files changed, 129 deletions(-)
37
37
38
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
39
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
41
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
42
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
42
@@ -XXX,XX +XXX,XX @@
43
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
44
if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {
44
{
45
uint32_t data = 0;
45
REQUIRE_ZICBOM(ctx);
46
- TCGLabel *over = gen_new_label();
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
47
47
+ TCGv src = get_address(ctx, a->rs1, 0);
48
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
48
+
49
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
50
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
51
52
data = FIELD_DP32(data, VDATA, VM, a->vm);
53
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
54
@@ -XXX,XX +XXX,XX @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
55
ctx->cfg_ptr->vlenb, data,
56
gen_helper_vfncvtbf16_f_f_w);
57
mark_vs_dirty(ctx);
58
- gen_set_label(over);
59
return true;
60
}
61
return false;
62
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
63
64
if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {
65
uint32_t data = 0;
66
- TCGLabel *over = gen_new_label();
67
68
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
69
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
70
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
71
72
data = FIELD_DP32(data, VDATA, VM, a->vm);
73
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
74
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
75
ctx->cfg_ptr->vlenb, data,
76
gen_helper_vfwcvtbf16_f_f_v);
77
mark_vs_dirty(ctx);
78
- gen_set_label(over);
79
return true;
80
}
81
return false;
82
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
83
if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
84
vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
85
uint32_t data = 0;
86
- TCGLabel *over = gen_new_label();
87
88
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
89
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
90
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
91
92
data = FIELD_DP32(data, VDATA, VM, a->vm);
93
data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
94
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
95
ctx->cfg_ptr->vlenb, data,
96
gen_helper_vfwmaccbf16_vv);
97
mark_vs_dirty(ctx);
98
- gen_set_label(over);
99
return true;
100
}
101
return false;
102
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/riscv/insn_trans/trans_rvv.c.inc
105
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
106
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
107
TCGv base;
108
TCGv_i32 desc;
109
110
- TCGLabel *over = gen_new_label();
111
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
112
-
113
dest = tcg_temp_new_ptr();
114
mask = tcg_temp_new_ptr();
115
base = get_gpr(s, rs1, EXT_NONE);
116
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
117
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
118
}
119
120
- gen_set_label(over);
121
return true;
50
return true;
122
}
51
}
123
52
124
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
125
TCGv base, stride;
54
{
126
TCGv_i32 desc;
55
REQUIRE_ZICBOM(ctx);
127
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
128
- TCGLabel *over = gen_new_label();
57
+ TCGv src = get_address(ctx, a->rs1, 0);
129
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
58
+
130
-
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
131
dest = tcg_temp_new_ptr();
132
mask = tcg_temp_new_ptr();
133
base = get_gpr(s, rs1, EXT_NONE);
134
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
135
136
fn(dest, mask, base, stride, tcg_env, desc);
137
138
- gen_set_label(over);
139
return true;
60
return true;
140
}
61
}
141
62
142
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
143
TCGv base;
64
{
144
TCGv_i32 desc;
65
REQUIRE_ZICBOM(ctx);
145
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
146
- TCGLabel *over = gen_new_label();
67
+ TCGv src = get_address(ctx, a->rs1, 0);
147
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
68
+
148
-
69
+ gen_helper_cbo_inval(tcg_env, src);
149
dest = tcg_temp_new_ptr();
150
mask = tcg_temp_new_ptr();
151
index = tcg_temp_new_ptr();
152
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
153
154
fn(dest, mask, base, index, tcg_env, desc);
155
156
- gen_set_label(over);
157
return true;
70
return true;
158
}
71
}
159
72
160
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
161
TCGv base;
74
{
162
TCGv_i32 desc;
75
REQUIRE_ZICBOZ(ctx);
163
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
164
- TCGLabel *over = gen_new_label();
77
+ TCGv src = get_address(ctx, a->rs1, 0);
165
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
78
+
166
-
79
+ gen_helper_cbo_zero(tcg_env, src);
167
dest = tcg_temp_new_ptr();
168
mask = tcg_temp_new_ptr();
169
base = get_gpr(s, rs1, EXT_NONE);
170
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
171
fn(dest, mask, base, tcg_env, desc);
172
173
mark_vs_dirty(s);
174
- gen_set_label(over);
175
return true;
80
return true;
176
}
81
}
177
178
@@ -XXX,XX +XXX,XX @@ static inline bool
179
do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
180
gen_helper_gvec_4_ptr *fn)
181
{
182
- TCGLabel *over = gen_new_label();
183
-
184
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
185
-
186
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
187
gvec_fn(s->sew, vreg_ofs(s, a->rd),
188
vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
189
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
190
s->cfg_ptr->vlenb, data, fn);
191
}
192
mark_vs_dirty(s);
193
- gen_set_label(over);
194
return true;
195
}
196
197
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
198
TCGv_i32 desc;
199
uint32_t data = 0;
200
201
- TCGLabel *over = gen_new_label();
202
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
203
-
204
dest = tcg_temp_new_ptr();
205
mask = tcg_temp_new_ptr();
206
src2 = tcg_temp_new_ptr();
207
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
208
fn(dest, mask, src1, src2, tcg_env, desc);
209
210
mark_vs_dirty(s);
211
- gen_set_label(over);
212
return true;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
216
TCGv_i32 desc;
217
uint32_t data = 0;
218
219
- TCGLabel *over = gen_new_label();
220
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
221
-
222
dest = tcg_temp_new_ptr();
223
mask = tcg_temp_new_ptr();
224
src2 = tcg_temp_new_ptr();
225
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
226
fn(dest, mask, src1, src2, tcg_env, desc);
227
228
mark_vs_dirty(s);
229
- gen_set_label(over);
230
return true;
231
}
232
233
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
234
{
235
if (checkfn(s, a)) {
236
uint32_t data = 0;
237
- TCGLabel *over = gen_new_label();
238
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
239
240
data = FIELD_DP32(data, VDATA, VM, a->vm);
241
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
242
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
243
s->cfg_ptr->vlenb,
244
data, fn);
245
mark_vs_dirty(s);
246
- gen_set_label(over);
247
return true;
248
}
249
return false;
250
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
251
{
252
if (opiwv_widen_check(s, a)) {
253
uint32_t data = 0;
254
- TCGLabel *over = gen_new_label();
255
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
256
257
data = FIELD_DP32(data, VDATA, VM, a->vm);
258
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
259
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
260
tcg_env, s->cfg_ptr->vlenb,
261
s->cfg_ptr->vlenb, data, fn);
262
mark_vs_dirty(s);
263
- gen_set_label(over);
264
return true;
265
}
266
return false;
267
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
268
gen_helper_gvec_4_ptr *fn, DisasContext *s)
269
{
270
uint32_t data = 0;
271
- TCGLabel *over = gen_new_label();
272
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
273
274
data = FIELD_DP32(data, VDATA, VM, vm);
275
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
276
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
277
vreg_ofs(s, vs2), tcg_env, s->cfg_ptr->vlenb,
278
s->cfg_ptr->vlenb, data, fn);
279
mark_vs_dirty(s);
280
- gen_set_label(over);
281
return true;
282
}
283
284
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
285
gen_helper_##NAME##_h, \
286
gen_helper_##NAME##_w, \
287
}; \
288
- TCGLabel *over = gen_new_label(); \
289
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
290
\
291
data = FIELD_DP32(data, VDATA, VM, a->vm); \
292
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
293
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
294
s->cfg_ptr->vlenb, data, \
295
fns[s->sew]); \
296
mark_vs_dirty(s); \
297
- gen_set_label(over); \
298
return true; \
299
} \
300
return false; \
301
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
302
gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
303
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
304
};
305
- TCGLabel *over = gen_new_label();
306
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
307
308
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
309
tcg_env, s->cfg_ptr->vlenb,
310
s->cfg_ptr->vlenb, data,
311
fns[s->sew]);
312
- gen_set_label(over);
313
}
314
mark_vs_dirty(s);
315
return true;
316
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
317
/* vmv.v.x has rs2 = 0 and vm = 1 */
318
vext_check_ss(s, a->rd, 0, 1)) {
319
TCGv s1;
320
- TCGLabel *over = gen_new_label();
321
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
322
323
s1 = get_gpr(s, a->rs1, EXT_SIGN);
324
325
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
326
}
327
328
mark_vs_dirty(s);
329
- gen_set_label(over);
330
return true;
331
}
332
return false;
333
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
334
gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
335
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
336
};
337
- TCGLabel *over = gen_new_label();
338
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
339
340
s1 = tcg_constant_i64(simm);
341
dest = tcg_temp_new_ptr();
342
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
343
fns[s->sew](dest, s1, tcg_env, desc);
344
345
mark_vs_dirty(s);
346
- gen_set_label(over);
347
}
348
return true;
349
}
350
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
351
gen_helper_##NAME##_w, \
352
gen_helper_##NAME##_d, \
353
}; \
354
- TCGLabel *over = gen_new_label(); \
355
gen_set_rm(s, RISCV_FRM_DYN); \
356
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
357
\
358
data = FIELD_DP32(data, VDATA, VM, a->vm); \
359
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
360
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
361
s->cfg_ptr->vlenb, data, \
362
fns[s->sew - 1]); \
363
mark_vs_dirty(s); \
364
- gen_set_label(over); \
365
return true; \
366
} \
367
return false; \
368
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
369
TCGv_i32 desc;
370
TCGv_i64 t1;
371
372
- TCGLabel *over = gen_new_label();
373
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
374
-
375
dest = tcg_temp_new_ptr();
376
mask = tcg_temp_new_ptr();
377
src2 = tcg_temp_new_ptr();
378
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
379
fn(dest, mask, t1, src2, tcg_env, desc);
380
381
mark_vs_dirty(s);
382
- gen_set_label(over);
383
return true;
384
}
385
386
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
387
static gen_helper_gvec_4_ptr * const fns[2] = { \
388
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
389
}; \
390
- TCGLabel *over = gen_new_label(); \
391
gen_set_rm(s, RISCV_FRM_DYN); \
392
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
393
\
394
data = FIELD_DP32(data, VDATA, VM, a->vm); \
395
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
396
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
397
s->cfg_ptr->vlenb, data, \
398
fns[s->sew - 1]); \
399
mark_vs_dirty(s); \
400
- gen_set_label(over); \
401
return true; \
402
} \
403
return false; \
404
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
405
static gen_helper_gvec_4_ptr * const fns[2] = { \
406
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
407
}; \
408
- TCGLabel *over = gen_new_label(); \
409
gen_set_rm(s, RISCV_FRM_DYN); \
410
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
411
\
412
data = FIELD_DP32(data, VDATA, VM, a->vm); \
413
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
414
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
415
s->cfg_ptr->vlenb, data, \
416
fns[s->sew - 1]); \
417
mark_vs_dirty(s); \
418
- gen_set_label(over); \
419
return true; \
420
} \
421
return false; \
422
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
423
{
424
if (checkfn(s, a)) {
425
uint32_t data = 0;
426
- TCGLabel *over = gen_new_label();
427
gen_set_rm_chkfrm(s, rm);
428
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
429
430
data = FIELD_DP32(data, VDATA, VM, a->vm);
431
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
432
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
433
s->cfg_ptr->vlenb,
434
s->cfg_ptr->vlenb, data, fn);
435
mark_vs_dirty(s);
436
- gen_set_label(over);
437
return true;
438
}
439
return false;
440
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
441
gen_helper_vmv_v_x_w,
442
gen_helper_vmv_v_x_d,
443
};
444
- TCGLabel *over = gen_new_label();
445
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
446
447
t1 = tcg_temp_new_i64();
448
/* NaN-box f[rs1] */
449
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
450
fns[s->sew - 1](dest, t1, tcg_env, desc);
451
452
mark_vs_dirty(s);
453
- gen_set_label(over);
454
}
455
return true;
456
}
457
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
458
gen_helper_##HELPER##_h, \
459
gen_helper_##HELPER##_w, \
460
}; \
461
- TCGLabel *over = gen_new_label(); \
462
gen_set_rm_chkfrm(s, FRM); \
463
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
464
\
465
data = FIELD_DP32(data, VDATA, VM, a->vm); \
466
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
467
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
468
s->cfg_ptr->vlenb, data, \
469
fns[s->sew - 1]); \
470
mark_vs_dirty(s); \
471
- gen_set_label(over); \
472
return true; \
473
} \
474
return false; \
475
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
476
gen_helper_##NAME##_h, \
477
gen_helper_##NAME##_w, \
478
}; \
479
- TCGLabel *over = gen_new_label(); \
480
gen_set_rm(s, RISCV_FRM_DYN); \
481
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
482
\
483
data = FIELD_DP32(data, VDATA, VM, a->vm); \
484
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
485
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
486
s->cfg_ptr->vlenb, data, \
487
fns[s->sew]); \
488
mark_vs_dirty(s); \
489
- gen_set_label(over); \
490
return true; \
491
} \
492
return false; \
493
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
494
gen_helper_##HELPER##_h, \
495
gen_helper_##HELPER##_w, \
496
}; \
497
- TCGLabel *over = gen_new_label(); \
498
gen_set_rm_chkfrm(s, FRM); \
499
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
500
\
501
data = FIELD_DP32(data, VDATA, VM, a->vm); \
502
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
503
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
504
s->cfg_ptr->vlenb, data, \
505
fns[s->sew - 1]); \
506
mark_vs_dirty(s); \
507
- gen_set_label(over); \
508
return true; \
509
} \
510
return false; \
511
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
512
gen_helper_##HELPER##_h, \
513
gen_helper_##HELPER##_w, \
514
}; \
515
- TCGLabel *over = gen_new_label(); \
516
gen_set_rm_chkfrm(s, FRM); \
517
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
518
\
519
data = FIELD_DP32(data, VDATA, VM, a->vm); \
520
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
521
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
522
s->cfg_ptr->vlenb, data, \
523
fns[s->sew]); \
524
mark_vs_dirty(s); \
525
- gen_set_label(over); \
526
return true; \
527
} \
528
return false; \
529
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
530
vext_check_isa_ill(s)) { \
531
uint32_t data = 0; \
532
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
533
- TCGLabel *over = gen_new_label(); \
534
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
535
\
536
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
537
data = \
538
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
539
s->cfg_ptr->vlenb, \
540
s->cfg_ptr->vlenb, data, fn); \
541
mark_vs_dirty(s); \
542
- gen_set_label(over); \
543
return true; \
544
} \
545
return false; \
546
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
547
s->vstart_eq_zero) { \
548
uint32_t data = 0; \
549
gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
550
- TCGLabel *over = gen_new_label(); \
551
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
552
\
553
data = FIELD_DP32(data, VDATA, VM, a->vm); \
554
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
555
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
556
s->cfg_ptr->vlenb, \
557
data, fn); \
558
mark_vs_dirty(s); \
559
- gen_set_label(over); \
560
return true; \
561
} \
562
return false; \
563
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
564
require_align(a->rd, s->lmul) &&
565
s->vstart_eq_zero) {
566
uint32_t data = 0;
567
- TCGLabel *over = gen_new_label();
568
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
569
570
data = FIELD_DP32(data, VDATA, VM, a->vm);
571
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
572
@@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
573
s->cfg_ptr->vlenb,
574
s->cfg_ptr->vlenb, data, fns[s->sew]);
575
mark_vs_dirty(s);
576
- gen_set_label(over);
577
return true;
578
}
579
return false;
580
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
581
require_align(a->rd, s->lmul) &&
582
require_vm(a->vm, a->rd)) {
583
uint32_t data = 0;
584
- TCGLabel *over = gen_new_label();
585
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
586
587
data = FIELD_DP32(data, VDATA, VM, a->vm);
588
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
589
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
590
s->cfg_ptr->vlenb,
591
data, fns[s->sew]);
592
mark_vs_dirty(s);
593
- gen_set_label(over);
594
return true;
595
}
596
return false;
597
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
598
gen_helper_vcompress_vm_b, gen_helper_vcompress_vm_h,
599
gen_helper_vcompress_vm_w, gen_helper_vcompress_vm_d,
600
};
601
- TCGLabel *over = gen_new_label();
602
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
603
604
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
605
data = FIELD_DP32(data, VDATA, VTA, s->vta);
606
@@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
607
s->cfg_ptr->vlenb, data,
608
fns[s->sew]);
609
mark_vs_dirty(s);
610
- gen_set_label(over);
611
return true;
612
}
613
return false;
614
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
615
{
616
uint32_t data = 0;
617
gen_helper_gvec_3_ptr *fn;
618
- TCGLabel *over = gen_new_label();
619
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
620
621
static gen_helper_gvec_3_ptr * const fns[6][4] = {
622
{
623
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
624
s->cfg_ptr->vlenb, data, fn);
625
626
mark_vs_dirty(s);
627
- gen_set_label(over);
628
return true;
629
}
630
631
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
632
index XXXXXXX..XXXXXXX 100644
633
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
634
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
635
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
636
gen_helper_##NAME##_w, \
637
gen_helper_##NAME##_d, \
638
}; \
639
- TCGLabel *over = gen_new_label(); \
640
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
641
\
642
data = FIELD_DP32(data, VDATA, VM, a->vm); \
643
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
644
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
645
s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, \
646
data, fns[s->sew]); \
647
mark_vs_dirty(s); \
648
- gen_set_label(over); \
649
return true; \
650
} \
651
return false; \
652
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
653
TCGv_ptr rd_v, rs2_v; \
654
TCGv_i32 desc, egs; \
655
uint32_t data = 0; \
656
- TCGLabel *over = gen_new_label(); \
657
\
658
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
659
/* save opcode for unwinding in case we throw an exception */ \
660
decode_save_opc(s); \
661
egs = tcg_constant_i32(EGS); \
662
gen_helper_egs_check(egs, tcg_env); \
663
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
664
} \
665
\
666
data = FIELD_DP32(data, VDATA, VM, a->vm); \
667
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
668
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
669
gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc); \
670
mark_vs_dirty(s); \
671
- gen_set_label(over); \
672
return true; \
673
} \
674
return false; \
675
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
676
TCGv_ptr rd_v, rs2_v; \
677
TCGv_i32 uimm_v, desc, egs; \
678
uint32_t data = 0; \
679
- TCGLabel *over = gen_new_label(); \
680
\
681
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
682
/* save opcode for unwinding in case we throw an exception */ \
683
decode_save_opc(s); \
684
egs = tcg_constant_i32(EGS); \
685
gen_helper_egs_check(egs, tcg_env); \
686
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
687
} \
688
\
689
data = FIELD_DP32(data, VDATA, VM, a->vm); \
690
@@ -XXX,XX +XXX,XX @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
691
tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2)); \
692
gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc); \
693
mark_vs_dirty(s); \
694
- gen_set_label(over); \
695
return true; \
696
} \
697
return false; \
698
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
699
{ \
700
if (CHECK(s, a)) { \
701
uint32_t data = 0; \
702
- TCGLabel *over = gen_new_label(); \
703
TCGv_i32 egs; \
704
\
705
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
706
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
707
decode_save_opc(s); \
708
egs = tcg_constant_i32(EGS); \
709
gen_helper_egs_check(egs, tcg_env); \
710
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
711
} \
712
\
713
data = FIELD_DP32(data, VDATA, VM, a->vm); \
714
@@ -XXX,XX +XXX,XX @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
715
data, gen_helper_##NAME); \
716
\
717
mark_vs_dirty(s); \
718
- gen_set_label(over); \
719
return true; \
720
} \
721
return false; \
722
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
723
{
724
if (vsha_check(s, a)) {
725
uint32_t data = 0;
726
- TCGLabel *over = gen_new_label();
727
TCGv_i32 egs;
728
729
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
730
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
731
decode_save_opc(s);
732
egs = tcg_constant_i32(ZVKNH_EGS);
733
gen_helper_egs_check(egs, tcg_env);
734
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
735
}
736
737
data = FIELD_DP32(data, VDATA, VM, a->vm);
738
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
739
gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
740
741
mark_vs_dirty(s);
742
- gen_set_label(over);
743
return true;
744
}
745
return false;
746
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
747
{
748
if (vsha_check(s, a)) {
749
uint32_t data = 0;
750
- TCGLabel *over = gen_new_label();
751
TCGv_i32 egs;
752
753
if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
754
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
755
decode_save_opc(s);
756
egs = tcg_constant_i32(ZVKNH_EGS);
757
gen_helper_egs_check(egs, tcg_env);
758
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
759
}
760
761
data = FIELD_DP32(data, VDATA, VM, a->vm);
762
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
763
gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
764
765
mark_vs_dirty(s);
766
- gen_set_label(over);
767
return true;
768
}
769
return false;
770
--
82
--
771
2.44.0
83
2.45.1
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The timebase-frequency of guest OS should be the same with host
3
In AIA spec, each hart (or each hart within a group) has a unique hart
4
machine. The timebase-frequency value in DTS should be got from
4
number to locate the memory pages of interrupt files in the address
5
hypervisor when using KVM acceleration.
5
space. The number of bits required to represent any hart number is equal
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
9
However, if the largest hart number among groups is a power of 2, QEMU
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
6
19
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Message-ID: <20240314061510.9800-1-yongxuan.wang@sifive.com>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
25
---
14
target/riscv/kvm/kvm_riscv.h | 1 +
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
15
hw/riscv/virt.c | 2 ++
27
1 file changed, 8 insertions(+), 1 deletion(-)
16
target/riscv/kvm/kvm-cpu.c | 9 +++++++++
17
3 files changed, 12 insertions(+)
18
28
19
diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/kvm/kvm_riscv.h
22
+++ b/target/riscv/kvm/kvm_riscv.h
23
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
24
void riscv_kvm_aplic_request(void *opaque, int irq, int level);
25
int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state);
26
void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
27
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs);
28
29
#endif
30
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/virt.c
33
+++ b/hw/riscv/virt.c
34
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
35
36
qemu_fdt_add_subnode(ms->fdt, "/cpus");
37
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
38
+ kvm_enabled() ?
39
+ kvm_riscv_get_timebase_frequency(first_cpu) :
40
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
41
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
42
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
43
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
44
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/kvm/kvm-cpu.c
31
--- a/target/riscv/kvm/kvm-cpu.c
46
+++ b/target/riscv/kvm/kvm-cpu.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
47
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
48
env->kvm_timer_dirty = false;
34
}
49
}
35
}
50
36
51
+uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs)
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
52
+{
53
+ uint64_t reg;
54
+
38
+
55
+ KVM_RISCV_GET_TIMER(cs, frequency, reg);
39
+ if (max_hart_per_socket > 1) {
40
+ max_hart_per_socket--;
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
42
+ } else {
43
+ hart_bits = 0;
44
+ }
56
+
45
+
57
+ return reg;
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
58
+}
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
59
+
48
&hart_bits, true, NULL);
60
static int kvm_riscv_get_regs_vector(CPUState *cs)
61
{
62
RISCVCPU *cpu = RISCV_CPU(cs);
63
--
49
--
64
2.44.0
50
2.45.1
65
66
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Change the for loops in ldst helpers to do a single increment in the
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
4
counter, and assign it env->vstart, to avoid re-reading from vstart
4
in bytes, when in this context we want 'reg_width' as the length in
5
every time.
5
bits.
6
6
7
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
9
beforehand.
10
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
12
clarity about what the variable represents. 'bitsize' is also used in
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Cc: Alex Bennée <alex.bennee@linaro.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
8
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Message-ID: <20240314175704.478276-11-dbarboza@ventanamicro.com>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
28
---
14
target/riscv/vector_helper.c | 6 +++---
29
target/riscv/gdbstub.c | 6 +++---
15
1 file changed, 3 insertions(+), 3 deletions(-)
30
1 file changed, 3 insertions(+), 3 deletions(-)
16
31
17
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/vector_helper.c
34
--- a/target/riscv/gdbstub.c
20
+++ b/target/riscv/vector_helper.c
35
+++ b/target/riscv/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
22
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
23
VSTART_CHECK_EARLY_EXIT(env);
38
{
24
39
RISCVCPU *cpu = RISCV_CPU(cs);
25
- for (i = env->vstart; i < env->vl; i++, env->vstart++) {
40
- int reg_width = cpu->cfg.vlenb;
26
+ for (i = env->vstart; i < env->vl; env->vstart = ++i) {
41
+ int bitsize = cpu->cfg.vlenb << 3;
27
k = 0;
42
GDBFeatureBuilder builder;
28
while (k < nf) {
43
int i;
29
if (!vm && !vext_elem_mask(v0, i)) {
44
30
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
31
VSTART_CHECK_EARLY_EXIT(env);
46
32
47
/* First define types and totals in a whole VL */
33
/* load bytes from guest memory */
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
34
- for (i = env->vstart; i < evl; i++, env->vstart++) {
49
- int count = reg_width / vec_lanes[i].size;
35
+ for (i = env->vstart; i < evl; env->vstart = ++i) {
50
+ int count = bitsize / vec_lanes[i].size;
36
k = 0;
51
gdb_feature_builder_append_tag(
37
while (k < nf) {
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
38
target_ulong addr = base + ((i * nf + k) << log2_esz);
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
39
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
40
VSTART_CHECK_EARLY_EXIT(env);
55
/* Define vector registers */
41
56
for (i = 0; i < 32; i++) {
42
/* load bytes from guest memory */
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
43
- for (i = env->vstart; i < env->vl; i++, env->vstart++) {
58
- reg_width, i, "riscv_vector", "vector");
44
+ for (i = env->vstart; i < env->vl; env->vstart = ++i) {
59
+ bitsize, i, "riscv_vector", "vector");
45
k = 0;
60
}
46
while (k < nf) {
61
47
if (!vm && !vext_elem_mask(v0, i)) {
62
gdb_feature_builder_end(&builder);
48
--
63
--
49
2.44.0
64
2.45.1
65
66
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair23@gmail.com>
1
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
CSRs are part of the disassembly.
6
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Fixes: ea10325917 ("RISC-V Disassembler")
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
16
1 file changed, 64 insertions(+), 1 deletion(-)
17
18
diff --git a/disas/riscv.c b/disas/riscv.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
21
+++ b/disas/riscv.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
23
case 0x0383: return "mibound";
24
case 0x0384: return "mdbase";
25
case 0x0385: return "mdbound";
26
- case 0x03a0: return "pmpcfg3";
27
+ case 0x03a0: return "pmpcfg0";
28
+ case 0x03a1: return "pmpcfg1";
29
+ case 0x03a2: return "pmpcfg2";
30
+ case 0x03a3: return "pmpcfg3";
31
+ case 0x03a4: return "pmpcfg4";
32
+ case 0x03a5: return "pmpcfg5";
33
+ case 0x03a6: return "pmpcfg6";
34
+ case 0x03a7: return "pmpcfg7";
35
+ case 0x03a8: return "pmpcfg8";
36
+ case 0x03a9: return "pmpcfg9";
37
+ case 0x03aa: return "pmpcfg10";
38
+ case 0x03ab: return "pmpcfg11";
39
+ case 0x03ac: return "pmpcfg12";
40
+ case 0x03ad: return "pmpcfg13";
41
+ case 0x03ae: return "pmpcfg14";
42
+ case 0x03af: return "pmpcfg15";
43
case 0x03b0: return "pmpaddr0";
44
case 0x03b1: return "pmpaddr1";
45
case 0x03b2: return "pmpaddr2";
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
47
case 0x03bd: return "pmpaddr13";
48
case 0x03be: return "pmpaddr14";
49
case 0x03bf: return "pmpaddr15";
50
+ case 0x03c0: return "pmpaddr16";
51
+ case 0x03c1: return "pmpaddr17";
52
+ case 0x03c2: return "pmpaddr18";
53
+ case 0x03c3: return "pmpaddr19";
54
+ case 0x03c4: return "pmpaddr20";
55
+ case 0x03c5: return "pmpaddr21";
56
+ case 0x03c6: return "pmpaddr22";
57
+ case 0x03c7: return "pmpaddr23";
58
+ case 0x03c8: return "pmpaddr24";
59
+ case 0x03c9: return "pmpaddr25";
60
+ case 0x03ca: return "pmpaddr26";
61
+ case 0x03cb: return "pmpaddr27";
62
+ case 0x03cc: return "pmpaddr28";
63
+ case 0x03cd: return "pmpaddr29";
64
+ case 0x03ce: return "pmpaddr30";
65
+ case 0x03cf: return "pmpaddr31";
66
+ case 0x03d0: return "pmpaddr32";
67
+ case 0x03d1: return "pmpaddr33";
68
+ case 0x03d2: return "pmpaddr34";
69
+ case 0x03d3: return "pmpaddr35";
70
+ case 0x03d4: return "pmpaddr36";
71
+ case 0x03d5: return "pmpaddr37";
72
+ case 0x03d6: return "pmpaddr38";
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
101
--
102
2.45.1
diff view generated by jsdifflib
New patch
1
From: Yu-Ming Chang <yumin686@andestech.com>
1
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
holding a zero value other than x0, the instruction will still attempt to write
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
9
a register holding a zero value, an illegal instruction exception should be
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/cpu.h | 4 ++++
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
19
target/riscv/op_helper.c | 6 ++---
20
3 files changed, 53 insertions(+), 8 deletions(-)
21
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
27
void riscv_cpu_update_mask(CPURISCVState *env);
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
29
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
31
+ target_ulong *ret_value);
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
33
target_ulong *ret_value,
34
target_ulong new_value, target_ulong write_mask);
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
36
target_ulong new_value,
37
target_ulong write_mask);
38
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
40
+ Int128 *ret_value);
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
42
Int128 *ret_value,
43
Int128 new_value, Int128 write_mask);
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
54
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
56
bool read_only = get_field(csrno, 0xC00) == 3;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
58
}
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
68
}
69
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
72
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
74
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
76
+ }
77
+
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
79
+}
80
+
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
82
target_ulong *ret_value,
83
target_ulong new_value, target_ulong write_mask)
84
{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
87
if (ret != RISCV_EXCP_NONE) {
88
return ret;
89
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
91
return RISCV_EXCP_NONE;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
96
+{
97
+ RISCVException ret;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
103
+
104
+ if (csr_ops[csrno].read128) {
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
106
+ int128_zero(), int128_zero());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
124
+}
125
+
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
127
Int128 *ret_value,
128
Int128 new_value, Int128 write_mask)
129
{
130
RISCVException ret;
131
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
133
+ ret = riscv_csrrw_check(env, csrno, true);
134
if (ret != RISCV_EXCP_NONE) {
135
return ret;
136
}
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/riscv/op_helper.c
140
+++ b/target/riscv/op_helper.c
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
142
}
143
144
target_ulong val = 0;
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
161
--
162
2.45.1
diff view generated by jsdifflib