1 | The following changes since commit fdd0df5340a8ebc8de88078387ebc85c5af7b40f: | 1 | The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946: |
---|---|---|---|
2 | 2 | ||
3 | Merge tag 'pull-ppc-20230610' of https://gitlab.com/danielhb/qemu into staging (2023-06-10 07:25:00 -0700) | 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-20230614 | 7 | https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528 |
8 | 8 | ||
9 | for you to fetch changes up to 860029321d9ebdff47e89561de61e9441fead70a: | 9 | for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393: |
10 | 10 | ||
11 | hw/intc: If mmsiaddrcfgh.L == 1, smsiaddrcfg and smsiaddrcfgh are read-only. (2023-06-14 10:04:30 +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 | Second RISC-V PR for 8.1 | 14 | RISC-V PR for 9.1 |
15 | 15 | ||
16 | * Skip Vector set tail when vta is zero | 16 | * APLICs add child earlier than realize |
17 | * Move zc* out of the experimental properties | 17 | * Fix exposure of Zkr |
18 | * Mask the implicitly enabled extensions in isa_string based on priv version | 18 | * Raise exceptions on wrs.nto |
19 | * Rework CPU extension validation and validate MISA changes | 19 | * Implement SBI debug console (DBCN) calls for KVM |
20 | * Fixup PMP TLB cacheing errors | 20 | * Support 64-bit addresses for initrd |
21 | * Writing to pmpaddr and MML/MMWP correctly triggers TLB flushes | 21 | * Change RISCV_EXCP_SEMIHOST exception number to 63 |
22 | * Fixup PMP bypass checks | 22 | * Tolerate KVM disable ext errors |
23 | * Deny access if access is partially inside a PMP entry | 23 | * Set tval in breakpoints |
24 | * Correct OpenTitanState parent type/size | 24 | * Add support for Zve32x extension |
25 | * Fix QEMU crash when NUMA nodes exceed available CPUs | 25 | * Add support for Zve64x extension |
26 | * Fix pointer mask transformation for vector address | 26 | * Relax vector register check in RISCV gdbstub |
27 | * Updates and improvements for Smstateen | 27 | * Fix the element agnostic Vector function problem |
28 | * Support disas for Zcm* extensions | 28 | * Fix Zvkb extension config |
29 | * Support disas for Z*inx extensions | 29 | * Implement dynamic establishment of custom decoder |
30 | * Remove unused decomp_rv32/64 value for vector instructions | 30 | * Add th.sxstatus CSR emulation |
31 | * Enable PC-relative translation | 31 | * Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions |
32 | * Assume M-mode FW in pflash0 only when "-bios none" | 32 | * Check single width operator for vector fp widen instructions |
33 | * Support using pflash via -blockdev option | 33 | * Check single width operator for vfncvt.rod.f.f.w |
34 | * Add vector registers to log | 34 | * Remove redudant SEW checking for vector fp narrow/widen instructions |
35 | * Clean up reference of Vector MTYPE | 35 | * Prioritize pmp errors in raise_mmu_exception() |
36 | * Remove the check for extra Vector tail elements | 36 | * Do not set mtval2 for non guest-page faults |
37 | * Smepmp: Return error when access permission not allowed in PMP | 37 | * Remove experimental prefix from "B" extension |
38 | * Fixes for smsiaddrcfg and smsiaddrcfgh in AIA | 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 | ||
39 | 43 | ||
40 | ---------------------------------------------------------------- | 44 | ---------------------------------------------------------------- |
41 | Daniel Henrique Barboza (10): | 45 | Alexei Filippov (1): |
42 | target/riscv/vector_helper.c: skip set tail when vta is zero | 46 | target/riscv: do not set mtval2 for non guest-page faults |
43 | target/riscv/cpu.c: add riscv_cpu_validate_v() | ||
44 | target/riscv/cpu.c: remove set_vext_version() | ||
45 | target/riscv/cpu.c: remove set_priv_version() | ||
46 | target/riscv: add PRIV_VERSION_LATEST | ||
47 | target/riscv/cpu.c: add priv_spec validate/disable_exts helpers | ||
48 | target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() | ||
49 | target/riscv/cpu.c: validate extensions before riscv_timer_init() | ||
50 | target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() | ||
51 | target/riscv: rework write_misa() | ||
52 | 47 | ||
53 | Himanshu Chauhan (1): | 48 | Alistair Francis (2): |
54 | target/riscv: Smepmp: Return error when access permission not allowed in PMP | 49 | target/riscv: rvzicbo: Fixup CBO extension register calculation |
50 | disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs | ||
55 | 51 | ||
56 | Ivan Klokov (1): | 52 | Andrew Jones (2): |
57 | util/log: Add vector registers to log | 53 | target/riscv/kvm: Fix exposure of Zkr |
54 | target/riscv: Raise exceptions on wrs.nto | ||
58 | 55 | ||
59 | Mayuresh Chitale (3): | 56 | Cheng Yang (1): |
60 | target/riscv: smstateen check for fcsr | 57 | hw/riscv/boot.c: Support 64-bit address for initrd |
61 | target/riscv: Reuse tb->flags.FS | ||
62 | target/riscv: smstateen knobs | ||
63 | 58 | ||
64 | Philippe Mathieu-Daudé (5): | 59 | Christoph Müllner (1): |
65 | hw/riscv/opentitan: Rename machine_[class]_init() functions | 60 | riscv: thead: Add th.sxstatus CSR emulation |
66 | hw/riscv/opentitan: Declare QOM types using DEFINE_TYPES() macro | ||
67 | hw/riscv/opentitan: Add TYPE_OPENTITAN_MACHINE definition | ||
68 | hw/riscv/opentitan: Explicit machine type definition | ||
69 | hw/riscv/opentitan: Correct OpenTitanState parent type/size | ||
70 | 61 | ||
71 | Sunil V L (3): | 62 | Clément Léger (1): |
72 | hw/riscv: virt: Assume M-mode FW in pflash0 only when "-bios none" | 63 | target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63 |
73 | riscv/virt: Support using pflash via -blockdev option | ||
74 | docs/system: riscv: Add pflash usage details | ||
75 | 64 | ||
76 | Tommy Wu (1): | 65 | Daniel Henrique Barboza (6): |
77 | hw/intc: If mmsiaddrcfgh.L == 1, smsiaddrcfg and smsiaddrcfgh are read-only. | 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() | ||
78 | 72 | ||
79 | Weiwei Li (33): | 73 | Huang Tao (2): |
80 | target/riscv: Move zc* out of the experimental properties | 74 | target/riscv: Fix the element agnostic function problem |
81 | target/riscv: Mask the implicitly enabled extensions in isa_string based on priv version | 75 | target/riscv: Implement dynamic establishment of custom decoder |
82 | target/riscv: Update check for Zca/Zcf/Zcd | ||
83 | target/riscv: Update pmp_get_tlb_size() | ||
84 | target/riscv: Move pmp_get_tlb_size apart from get_physical_address_pmp | ||
85 | target/riscv: Make the short cut really work in pmp_hart_has_privs | ||
86 | target/riscv: Change the return type of pmp_hart_has_privs() to bool | ||
87 | target/riscv: Make RLB/MML/MMWP bits writable only when Smepmp is enabled | ||
88 | target/riscv: Remove unused paramters in pmp_hart_has_privs_default() | ||
89 | target/riscv: Flush TLB when MMWP or MML bits are changed | ||
90 | target/riscv: Update the next rule addr in pmpaddr_csr_write() | ||
91 | target/riscv: Flush TLB when pmpaddr is updated | ||
92 | target/riscv: Flush TLB only when pmpcfg/pmpaddr really changes | ||
93 | target/riscv: Separate pmp_update_rule() in pmpcfg_csr_write | ||
94 | target/riscv: Deny access if access is partially inside the PMP entry | ||
95 | target/riscv: Fix pointer mask transformation for vector address | ||
96 | target/riscv: Update cur_pmmask/base when xl changes | ||
97 | disas: Change type of disassemble_info.target_info to pointer | ||
98 | target/riscv: Split RISCVCPUConfig declarations from cpu.h into cpu_cfg.h | ||
99 | target/riscv: Pass RISCVCPUConfig as target_info to disassemble_info | ||
100 | disas/riscv.c: Support disas for Zcm* extensions | ||
101 | disas/riscv.c: Support disas for Z*inx extensions | ||
102 | disas/riscv.c: Remove unused decomp_rv32/64 value for vector instructions | ||
103 | disas/riscv.c: Fix lines with over 80 characters | ||
104 | disas/riscv.c: Remove redundant parentheses | ||
105 | target/riscv: Fix target address to update badaddr | ||
106 | target/riscv: Introduce cur_insn_len into DisasContext | ||
107 | target/riscv: Change gen_goto_tb to work on displacements | ||
108 | target/riscv: Change gen_set_pc_imm to gen_update_pc | ||
109 | target/riscv: Use true diff for gen_pc_plus_diff | ||
110 | target/riscv: Enable PC-relative translation | ||
111 | target/riscv: Remove pc_succ_insn from DisasContext | ||
112 | target/riscv: Fix initialized value for cur_pmmask | ||
113 | 76 | ||
114 | Xiao Wang (2): | 77 | Jason Chien (3): |
115 | target/riscv/vector_helper.c: clean up reference of MTYPE | 78 | target/riscv: Add support for Zve32x extension |
116 | target/riscv/vector_helper.c: Remove the check for extra tail elements | 79 | target/riscv: Add support for Zve64x extension |
80 | target/riscv: Relax vector register check in RISCV gdbstub | ||
117 | 81 | ||
118 | Yin Wang (1): | 82 | Max Chou (4): |
119 | hw/riscv: qemu crash when NUMA nodes exceed available CPUs | 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 | ||
120 | 87 | ||
121 | docs/system/riscv/virt.rst | 31 + | 88 | Rob Bradford (1): |
122 | include/disas/dis-asm.h | 2 +- | 89 | target/riscv: Remove experimental prefix from "B" extension |
123 | include/hw/core/cpu.h | 2 + | ||
124 | include/hw/riscv/opentitan.h | 6 +- | ||
125 | include/qemu/log.h | 1 + | ||
126 | target/riscv/cpu.h | 117 +-- | ||
127 | target/riscv/cpu_cfg.h | 136 +++ | ||
128 | target/riscv/pmp.h | 11 +- | ||
129 | accel/tcg/cpu-exec.c | 3 + | ||
130 | disas/riscv.c | 1194 +++++++++++++----------- | ||
131 | hw/intc/riscv_aplic.c | 4 +- | ||
132 | hw/riscv/numa.c | 6 + | ||
133 | hw/riscv/opentitan.c | 38 +- | ||
134 | hw/riscv/virt.c | 59 +- | ||
135 | target/riscv/cpu.c | 384 +++++--- | ||
136 | target/riscv/cpu_helper.c | 37 +- | ||
137 | target/riscv/csr.c | 75 +- | ||
138 | target/riscv/pmp.c | 205 ++-- | ||
139 | target/riscv/translate.c | 99 +- | ||
140 | target/riscv/vector_helper.c | 33 +- | ||
141 | util/log.c | 2 + | ||
142 | target/riscv/insn_trans/trans_privileged.c.inc | 2 +- | ||
143 | target/riscv/insn_trans/trans_rvd.c.inc | 12 +- | ||
144 | target/riscv/insn_trans/trans_rvf.c.inc | 21 +- | ||
145 | target/riscv/insn_trans/trans_rvi.c.inc | 46 +- | ||
146 | target/riscv/insn_trans/trans_rvv.c.inc | 4 +- | ||
147 | target/riscv/insn_trans/trans_rvzawrs.c.inc | 2 +- | ||
148 | target/riscv/insn_trans/trans_rvzce.c.inc | 10 +- | ||
149 | target/riscv/insn_trans/trans_xthead.c.inc | 2 +- | ||
150 | 29 files changed, 1442 insertions(+), 1102 deletions(-) | ||
151 | create mode 100644 target/riscv/cpu_cfg.h | ||
152 | 90 | ||
91 | Yangyu Chen (1): | ||
92 | target/riscv/cpu.c: fix Zvkb extension config | ||
93 | |||
94 | Yong-Xuan Wang (1): | ||
95 | target/riscv/kvm.c: Fix the hart bit setting of AIA | ||
96 | |||
97 | Yu-Ming Chang (1): | ||
98 | target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR | ||
99 | |||
100 | yang.zhang (1): | ||
101 | hw/intc/riscv_aplic: APLICs should add child earlier than realize | ||
102 | |||
103 | MAINTAINERS | 1 + | ||
104 | target/riscv/cpu.h | 11 ++ | ||
105 | target/riscv/cpu_bits.h | 2 +- | ||
106 | target/riscv/cpu_cfg.h | 2 + | ||
107 | target/riscv/helper.h | 1 + | ||
108 | target/riscv/sbi_ecall_interface.h | 17 +++ | ||
109 | target/riscv/tcg/tcg-cpu.h | 15 +++ | ||
110 | disas/riscv.c | 65 +++++++++- | ||
111 | hw/intc/riscv_aplic.c | 8 +- | ||
112 | hw/riscv/boot.c | 4 +- | ||
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 |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | The function is a no-op if 'vta' is zero but we're still doing a lot of | ||
4 | stuff in this function regardless. vext_set_elems_1s() will ignore every | ||
5 | single time (since vta is zero) and we just wasted time. | ||
6 | |||
7 | Skip it altogether in this case. Aside from the code simplification | ||
8 | there's a noticeable emulation performance gain by doing it. For a | ||
9 | regular C binary that does a vectors operation like this: | ||
10 | |||
11 | ======= | ||
12 | #define SZ 10000000 | ||
13 | |||
14 | int main () | ||
15 | { | ||
16 | int *a = malloc (SZ * sizeof (int)); | ||
17 | int *b = malloc (SZ * sizeof (int)); | ||
18 | int *c = malloc (SZ * sizeof (int)); | ||
19 | |||
20 | for (int i = 0; i < SZ; i++) | ||
21 | c[i] = a[i] + b[i]; | ||
22 | return c[SZ - 1]; | ||
23 | } | ||
24 | ======= | ||
25 | |||
26 | Emulating it with qemu-riscv64 and RVV takes ~0.3 sec: | ||
27 | |||
28 | $ time ~/work/qemu/build/qemu-riscv64 \ | ||
29 | -cpu rv64,debug=false,vext_spec=v1.0,v=true,vlen=128 ./foo.out | ||
30 | |||
31 | real 0m0.303s | ||
32 | user 0m0.281s | ||
33 | sys 0m0.023s | ||
34 | |||
35 | With this skip we take ~0.275 sec: | ||
36 | |||
37 | $ time ~/work/qemu/build/qemu-riscv64 \ | ||
38 | -cpu rv64,debug=false,vext_spec=v1.0,v=true,vlen=128 ./foo.out | ||
39 | |||
40 | real 0m0.274s | ||
41 | user 0m0.252s | ||
42 | sys 0m0.019s | ||
43 | |||
44 | This performance gain adds up fast when executing heavy benchmarks like | ||
45 | SPEC. | ||
46 | |||
47 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
48 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
49 | Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com> | ||
50 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
51 | Message-Id: <20230427205708.246679-2-dbarboza@ventanamicro.com> | ||
52 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
53 | --- | ||
54 | target/riscv/vector_helper.c | 11 ++++++++--- | ||
55 | 1 file changed, 8 insertions(+), 3 deletions(-) | ||
56 | |||
57 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/target/riscv/vector_helper.c | ||
60 | +++ b/target/riscv/vector_helper.c | ||
61 | @@ -XXX,XX +XXX,XX @@ static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl, | ||
62 | void *vd, uint32_t desc, uint32_t nf, | ||
63 | uint32_t esz, uint32_t max_elems) | ||
64 | { | ||
65 | - uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
66 | - uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3; | ||
67 | + uint32_t total_elems, vlenb, registers_used; | ||
68 | uint32_t vta = vext_vta(desc); | ||
69 | - uint32_t registers_used; | ||
70 | int k; | ||
71 | |||
72 | + if (vta == 0) { | ||
73 | + return; | ||
74 | + } | ||
75 | + | ||
76 | + total_elems = vext_get_total_elems(env, desc, esz); | ||
77 | + vlenb = riscv_cpu_cfg(env)->vlen >> 3; | ||
78 | + | ||
79 | for (k = 0; k < nf; ++k) { | ||
80 | vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz, | ||
81 | (k * max_elems + max_elems) * esz); | ||
82 | -- | ||
83 | 2.40.1 | diff view generated by jsdifflib |
1 | From: Tommy Wu <tommy.wu@sifive.com> | 1 | From: "yang.zhang" <yang.zhang@hexintek.com> |
---|---|---|---|
2 | 2 | ||
3 | According to the `The RISC-V Advanced Interrupt Architecture` | 3 | Since only root APLICs can have hw IRQ lines, aplic->parent should |
4 | document, if register `mmsiaddrcfgh` of the domain has bit L set | 4 | be initialized first. |
5 | to one, then `smsiaddrcfg` and `smsiaddrcfgh` are locked as | ||
6 | read-only alongside `mmsiaddrcfg` and `mmsiaddrcfgh`. | ||
7 | 5 | ||
8 | Signed-off-by: Tommy Wu <tommy.wu@sifive.com> | 6 | Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation") |
9 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | 7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Signed-off-by: yang.zhang <yang.zhang@hexintek.com> |
11 | Reviewed-by: Anup Patel <anup@brainfault.org> | 9 | Cc: qemu-stable <qemu-stable@nongnu.org> |
12 | Message-Id: <20230609055936.3925438-1-tommy.wu@sifive.com> | 10 | Message-ID: <20240409014445.278-1-gaoshanliukou@163.com> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 12 | --- |
15 | hw/intc/riscv_aplic.c | 4 ++-- | 13 | hw/intc/riscv_aplic.c | 8 ++++---- |
16 | 1 file changed, 2 insertions(+), 2 deletions(-) | 14 | 1 file changed, 4 insertions(+), 4 deletions(-) |
17 | 15 | ||
18 | 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 |
19 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/hw/intc/riscv_aplic.c | 18 | --- a/hw/intc/riscv_aplic.c |
21 | +++ b/hw/intc/riscv_aplic.c | 19 | +++ b/hw/intc/riscv_aplic.c |
22 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_write(void *opaque, hwaddr addr, uint64_t value, | 20 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, |
23 | * domains). | 21 | qdev_prop_set_bit(dev, "msimode", msimode); |
24 | */ | 22 | qdev_prop_set_bit(dev, "mmode", mmode); |
25 | if (aplic->num_children && | 23 | |
26 | - !(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) { | 24 | + if (parent) { |
27 | + !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) { | 25 | + riscv_aplic_add_child(parent, dev); |
28 | aplic->smsicfgaddr = value; | 26 | + } |
29 | } | 27 | + |
30 | } else if (aplic->mmode && aplic->msimode && | 28 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
31 | (addr == APLIC_SMSICFGADDRH)) { | 29 | |
32 | if (aplic->num_children && | 30 | if (!is_kvm_aia(msimode)) { |
33 | - !(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) { | 31 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); |
34 | + !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) { | 32 | } |
35 | aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK; | 33 | |
36 | } | 34 | - if (parent) { |
37 | } else if ((APLIC_SETIP_BASE <= addr) && | 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); | ||
38 | -- | 41 | -- |
39 | 2.40.1 | 42 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Andrew Jones <ajones@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | All these generic CPUs are using the latest priv available, at this | 3 | The Zkr extension may only be exposed to KVM guests if the VMM |
4 | moment PRIV_VERSION_1_12_0: | 4 | implements the SEED CSR. Use the same implementation as TCG. |
5 | 5 | ||
6 | - riscv_any_cpu_init() | 6 | Without this patch, running with a KVM which does not forward the |
7 | - rv32_base_cpu_init() | 7 | SEED CSR access to QEMU will result in an ILL exception being |
8 | - rv64_base_cpu_init() | 8 | injected into the guest (this results in Linux guests crashing on |
9 | - rv128_base_cpu_init() | 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. | ||
10 | 11 | ||
11 | Create a new PRIV_VERSION_LATEST enum and use it in those cases. I'll | 12 | Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8") |
12 | make it easier to update everything at once when a new priv version is | 13 | Signed-off-by: Andrew Jones <ajones@ventanamicro.com> |
13 | available. | 14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
14 | 15 | Cc: qemu-stable <qemu-stable@nongnu.org> | |
15 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 16 | Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com> |
16 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
17 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
18 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | Message-Id: <20230517135714.211809-5-dbarboza@ventanamicro.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
22 | --- | 18 | --- |
23 | target/riscv/cpu.h | 2 ++ | 19 | target/riscv/cpu.h | 3 +++ |
24 | target/riscv/cpu.c | 8 ++++---- | 20 | target/riscv/csr.c | 18 ++++++++++++++---- |
25 | 2 files changed, 6 insertions(+), 4 deletions(-) | 21 | target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++ |
22 | 3 files changed, 42 insertions(+), 4 deletions(-) | ||
26 | 23 | ||
27 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 24 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
28 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/target/riscv/cpu.h | 26 | --- a/target/riscv/cpu.h |
30 | +++ b/target/riscv/cpu.h | 27 | +++ b/target/riscv/cpu.h |
31 | @@ -XXX,XX +XXX,XX @@ enum { | 28 | @@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); |
32 | PRIV_VERSION_1_10_0 = 0, | 29 | |
33 | PRIV_VERSION_1_11_0, | 30 | void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); |
34 | PRIV_VERSION_1_12_0, | 31 | |
32 | +target_ulong riscv_new_csr_seed(target_ulong new_value, | ||
33 | + target_ulong write_mask); | ||
35 | + | 34 | + |
36 | + PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0, | 35 | uint8_t satp_mode_max_from_map(uint32_t map); |
37 | }; | 36 | const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit); |
38 | 37 | ||
39 | #define VEXT_VERSION_1_00_0 0x00010000 | 38 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
40 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/target/riscv/cpu.c | 40 | --- a/target/riscv/csr.c |
43 | +++ b/target/riscv/cpu.c | 41 | +++ b/target/riscv/csr.c |
44 | @@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj) | 42 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, |
45 | VM_1_10_SV32 : VM_1_10_SV57); | ||
46 | #endif | 43 | #endif |
47 | 44 | ||
48 | - env->priv_ver = PRIV_VERSION_1_12_0; | 45 | /* Crypto Extension */ |
49 | + env->priv_ver = PRIV_VERSION_LATEST; | 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; | ||
50 | } | 80 | } |
51 | 81 | ||
52 | #if defined(TARGET_RISCV64) | 82 | +static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run) |
53 | @@ -XXX,XX +XXX,XX @@ static void rv64_base_cpu_init(Object *obj) | 83 | +{ |
54 | set_misa(env, MXL_RV64, 0); | 84 | + target_ulong csr_num = run->riscv_csr.csr_num; |
55 | riscv_cpu_add_user_properties(obj); | 85 | + target_ulong new_value = run->riscv_csr.new_value; |
56 | /* Set latest version of privileged specification */ | 86 | + target_ulong write_mask = run->riscv_csr.write_mask; |
57 | - env->priv_ver = PRIV_VERSION_1_12_0; | 87 | + int ret = 0; |
58 | + env->priv_ver = PRIV_VERSION_LATEST; | 88 | + |
59 | #ifndef CONFIG_USER_ONLY | 89 | + switch (csr_num) { |
60 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); | 90 | + case CSR_SEED: |
61 | #endif | 91 | + run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask); |
62 | @@ -XXX,XX +XXX,XX @@ static void rv128_base_cpu_init(Object *obj) | 92 | + break; |
63 | set_misa(env, MXL_RV128, 0); | 93 | + default: |
64 | riscv_cpu_add_user_properties(obj); | 94 | + qemu_log_mask(LOG_UNIMP, |
65 | /* Set latest version of privileged specification */ | 95 | + "%s: un-handled CSR EXIT for CSR %lx\n", |
66 | - env->priv_ver = PRIV_VERSION_1_12_0; | 96 | + __func__, csr_num); |
67 | + env->priv_ver = PRIV_VERSION_LATEST; | 97 | + ret = -1; |
68 | #ifndef CONFIG_USER_ONLY | 98 | + break; |
69 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); | 99 | + } |
70 | #endif | 100 | + |
71 | @@ -XXX,XX +XXX,XX @@ static void rv32_base_cpu_init(Object *obj) | 101 | + return ret; |
72 | set_misa(env, MXL_RV32, 0); | 102 | +} |
73 | riscv_cpu_add_user_properties(obj); | 103 | + |
74 | /* Set latest version of privileged specification */ | 104 | int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) |
75 | - env->priv_ver = PRIV_VERSION_1_12_0; | 105 | { |
76 | + env->priv_ver = PRIV_VERSION_LATEST; | 106 | int ret = 0; |
77 | #ifndef CONFIG_USER_ONLY | 107 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) |
78 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); | 108 | case KVM_EXIT_RISCV_SBI: |
79 | #endif | 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); | ||
80 | -- | 117 | -- |
81 | 2.40.1 | 118 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | From: Andrew Jones <ajones@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Follow QOM style which declares FOO_init() as instance | 3 | Implementing wrs.nto to always just return is consistent with the |
4 | initializer and FOO_class_init() as class initializer: | 4 | specification, as the instruction is permitted to terminate the |
5 | rename the OpenTitan machine class/instance init() | 5 | stall for any reason, but it's not useful for virtualization, where |
6 | accordingly. | 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. | ||
7 | 13 | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 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> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 18 | Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com> |
11 | Message-Id: <20230520054510.68822-2-philmd@linaro.org> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 20 | --- |
14 | hw/riscv/opentitan.c | 8 ++++---- | 21 | target/riscv/helper.h | 1 + |
15 | 1 file changed, 4 insertions(+), 4 deletions(-) | 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(-) | ||
16 | 25 | ||
17 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | 26 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h |
18 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/riscv/opentitan.c | 28 | --- a/target/riscv/helper.h |
20 | +++ b/hw/riscv/opentitan.c | 29 | +++ b/target/riscv/helper.h |
21 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = { | 30 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl) |
22 | [IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 }, | 31 | DEF_HELPER_1(sret, tl, env) |
23 | }; | 32 | DEF_HELPER_1(mret, tl, env) |
24 | 33 | DEF_HELPER_1(wfi, void, env) | |
25 | -static void opentitan_board_init(MachineState *machine) | 34 | +DEF_HELPER_1(wrs_nto, void, env) |
26 | +static void opentitan_machine_init(MachineState *machine) | 35 | DEF_HELPER_1(tlb_flush, void, env) |
27 | { | 36 | DEF_HELPER_1(tlb_flush_all, void, env) |
28 | MachineClass *mc = MACHINE_GET_CLASS(machine); | 37 | /* Native Debug */ |
29 | const MemMapEntry *memmap = ibex_memmap; | 38 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c |
30 | @@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine) | 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) | ||
31 | } | 43 | } |
32 | } | 44 | } |
33 | 45 | ||
34 | -static void opentitan_machine_init(MachineClass *mc) | 46 | +void helper_wrs_nto(CPURISCVState *env) |
35 | +static void opentitan_machine_class_init(MachineClass *mc) | 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) | ||
36 | { | 58 | { |
37 | mc->desc = "RISC-V Board compatible with OpenTitan"; | 59 | CPUState *cs = env_cpu(env); |
38 | - mc->init = opentitan_board_init; | 60 | diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc |
39 | + mc->init = opentitan_machine_init; | 61 | index XXXXXXX..XXXXXXX 100644 |
40 | mc->max_cpus = 1; | 62 | --- a/target/riscv/insn_trans/trans_rvzawrs.c.inc |
41 | mc->default_cpu_type = TYPE_RISCV_CPU_IBEX; | 63 | +++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc |
42 | mc->default_ram_id = "riscv.lowrisc.ibex.ram"; | 64 | @@ -XXX,XX +XXX,XX @@ |
43 | mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size; | 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; | ||
44 | } | 75 | } |
45 | 76 | ||
46 | -DEFINE_MACHINE("opentitan", opentitan_machine_init) | 77 | -#define GEN_TRANS_WRS(insn) \ |
47 | +DEFINE_MACHINE("opentitan", opentitan_machine_class_init) | 78 | -static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \ |
48 | 79 | -{ \ | |
49 | static void lowrisc_ibex_soc_init(Object *obj) | 80 | - (void)a; \ |
50 | { | 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 | +} | ||
51 | -- | 105 | -- |
52 | 2.40.1 | 106 | 2.45.1 |
53 | 107 | ||
54 | 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 | We're doing env->priv_spec validation and assignment at the start of | 3 | SBI defines a Debug Console extension "DBCN" that will, in time, replace |
4 | riscv_cpu_realize(), which is fine, but then we're doing a force disable | 4 | the legacy console putchar and getchar SBI extensions. |
5 | on extensions that aren't compatible with the priv version. | 5 | |
6 | 6 | The appeal of the DBCN extension is that it allows multiple bytes to be | |
7 | This second step is being done too early. The disabled extensions might be | 7 | read/written in the SBI console in a single SBI call. |
8 | re-enabled again in riscv_cpu_validate_set_extensions() by accident. A | 8 | |
9 | better place to put this code is at the end of | 9 | As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM |
10 | riscv_cpu_validate_set_extensions() after all the validations are | 10 | module to userspace. But this will only happens if the KVM module |
11 | completed. | 11 | actually supports this SBI extension and we activate it. |
12 | 12 | ||
13 | Add a new helper, riscv_cpu_disable_priv_spec_isa_exts(), to disable the | 13 | We'll check for DBCN support during init time, checking if get-reg-list |
14 | extesions after the validation is done. While we're at it, create a | 14 | is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via |
15 | riscv_cpu_validate_priv_spec() helper to host all env->priv_spec related | 15 | kvm_set_one_reg() during kvm_arch_init_vcpu(). |
16 | validation to unclog riscv_cpu_realize a bit. | 16 | |
17 | Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for | ||
18 | SBI_EXT_DBCN, reading and writing as required. | ||
19 | |||
20 | A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V | ||
21 | host, takes around 20 seconds to boot without using DBCN. With this | ||
22 | patch we're taking around 14 seconds to boot due to the speed-up in the | ||
23 | terminal output. There's no change in boot time if the guest isn't | ||
24 | using earlycon. | ||
17 | 25 | ||
18 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 26 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
19 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 27 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
20 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 28 | Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com> |
21 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | Message-Id: <20230517135714.211809-8-dbarboza@ventanamicro.com> | ||
23 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 29 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
24 | --- | 30 | --- |
25 | target/riscv/cpu.c | 91 ++++++++++++++++++++++++++++------------------ | 31 | target/riscv/sbi_ecall_interface.h | 17 +++++ |
26 | 1 file changed, 56 insertions(+), 35 deletions(-) | 32 | target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++ |
27 | 33 | 2 files changed, 128 insertions(+) | |
28 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 34 | |
35 | diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
30 | --- a/target/riscv/cpu.c | 37 | --- a/target/riscv/sbi_ecall_interface.h |
31 | +++ b/target/riscv/cpu.c | 38 | +++ b/target/riscv/sbi_ecall_interface.h |
32 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, | 39 | @@ -XXX,XX +XXX,XX @@ |
33 | env->vext_ver = vext_version; | 40 | |
34 | } | 41 | /* clang-format off */ |
35 | 42 | ||
36 | +static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp) | 43 | +#define SBI_SUCCESS 0 |
44 | +#define SBI_ERR_FAILED -1 | ||
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) | ||
37 | +{ | 101 | +{ |
38 | + CPURISCVState *env = &cpu->env; | 102 | + struct kvm_reg_list *reg_search; |
39 | + int priv_version = -1; | 103 | + |
40 | + | 104 | + reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n, |
41 | + if (cpu->cfg.priv_spec) { | 105 | + sizeof(uint64_t), uint64_cmp); |
42 | + if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { | 106 | + |
43 | + priv_version = PRIV_VERSION_1_12_0; | 107 | + if (reg_search) { |
44 | + } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { | 108 | + kvm_sbi_dbcn.supported = true; |
45 | + priv_version = PRIV_VERSION_1_11_0; | ||
46 | + } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { | ||
47 | + priv_version = PRIV_VERSION_1_10_0; | ||
48 | + } else { | ||
49 | + error_setg(errp, | ||
50 | + "Unsupported privilege spec version '%s'", | ||
51 | + cpu->cfg.priv_spec); | ||
52 | + return; | ||
53 | + } | ||
54 | + | ||
55 | + env->priv_ver = priv_version; | ||
56 | + } | 109 | + } |
57 | +} | 110 | +} |
58 | + | 111 | + |
59 | +static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) | 112 | static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu, |
113 | struct kvm_reg_list *reglist) | ||
114 | { | ||
115 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu) | ||
116 | if (riscv_has_ext(&cpu->env, RVV)) { | ||
117 | kvm_riscv_read_vlenb(cpu, kvmcpu, reglist); | ||
118 | } | ||
119 | + | ||
120 | + kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist); | ||
121 | } | ||
122 | |||
123 | static void riscv_init_kvm_registers(Object *cpu_obj) | ||
124 | @@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs) | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | +static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs) | ||
60 | +{ | 129 | +{ |
61 | + CPURISCVState *env = &cpu->env; | 130 | + target_ulong reg = 1; |
62 | + int i; | 131 | + |
63 | + | 132 | + if (!kvm_sbi_dbcn.supported) { |
64 | + /* Force disable extensions if priv spec version does not match */ | 133 | + return 0; |
65 | + for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { | 134 | + } |
66 | + if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && | 135 | + |
67 | + (env->priv_ver < isa_edata_arr[i].min_version)) { | 136 | + return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, ®); |
68 | + isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); | 137 | +} |
69 | +#ifndef CONFIG_USER_ONLY | 138 | + |
70 | + warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx | 139 | int kvm_arch_init_vcpu(CPUState *cs) |
71 | + " because privilege spec version does not match", | 140 | { |
72 | + isa_edata_arr[i].name, env->mhartid); | 141 | int ret = 0; |
73 | +#else | 142 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) |
74 | + warn_report("disabling %s extension because " | 143 | kvm_riscv_update_cpu_misa_ext(cpu, cs); |
75 | + "privilege spec version does not match", | 144 | kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs); |
76 | + isa_edata_arr[i].name); | 145 | |
77 | +#endif | 146 | + ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs); |
78 | + } | 147 | + |
148 | return ret; | ||
149 | } | ||
150 | |||
151 | @@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) | ||
152 | return true; | ||
153 | } | ||
154 | |||
155 | +static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run) | ||
156 | +{ | ||
157 | + g_autofree uint8_t *buf = NULL; | ||
158 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
159 | + target_ulong num_bytes; | ||
160 | + uint64_t addr; | ||
161 | + unsigned char ch; | ||
162 | + int ret; | ||
163 | + | ||
164 | + switch (run->riscv_sbi.function_id) { | ||
165 | + case SBI_EXT_DBCN_CONSOLE_READ: | ||
166 | + case SBI_EXT_DBCN_CONSOLE_WRITE: | ||
167 | + num_bytes = run->riscv_sbi.args[0]; | ||
168 | + | ||
169 | + if (num_bytes == 0) { | ||
170 | + run->riscv_sbi.ret[0] = SBI_SUCCESS; | ||
171 | + run->riscv_sbi.ret[1] = 0; | ||
172 | + break; | ||
173 | + } | ||
174 | + | ||
175 | + addr = run->riscv_sbi.args[1]; | ||
176 | + | ||
177 | + /* | ||
178 | + * Handle the case where a 32 bit CPU is running in a | ||
179 | + * 64 bit addressing env. | ||
180 | + */ | ||
181 | + if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) { | ||
182 | + addr |= (uint64_t)run->riscv_sbi.args[2] << 32; | ||
183 | + } | ||
184 | + | ||
185 | + buf = g_malloc0(num_bytes); | ||
186 | + | ||
187 | + if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) { | ||
188 | + ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes); | ||
189 | + if (ret < 0) { | ||
190 | + error_report("SBI_EXT_DBCN_CONSOLE_READ: error when " | ||
191 | + "reading chardev"); | ||
192 | + exit(1); | ||
193 | + } | ||
194 | + | ||
195 | + cpu_physical_memory_write(addr, buf, ret); | ||
196 | + } else { | ||
197 | + cpu_physical_memory_read(addr, buf, num_bytes); | ||
198 | + | ||
199 | + ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes); | ||
200 | + if (ret < 0) { | ||
201 | + error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when " | ||
202 | + "writing chardev"); | ||
203 | + exit(1); | ||
204 | + } | ||
205 | + } | ||
206 | + | ||
207 | + run->riscv_sbi.ret[0] = SBI_SUCCESS; | ||
208 | + run->riscv_sbi.ret[1] = ret; | ||
209 | + break; | ||
210 | + case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: | ||
211 | + ch = run->riscv_sbi.args[0]; | ||
212 | + ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch)); | ||
213 | + | ||
214 | + if (ret < 0) { | ||
215 | + error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when " | ||
216 | + "writing chardev"); | ||
217 | + exit(1); | ||
218 | + } | ||
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; | ||
79 | + } | 225 | + } |
80 | +} | 226 | +} |
81 | + | 227 | + |
82 | /* | 228 | static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run) |
83 | * Check consistency between chosen extensions while setting | 229 | { |
84 | * cpu->cfg accordingly. | 230 | int ret = 0; |
85 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 231 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run) |
86 | cpu->cfg.ext_zksed = true; | 232 | } |
87 | cpu->cfg.ext_zksh = true; | 233 | ret = 0; |
88 | } | 234 | break; |
89 | + | 235 | + case SBI_EXT_DBCN: |
90 | + /* | 236 | + kvm_riscv_handle_sbi_dbcn(cs, run); |
91 | + * Disable isa extensions based on priv spec after we | 237 | + break; |
92 | + * validated and set everything we need. | 238 | default: |
93 | + */ | 239 | qemu_log_mask(LOG_UNIMP, |
94 | + riscv_cpu_disable_priv_spec_isa_exts(cpu); | 240 | "%s: un-handled SBI EXIT, specific reasons is %lu\n", |
95 | } | ||
96 | |||
97 | #ifndef CONFIG_USER_ONLY | ||
98 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
99 | CPURISCVState *env = &cpu->env; | ||
100 | RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); | ||
101 | CPUClass *cc = CPU_CLASS(mcc); | ||
102 | - int i, priv_version = -1; | ||
103 | Error *local_err = NULL; | ||
104 | |||
105 | cpu_exec_realizefn(cs, &local_err); | ||
106 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | - if (cpu->cfg.priv_spec) { | ||
111 | - if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { | ||
112 | - priv_version = PRIV_VERSION_1_12_0; | ||
113 | - } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { | ||
114 | - priv_version = PRIV_VERSION_1_11_0; | ||
115 | - } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { | ||
116 | - priv_version = PRIV_VERSION_1_10_0; | ||
117 | - } else { | ||
118 | - error_setg(errp, | ||
119 | - "Unsupported privilege spec version '%s'", | ||
120 | - cpu->cfg.priv_spec); | ||
121 | - return; | ||
122 | - } | ||
123 | - } | ||
124 | - | ||
125 | - if (priv_version >= PRIV_VERSION_1_10_0) { | ||
126 | - env->priv_ver = priv_version; | ||
127 | + riscv_cpu_validate_priv_spec(cpu, &local_err); | ||
128 | + if (local_err != NULL) { | ||
129 | + error_propagate(errp, local_err); | ||
130 | + return; | ||
131 | } | ||
132 | |||
133 | riscv_cpu_validate_misa_priv(env, &local_err); | ||
134 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
135 | return; | ||
136 | } | ||
137 | |||
138 | - /* Force disable extensions if priv spec version does not match */ | ||
139 | - for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { | ||
140 | - if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && | ||
141 | - (env->priv_ver < isa_edata_arr[i].min_version)) { | ||
142 | - isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); | ||
143 | -#ifndef CONFIG_USER_ONLY | ||
144 | - warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx | ||
145 | - " because privilege spec version does not match", | ||
146 | - isa_edata_arr[i].name, env->mhartid); | ||
147 | -#else | ||
148 | - warn_report("disabling %s extension because " | ||
149 | - "privilege spec version does not match", | ||
150 | - isa_edata_arr[i].name); | ||
151 | -#endif | ||
152 | - } | ||
153 | - } | ||
154 | - | ||
155 | if (cpu->cfg.epmp && !cpu->cfg.pmp) { | ||
156 | /* | ||
157 | * Enhanced PMP should only be available | ||
158 | -- | 241 | -- |
159 | 2.40.1 | 242 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Cheng Yang <yangcheng.work@foxmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Compute the target address before storing it into badaddr | 3 | Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell() |
4 | when mis-aligned exception is triggered. | 4 | to set the address of initrd in FDT to support 64-bit address. |
5 | Use a target_pc temp to store the target address to avoid | ||
6 | the confusing operation that udpate target address into | ||
7 | cpu_pc before misalign check, then update it into badaddr | ||
8 | and restore cpu_pc to current pc if exception is triggered. | ||
9 | 5 | ||
10 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 6 | Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com> |
11 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
14 | Message-Id: <20230526072124.298466-2-liweiwei@iscas.ac.cn> | 8 | Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com> |
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 10 | --- |
17 | target/riscv/translate.c | 21 ++++++++++----------- | 11 | hw/riscv/boot.c | 4 ++-- |
18 | target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++------- | 12 | 1 file changed, 2 insertions(+), 2 deletions(-) |
19 | target/riscv/insn_trans/trans_rvzce.c.inc | 4 ++-- | ||
20 | 3 files changed, 28 insertions(+), 20 deletions(-) | ||
21 | 13 | ||
22 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 14 | diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c |
23 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/riscv/translate.c | 16 | --- a/hw/riscv/boot.c |
25 | +++ b/target/riscv/translate.c | 17 | +++ b/hw/riscv/boot.c |
26 | @@ -XXX,XX +XXX,XX @@ static void decode_save_opc(DisasContext *ctx) | 18 | @@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry) |
27 | ctx->insn_start = NULL; | 19 | /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */ |
28 | } | 20 | if (fdt) { |
29 | 21 | end = start + size; | |
30 | -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest) | 22 | - qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start); |
31 | +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx, | 23 | - qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end); |
32 | + target_ulong dest) | 24 | + qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start); |
33 | { | 25 | + qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end); |
34 | if (get_xl(ctx) == MXL_RV32) { | ||
35 | dest = (int32_t)dest; | ||
36 | } | ||
37 | - tcg_gen_movi_tl(cpu_pc, dest); | ||
38 | + tcg_gen_movi_tl(target, dest); | ||
39 | } | ||
40 | |||
41 | -static void gen_set_pc(DisasContext *ctx, TCGv dest) | ||
42 | +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest) | ||
43 | { | ||
44 | - if (get_xl(ctx) == MXL_RV32) { | ||
45 | - tcg_gen_ext32s_tl(cpu_pc, dest); | ||
46 | - } else { | ||
47 | - tcg_gen_mov_tl(cpu_pc, dest); | ||
48 | - } | ||
49 | + gen_pc_plus_diff(cpu_pc, ctx, dest); | ||
50 | } | ||
51 | |||
52 | static void generate_exception(DisasContext *ctx, int excp) | ||
53 | @@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx) | ||
54 | } | 26 | } |
55 | } | 27 | } |
56 | 28 | ||
57 | -static void gen_exception_inst_addr_mis(DisasContext *ctx) | ||
58 | +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target) | ||
59 | { | ||
60 | - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr)); | ||
61 | + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr)); | ||
62 | generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS); | ||
63 | } | ||
64 | |||
65 | @@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
66 | next_pc = ctx->base.pc_next + imm; | ||
67 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
68 | if ((next_pc & 0x3) != 0) { | ||
69 | - gen_exception_inst_addr_mis(ctx); | ||
70 | + TCGv target_pc = tcg_temp_new(); | ||
71 | + gen_pc_plus_diff(target_pc, ctx, next_pc); | ||
72 | + gen_exception_inst_addr_mis(ctx, target_pc); | ||
73 | return; | ||
74 | } | ||
75 | } | ||
76 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
79 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
80 | @@ -XXX,XX +XXX,XX @@ static bool trans_jal(DisasContext *ctx, arg_jal *a) | ||
81 | static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
82 | { | ||
83 | TCGLabel *misaligned = NULL; | ||
84 | + TCGv target_pc = tcg_temp_new(); | ||
85 | |||
86 | - tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm); | ||
87 | - tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2); | ||
88 | + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm); | ||
89 | + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2); | ||
90 | + | ||
91 | + if (get_xl(ctx) == MXL_RV32) { | ||
92 | + tcg_gen_ext32s_tl(target_pc, target_pc); | ||
93 | + } | ||
94 | |||
95 | - gen_set_pc(ctx, cpu_pc); | ||
96 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
97 | TCGv t0 = tcg_temp_new(); | ||
98 | |||
99 | misaligned = gen_new_label(); | ||
100 | - tcg_gen_andi_tl(t0, cpu_pc, 0x2); | ||
101 | + tcg_gen_andi_tl(t0, target_pc, 0x2); | ||
102 | tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned); | ||
103 | } | ||
104 | |||
105 | gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn); | ||
106 | + tcg_gen_mov_tl(cpu_pc, target_pc); | ||
107 | lookup_and_goto_ptr(ctx); | ||
108 | |||
109 | if (misaligned) { | ||
110 | gen_set_label(misaligned); | ||
111 | - gen_exception_inst_addr_mis(ctx); | ||
112 | + gen_exception_inst_addr_mis(ctx, target_pc); | ||
113 | } | ||
114 | ctx->base.is_jmp = DISAS_NORETURN; | ||
115 | |||
116 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
117 | TCGLabel *l = gen_new_label(); | ||
118 | TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
119 | TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN); | ||
120 | + target_ulong next_pc; | ||
121 | |||
122 | if (get_xl(ctx) == MXL_RV128) { | ||
123 | TCGv src1h = get_gprh(ctx, a->rs1); | ||
124 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
125 | |||
126 | gen_set_label(l); /* branch taken */ | ||
127 | |||
128 | + next_pc = ctx->base.pc_next + a->imm; | ||
129 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca && | ||
130 | - ((ctx->base.pc_next + a->imm) & 0x3)) { | ||
131 | + (next_pc & 0x3)) { | ||
132 | /* misaligned */ | ||
133 | - gen_exception_inst_addr_mis(ctx); | ||
134 | + TCGv target_pc = tcg_temp_new(); | ||
135 | + gen_pc_plus_diff(target_pc, ctx, next_pc); | ||
136 | + gen_exception_inst_addr_mis(ctx, target_pc); | ||
137 | } else { | ||
138 | gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm); | ||
139 | } | ||
140 | diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
141 | index XXXXXXX..XXXXXXX 100644 | ||
142 | --- a/target/riscv/insn_trans/trans_rvzce.c.inc | ||
143 | +++ b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
144 | @@ -XXX,XX +XXX,XX @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) | ||
145 | } | ||
146 | |||
147 | if (ret) { | ||
148 | - TCGv ret_addr = get_gpr(ctx, xRA, EXT_NONE); | ||
149 | - gen_set_pc(ctx, ret_addr); | ||
150 | + TCGv ret_addr = get_gpr(ctx, xRA, EXT_SIGN); | ||
151 | + tcg_gen_mov_tl(cpu_pc, ret_addr); | ||
152 | tcg_gen_lookup_and_goto_ptr(); | ||
153 | ctx->base.is_jmp = DISAS_NORETURN; | ||
154 | } | ||
155 | -- | 29 | -- |
156 | 2.40.1 | 30 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Clément Léger <cleger@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | pflash devices can be used in virt machine for different | 3 | The current semihost exception number (16) is a reserved number (range |
4 | purposes like for ROM code or S-mode FW payload. Add a | 4 | [16-17]). The upcoming double trap specification uses that number for |
5 | section in the documentation on how to use pflash devices | 5 | the double trap exception. Since the privileged spec (Table 22) defines |
6 | for different purposes. | 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. | ||
7 | 9 | ||
8 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 10 | Signed-off-by: Clément Léger <cleger@rivosinc.com> |
9 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 11 | |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
11 | Message-Id: <20230601045910.18646-4-sunilvl@ventanamicro.com> | 13 | Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com> |
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 15 | --- |
14 | docs/system/riscv/virt.rst | 31 +++++++++++++++++++++++++++++++ | 16 | target/riscv/cpu_bits.h | 2 +- |
15 | 1 file changed, 31 insertions(+) | 17 | 1 file changed, 1 insertion(+), 1 deletion(-) |
16 | 18 | ||
17 | diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst | 19 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h |
18 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/docs/system/riscv/virt.rst | 21 | --- a/target/riscv/cpu_bits.h |
20 | +++ b/docs/system/riscv/virt.rst | 22 | +++ b/target/riscv/cpu_bits.h |
21 | @@ -XXX,XX +XXX,XX @@ with the default OpenSBI firmware image as the -bios. It also supports | 23 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { |
22 | the recommended RISC-V bootflow: U-Boot SPL (M-mode) loads OpenSBI fw_dynamic | 24 | RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */ |
23 | firmware and U-Boot proper (S-mode), using the standard -bios functionality. | 25 | RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */ |
24 | 26 | RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */ | |
25 | +Using flash devices | 27 | - RISCV_EXCP_SEMIHOST = 0x10, |
26 | +------------------- | 28 | RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14, |
27 | + | 29 | RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15, |
28 | +By default, the first flash device (pflash0) is expected to contain | 30 | RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16, |
29 | +S-mode firmware code. It can be configured as read-only, with the | 31 | RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17, |
30 | +second flash device (pflash1) available to store configuration data. | 32 | + RISCV_EXCP_SEMIHOST = 0x3f, |
31 | + | 33 | } RISCVException; |
32 | +For example, booting edk2 looks like | 34 | |
33 | + | 35 | #define RISCV_EXCP_INT_FLAG 0x80000000 |
34 | +.. code-block:: bash | ||
35 | + | ||
36 | + $ qemu-system-riscv64 \ | ||
37 | + -blockdev node-name=pflash0,driver=file,read-only=on,filename=<edk2_code> \ | ||
38 | + -blockdev node-name=pflash1,driver=file,filename=<edk2_vars> \ | ||
39 | + -M virt,pflash0=pflash0,pflash1=pflash1 \ | ||
40 | + ... other args .... | ||
41 | + | ||
42 | +For TCG guests only, it is also possible to boot M-mode firmware from | ||
43 | +the first flash device (pflash0) by additionally passing ``-bios | ||
44 | +none``, as in | ||
45 | + | ||
46 | +.. code-block:: bash | ||
47 | + | ||
48 | + $ qemu-system-riscv64 \ | ||
49 | + -bios none \ | ||
50 | + -blockdev node-name=pflash0,driver=file,read-only=on,filename=<m_mode_code> \ | ||
51 | + -M virt,pflash0=pflash0 \ | ||
52 | + ... other args .... | ||
53 | + | ||
54 | +Firmware images used for pflash must be exactly 32 MiB in size. | ||
55 | + | ||
56 | Machine-specific options | ||
57 | ------------------------ | ||
58 | |||
59 | -- | 36 | -- |
60 | 2.40.1 | 37 | 2.45.1 |
61 | 38 | ||
62 | 39 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | This setter is doing nothing else but setting env->vext_ver. Assign the | 3 | Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr |
4 | value directly. | 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. | ||
5 | 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> | ||
6 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 30 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
7 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 31 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
8 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 32 | Cc: qemu-stable <qemu-stable@nongnu.org> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 33 | Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com> |
10 | Message-Id: <20230517135714.211809-3-dbarboza@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 34 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 35 | --- |
13 | target/riscv/cpu.c | 7 +------ | 36 | target/riscv/kvm/kvm-cpu.c | 12 ++++++++---- |
14 | 1 file changed, 1 insertion(+), 6 deletions(-) | 37 | 1 file changed, 8 insertions(+), 4 deletions(-) |
15 | 38 | ||
16 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 39 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c |
17 | index XXXXXXX..XXXXXXX 100644 | 40 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/cpu.c | 41 | --- a/target/riscv/kvm/kvm-cpu.c |
19 | +++ b/target/riscv/cpu.c | 42 | +++ b/target/riscv/kvm/kvm-cpu.c |
20 | @@ -XXX,XX +XXX,XX @@ static void set_priv_version(CPURISCVState *env, int priv_ver) | 43 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs) |
21 | env->priv_ver = priv_ver; | 44 | reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg); |
45 | ret = kvm_set_one_reg(cs, id, ®); | ||
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 | } | ||
22 | } | 61 | } |
23 | |||
24 | -static void set_vext_version(CPURISCVState *env, int vext_ver) | ||
25 | -{ | ||
26 | - env->vext_ver = vext_ver; | ||
27 | -} | ||
28 | - | ||
29 | #ifndef CONFIG_USER_ONLY | ||
30 | static uint8_t satp_mode_from_str(const char *satp_mode_str) | ||
31 | { | ||
32 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, | ||
33 | qemu_log("vector version is not specified, " | ||
34 | "use the default value v1.0\n"); | ||
35 | } | ||
36 | - set_vext_version(env, vext_version); | ||
37 | + env->vext_ver = vext_version; | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | -- | 62 | -- |
42 | 2.40.1 | 63 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | We initialize cur_pmmask as -1(UINT32_MAX/UINT64_MAX) and regard it | 3 | We're not setting (s/m)tval when triggering breakpoints of type 2 |
4 | as if pointer mask is disabled in current implementation. However, | 4 | (mcontrol) and 6 (mcontrol6). According to the debug spec section |
5 | the addresses for vector load/store will be adjusted to zero in this | 5 | 5.7.12, "Match Control Type 6": |
6 | case and -1(UINT32_MAX/UINT64_MAX) is valid value for pmmask when | ||
7 | pointer mask is enabled. | ||
8 | 6 | ||
9 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | "The Privileged Spec says that breakpoint exceptions that occur on |
10 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 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(). | ||
24 | |||
25 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
26 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 27 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
12 | Message-Id: <20230610094651.43786-1-liweiwei@iscas.ac.cn> | 28 | Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 29 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 30 | --- |
15 | target/riscv/cpu_helper.c | 4 ++-- | 31 | target/riscv/cpu_helper.c | 1 + |
16 | 1 file changed, 2 insertions(+), 2 deletions(-) | 32 | target/riscv/debug.c | 3 +++ |
33 | 2 files changed, 4 insertions(+) | ||
17 | 34 | ||
18 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | 35 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c |
19 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/riscv/cpu_helper.c | 37 | --- a/target/riscv/cpu_helper.c |
21 | +++ b/target/riscv/cpu_helper.c | 38 | +++ b/target/riscv/cpu_helper.c |
22 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | 39 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) |
23 | flags = FIELD_DP32(flags, TB_FLAGS, FS, fs); | 40 | tval = env->bins; |
24 | flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); | 41 | break; |
25 | flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); | 42 | case RISCV_EXCP_BREAKPOINT: |
26 | - if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) { | 43 | + tval = env->badaddr; |
27 | + if (env->cur_pmmask != 0) { | 44 | if (cs->watchpoint_hit) { |
28 | flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1); | 45 | tval = cs->watchpoint_hit->hitaddr; |
29 | } | 46 | cs->watchpoint_hit = NULL; |
30 | if (env->cur_pmbase != 0) { | 47 | diff --git a/target/riscv/debug.c b/target/riscv/debug.c |
31 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | 48 | index XXXXXXX..XXXXXXX 100644 |
32 | 49 | --- a/target/riscv/debug.c | |
33 | void riscv_cpu_update_mask(CPURISCVState *env) | 50 | +++ b/target/riscv/debug.c |
34 | { | 51 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs) |
35 | - target_ulong mask = -1, base = 0; | 52 | if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { |
36 | + target_ulong mask = 0, base = 0; | 53 | /* check U/S/M bit against current privilege level */ |
37 | /* | 54 | if ((ctrl >> 3) & BIT(env->priv)) { |
38 | * TODO: Current RVJ spec does not specify | 55 | + env->badaddr = pc; |
39 | * how the extension interacts with XLEN. | 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 | } | ||
40 | -- | 73 | -- |
41 | 2.40.1 | 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 | We have 4 config settings being done in riscv_cpu_init(): ext_ifencei, | 3 | Privileged spec section 4.1.9 mentions: |
4 | ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu" | ||
5 | device, which happens to be the parent device of every RISC-V cpu. | ||
6 | 4 | ||
7 | The result is that these 4 configs are being set every time, and every | 5 | "When a trap is taken into S-mode, stval is written with |
8 | other CPU should always account for them. CPUs such as sifive_e need to | 6 | exception-specific information to assist software in handling the trap. |
9 | disable settings that aren't enabled simply because the parent class | 7 | (...) |
10 | happens to be enabling it. | ||
11 | 8 | ||
12 | Moving all configurations from the parent class to each CPU will | 9 | If stval is written with a nonzero value when a breakpoint, |
13 | centralize the config of each CPU into its own init(), which is clearer | 10 | address-misaligned, access-fault, or page-fault exception occurs on an |
14 | than having to account to whatever happens to be set in the parent | 11 | instruction fetch, load, or store, then stval will contain the faulting |
15 | device. These settings are also being set in register_cpu_props() when | 12 | virtual address." |
16 | no 'misa_ext' is set, so for these CPUs we don't need changes. Named | 13 | |
17 | CPUs will receive all cfgs that the parent were setting into their | 14 | A similar text is found for mtval in section 3.1.16. |
18 | init(). | 15 | |
16 | Setting mtval/stval in this scenario is optional, but some softwares read | ||
17 | these regs when handling ebreaks. | ||
18 | |||
19 | Write 'badaddr' in all ebreak breakpoints to write the appropriate | ||
20 | 'tval' during riscv_do_cpu_interrrupt(). | ||
19 | 21 | ||
20 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 22 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
23 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
21 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 24 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
22 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 25 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
23 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 26 | Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com> |
24 | Message-Id: <20230517135714.211809-11-dbarboza@ventanamicro.com> | ||
25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 27 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
26 | --- | 28 | --- |
27 | target/riscv/cpu.c | 59 ++++++++++++++++++++++++++++++++++++---------- | 29 | target/riscv/insn_trans/trans_privileged.c.inc | 2 ++ |
28 | 1 file changed, 47 insertions(+), 12 deletions(-) | 30 | 1 file changed, 2 insertions(+) |
29 | 31 | ||
30 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 32 | diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc |
31 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/target/riscv/cpu.c | 34 | --- a/target/riscv/insn_trans/trans_privileged.c.inc |
33 | +++ b/target/riscv/cpu.c | 35 | +++ b/target/riscv/insn_trans/trans_privileged.c.inc |
34 | @@ -XXX,XX +XXX,XX @@ static void set_satp_mode_default_map(RISCVCPU *cpu) | 36 | @@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a) |
35 | 37 | if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) { | |
36 | static void riscv_any_cpu_init(Object *obj) | 38 | generate_exception(ctx, RISCV_EXCP_SEMIHOST); |
37 | { | 39 | } else { |
38 | - CPURISCVState *env = &RISCV_CPU(obj)->env; | 40 | + tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env, |
39 | + RISCVCPU *cpu = RISCV_CPU(obj); | 41 | + offsetof(CPURISCVState, badaddr)); |
40 | + CPURISCVState *env = &cpu->env; | 42 | generate_exception(ctx, RISCV_EXCP_BREAKPOINT); |
41 | #if defined(TARGET_RISCV32) | 43 | } |
42 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU); | 44 | return true; |
43 | #elif defined(TARGET_RISCV64) | ||
44 | @@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj) | ||
45 | #endif | ||
46 | |||
47 | env->priv_ver = PRIV_VERSION_LATEST; | ||
48 | + | ||
49 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
50 | + cpu->cfg.ext_ifencei = true; | ||
51 | + cpu->cfg.ext_icsr = true; | ||
52 | + cpu->cfg.mmu = true; | ||
53 | + cpu->cfg.pmp = true; | ||
54 | } | ||
55 | |||
56 | #if defined(TARGET_RISCV64) | ||
57 | @@ -XXX,XX +XXX,XX @@ static void rv64_base_cpu_init(Object *obj) | ||
58 | |||
59 | static void rv64_sifive_u_cpu_init(Object *obj) | ||
60 | { | ||
61 | - CPURISCVState *env = &RISCV_CPU(obj)->env; | ||
62 | + RISCVCPU *cpu = RISCV_CPU(obj); | ||
63 | + CPURISCVState *env = &cpu->env; | ||
64 | set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | ||
65 | env->priv_ver = PRIV_VERSION_1_10_0; | ||
66 | #ifndef CONFIG_USER_ONLY | ||
67 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); | ||
68 | #endif | ||
69 | + | ||
70 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
71 | + cpu->cfg.ext_ifencei = true; | ||
72 | + cpu->cfg.ext_icsr = true; | ||
73 | + cpu->cfg.mmu = true; | ||
74 | + cpu->cfg.pmp = true; | ||
75 | } | ||
76 | |||
77 | static void rv64_sifive_e_cpu_init(Object *obj) | ||
78 | @@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj) | ||
79 | |||
80 | set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); | ||
81 | env->priv_ver = PRIV_VERSION_1_10_0; | ||
82 | - cpu->cfg.mmu = false; | ||
83 | #ifndef CONFIG_USER_ONLY | ||
84 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
85 | #endif | ||
86 | + | ||
87 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
88 | + cpu->cfg.ext_ifencei = true; | ||
89 | + cpu->cfg.ext_icsr = true; | ||
90 | + cpu->cfg.pmp = true; | ||
91 | } | ||
92 | |||
93 | static void rv64_thead_c906_cpu_init(Object *obj) | ||
94 | @@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj) | ||
95 | #ifndef CONFIG_USER_ONLY | ||
96 | set_satp_mode_max_supported(cpu, VM_1_10_SV39); | ||
97 | #endif | ||
98 | + | ||
99 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
100 | + cpu->cfg.pmp = true; | ||
101 | } | ||
102 | |||
103 | static void rv64_veyron_v1_cpu_init(Object *obj) | ||
104 | @@ -XXX,XX +XXX,XX @@ static void rv32_base_cpu_init(Object *obj) | ||
105 | |||
106 | static void rv32_sifive_u_cpu_init(Object *obj) | ||
107 | { | ||
108 | - CPURISCVState *env = &RISCV_CPU(obj)->env; | ||
109 | + RISCVCPU *cpu = RISCV_CPU(obj); | ||
110 | + CPURISCVState *env = &cpu->env; | ||
111 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | ||
112 | env->priv_ver = PRIV_VERSION_1_10_0; | ||
113 | #ifndef CONFIG_USER_ONLY | ||
114 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); | ||
115 | #endif | ||
116 | + | ||
117 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
118 | + cpu->cfg.ext_ifencei = true; | ||
119 | + cpu->cfg.ext_icsr = true; | ||
120 | + cpu->cfg.mmu = true; | ||
121 | + cpu->cfg.pmp = true; | ||
122 | } | ||
123 | |||
124 | static void rv32_sifive_e_cpu_init(Object *obj) | ||
125 | @@ -XXX,XX +XXX,XX @@ static void rv32_sifive_e_cpu_init(Object *obj) | ||
126 | |||
127 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); | ||
128 | env->priv_ver = PRIV_VERSION_1_10_0; | ||
129 | - cpu->cfg.mmu = false; | ||
130 | #ifndef CONFIG_USER_ONLY | ||
131 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
132 | #endif | ||
133 | + | ||
134 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
135 | + cpu->cfg.ext_ifencei = true; | ||
136 | + cpu->cfg.ext_icsr = true; | ||
137 | + cpu->cfg.pmp = true; | ||
138 | } | ||
139 | |||
140 | static void rv32_ibex_cpu_init(Object *obj) | ||
141 | @@ -XXX,XX +XXX,XX @@ static void rv32_ibex_cpu_init(Object *obj) | ||
142 | |||
143 | set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); | ||
144 | env->priv_ver = PRIV_VERSION_1_11_0; | ||
145 | - cpu->cfg.mmu = false; | ||
146 | #ifndef CONFIG_USER_ONLY | ||
147 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
148 | #endif | ||
149 | cpu->cfg.epmp = true; | ||
150 | + | ||
151 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
152 | + cpu->cfg.ext_ifencei = true; | ||
153 | + cpu->cfg.ext_icsr = true; | ||
154 | + cpu->cfg.pmp = true; | ||
155 | } | ||
156 | |||
157 | static void rv32_imafcu_nommu_cpu_init(Object *obj) | ||
158 | @@ -XXX,XX +XXX,XX @@ static void rv32_imafcu_nommu_cpu_init(Object *obj) | ||
159 | |||
160 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); | ||
161 | env->priv_ver = PRIV_VERSION_1_10_0; | ||
162 | - cpu->cfg.mmu = false; | ||
163 | #ifndef CONFIG_USER_ONLY | ||
164 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
165 | #endif | ||
166 | + | ||
167 | + /* inherited from parent obj via riscv_cpu_init() */ | ||
168 | + cpu->cfg.ext_ifencei = true; | ||
169 | + cpu->cfg.ext_icsr = true; | ||
170 | + cpu->cfg.pmp = true; | ||
171 | } | ||
172 | #endif | ||
173 | |||
174 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj) | ||
175 | { | ||
176 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
177 | |||
178 | - cpu->cfg.ext_ifencei = true; | ||
179 | - cpu->cfg.ext_icsr = true; | ||
180 | - cpu->cfg.mmu = true; | ||
181 | - cpu->cfg.pmp = true; | ||
182 | - | ||
183 | cpu_set_cpustate_pointers(cpu); | ||
184 | |||
185 | #ifndef CONFIG_USER_ONLY | ||
186 | -- | 45 | -- |
187 | 2.40.1 | 46 | 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 | There is no need to init timers if we're not even sure that our | 3 | Add support for Zve32x extension and replace some checks for Zve32f with |
4 | extensions are valid. Execute riscv_cpu_validate_set_extensions() before | 4 | Zve32x, since Zve32f depends on Zve32x. |
5 | riscv_timer_init(). | ||
6 | 5 | ||
7 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 6 | Signed-off-by: Jason Chien <jason.chien@sifive.com> |
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 7 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | Reviewed-by: Max Chou <max.chou@sifive.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | Message-Id: <20230517135714.211809-10-dbarboza@ventanamicro.com> | 10 | Message-ID: <20240328022343.6871-2-jason.chien@sifive.com> |
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 12 | --- |
14 | target/riscv/cpu.c | 11 ++++------- | 13 | target/riscv/cpu_cfg.h | 1 + |
15 | 1 file changed, 4 insertions(+), 7 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(-) | ||
16 | 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; | ||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 33 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
18 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu.c | 35 | --- a/target/riscv/cpu.c |
20 | +++ b/target/riscv/cpu.c | 36 | +++ b/target/riscv/cpu.c |
21 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | 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; | ||
79 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
80 | index XXXXXXX..XXXXXXX 100644 | ||
81 | --- a/target/riscv/tcg/tcg-cpu.c | ||
82 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
83 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
22 | return; | 84 | return; |
23 | } | 85 | } |
24 | 86 | ||
25 | - | 87 | - if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) { |
26 | -#ifndef CONFIG_USER_ONLY | 88 | - error_setg(errp, "Zve32f/Zve64f extensions require F extension"); |
27 | - if (cpu->cfg.ext_sstc) { | 89 | - return; |
28 | - riscv_timer_init(cpu); | 90 | + /* The Zve32f extension depends on the Zve32x extension */ |
29 | - } | 91 | + if (cpu->cfg.ext_zve32f) { |
30 | -#endif /* CONFIG_USER_ONLY */ | 92 | + if (!riscv_has_ext(env, RVF)) { |
31 | - | 93 | + error_setg(errp, "Zve32f/Zve64f extensions require F extension"); |
32 | riscv_cpu_validate_set_extensions(cpu, &local_err); | 94 | + return; |
33 | if (local_err != NULL) { | 95 | + } |
34 | error_propagate(errp, local_err); | 96 | + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true); |
35 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
36 | } | 97 | } |
37 | 98 | ||
38 | #ifndef CONFIG_USER_ONLY | 99 | if (cpu->cfg.ext_zvfh) { |
39 | + if (cpu->cfg.ext_sstc) { | 100 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
40 | + riscv_timer_init(cpu); | 101 | cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true); |
41 | + } | 102 | } |
42 | + | 103 | |
43 | if (cpu->cfg.pmu_num) { | 104 | - /* |
44 | if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) { | 105 | - * In principle Zve*x would also suffice here, were they supported |
45 | cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | 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"); | ||
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 | |||
46 | -- | 137 | -- |
47 | 2.40.1 | 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 | The RVV verification will error out if fails and it's being done at the | 3 | Add support for Zve64x extension. Enabling Zve64f enables Zve64x and |
4 | end of riscv_cpu_validate_set_extensions(), after we've already set some | 4 | enabling Zve64x enables Zve32x according to their dependency. |
5 | extensions that are dependent on RVV. Let's put it in its own function | ||
6 | and do it earlier. | ||
7 | 5 | ||
8 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 6 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107 |
9 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 7 | Signed-off-by: Jason Chien <jason.chien@sifive.com> |
10 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Max Chou <max.chou@sifive.com> |
12 | Message-Id: <20230517135714.211809-2-dbarboza@ventanamicro.com> | 10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | Message-ID: <20240328022343.6871-3-jason.chien@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 13 | --- |
15 | target/riscv/cpu.c | 89 +++++++++++++++++++++++++--------------------- | 14 | target/riscv/cpu_cfg.h | 1 + |
16 | 1 file changed, 48 insertions(+), 41 deletions(-) | 15 | target/riscv/cpu.c | 2 ++ |
16 | target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------ | ||
17 | 3 files changed, 14 insertions(+), 6 deletions(-) | ||
17 | 18 | ||
19 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/cpu_cfg.h | ||
22 | +++ b/target/riscv/cpu_cfg.h | ||
23 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
24 | bool ext_zve32x; | ||
25 | bool ext_zve64f; | ||
26 | bool ext_zve64d; | ||
27 | + bool ext_zve64x; | ||
28 | bool ext_zvbb; | ||
29 | bool ext_zvbc; | ||
30 | bool ext_zvkb; | ||
18 | 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 |
19 | index XXXXXXX..XXXXXXX 100644 | 32 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/riscv/cpu.c | 33 | --- a/target/riscv/cpu.c |
21 | +++ b/target/riscv/cpu.c | 34 | +++ b/target/riscv/cpu.c |
22 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) | 35 | @@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = { |
23 | } | 36 | ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x), |
24 | } | 37 | ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f), |
25 | 38 | ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d), | |
26 | +static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, | 39 | + ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x), |
27 | + Error **errp) | 40 | ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin), |
28 | +{ | 41 | ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma), |
29 | + int vext_version = VEXT_VERSION_1_00_0; | 42 | ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh), |
30 | + | 43 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { |
31 | + if (!is_power_of_2(cfg->vlen)) { | 44 | MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false), |
32 | + error_setg(errp, "Vector extension VLEN must be power of 2"); | 45 | MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false), |
33 | + return; | 46 | MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false), |
34 | + } | 47 | + MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false), |
35 | + if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { | 48 | MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false), |
36 | + error_setg(errp, | 49 | MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false), |
37 | + "Vector extension implementation only supports VLEN " | 50 | MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false), |
38 | + "in the range [128, %d]", RV_VLEN_MAX); | 51 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
39 | + return; | 52 | index XXXXXXX..XXXXXXX 100644 |
40 | + } | 53 | --- a/target/riscv/tcg/tcg-cpu.c |
41 | + if (!is_power_of_2(cfg->elen)) { | 54 | +++ b/target/riscv/tcg/tcg-cpu.c |
42 | + error_setg(errp, "Vector extension ELEN must be power of 2"); | 55 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
43 | + return; | 56 | |
44 | + } | 57 | /* The Zve64d extension depends on the Zve64f extension */ |
45 | + if (cfg->elen > 64 || cfg->elen < 8) { | 58 | if (cpu->cfg.ext_zve64d) { |
46 | + error_setg(errp, | 59 | + if (!riscv_has_ext(env, RVD)) { |
47 | + "Vector extension implementation only supports ELEN " | 60 | + error_setg(errp, "Zve64d/V extensions require D extension"); |
48 | + "in the range [8, 64]"); | ||
49 | + return; | ||
50 | + } | ||
51 | + if (cfg->vext_spec) { | ||
52 | + if (!g_strcmp0(cfg->vext_spec, "v1.0")) { | ||
53 | + vext_version = VEXT_VERSION_1_00_0; | ||
54 | + } else { | ||
55 | + error_setg(errp, "Unsupported vector spec version '%s'", | ||
56 | + cfg->vext_spec); | ||
57 | + return; | 61 | + return; |
58 | + } | 62 | + } |
59 | + } else { | 63 | cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true); |
60 | + qemu_log("vector version is not specified, " | 64 | } |
61 | + "use the default value v1.0\n"); | 65 | |
62 | + } | 66 | - /* The Zve64f extension depends on the Zve32f extension */ |
63 | + set_vext_version(env, vext_version); | 67 | + /* The Zve64f extension depends on the Zve64x and Zve32f extensions */ |
64 | +} | 68 | if (cpu->cfg.ext_zve64f) { |
65 | + | 69 | + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true); |
66 | /* | 70 | cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true); |
67 | * Check consistency between chosen extensions while setting | 71 | } |
68 | * cpu->cfg accordingly. | 72 | |
69 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) | 73 | - if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) { |
70 | static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 74 | - error_setg(errp, "Zve64d/V extensions require D extension"); |
71 | { | 75 | - return; |
72 | CPURISCVState *env = &cpu->env; | 76 | + /* The Zve64x extension depends on the Zve32x extension */ |
73 | + Error *local_err = NULL; | 77 | + if (cpu->cfg.ext_zve64x) { |
74 | 78 | + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true); | |
75 | /* Do some ISA extension error checking */ | 79 | } |
76 | if (riscv_has_ext(env, RVG) && | 80 | |
77 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 81 | /* The Zve32f extension depends on the Zve32x extension */ |
82 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
78 | return; | 83 | return; |
79 | } | 84 | } |
80 | 85 | ||
81 | - /* The V vector extension depends on the Zve64d extension */ | 86 | - if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) { |
82 | if (riscv_has_ext(env, RVV)) { | 87 | + if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) { |
83 | + riscv_cpu_validate_v(env, &cpu->cfg, &local_err); | 88 | error_setg( |
84 | + if (local_err != NULL) { | 89 | errp, |
85 | + error_propagate(errp, local_err); | 90 | - "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions"); |
86 | + return; | 91 | + "Zvbc and Zvknhb extensions require V or Zve64x extensions"); |
87 | + } | 92 | return; |
88 | + | ||
89 | + /* The V vector extension depends on the Zve64d extension */ | ||
90 | cpu->cfg.ext_zve64d = true; | ||
91 | } | 93 | } |
92 | 94 | ||
93 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
94 | cpu->cfg.ext_zksed = true; | ||
95 | cpu->cfg.ext_zksh = true; | ||
96 | } | ||
97 | - | ||
98 | - if (riscv_has_ext(env, RVV)) { | ||
99 | - int vext_version = VEXT_VERSION_1_00_0; | ||
100 | - if (!is_power_of_2(cpu->cfg.vlen)) { | ||
101 | - error_setg(errp, | ||
102 | - "Vector extension VLEN must be power of 2"); | ||
103 | - return; | ||
104 | - } | ||
105 | - if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) { | ||
106 | - error_setg(errp, | ||
107 | - "Vector extension implementation only supports VLEN " | ||
108 | - "in the range [128, %d]", RV_VLEN_MAX); | ||
109 | - return; | ||
110 | - } | ||
111 | - if (!is_power_of_2(cpu->cfg.elen)) { | ||
112 | - error_setg(errp, | ||
113 | - "Vector extension ELEN must be power of 2"); | ||
114 | - return; | ||
115 | - } | ||
116 | - if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) { | ||
117 | - error_setg(errp, | ||
118 | - "Vector extension implementation only supports ELEN " | ||
119 | - "in the range [8, 64]"); | ||
120 | - return; | ||
121 | - } | ||
122 | - if (cpu->cfg.vext_spec) { | ||
123 | - if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) { | ||
124 | - vext_version = VEXT_VERSION_1_00_0; | ||
125 | - } else { | ||
126 | - error_setg(errp, | ||
127 | - "Unsupported vector spec version '%s'", | ||
128 | - cpu->cfg.vext_spec); | ||
129 | - return; | ||
130 | - } | ||
131 | - } else { | ||
132 | - qemu_log("vector version is not specified, " | ||
133 | - "use the default value v1.0\n"); | ||
134 | - } | ||
135 | - set_vext_version(env, vext_version); | ||
136 | - } | ||
137 | } | ||
138 | |||
139 | #ifndef CONFIG_USER_ONLY | ||
140 | -- | 95 | -- |
141 | 2.40.1 | 96 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Jason Chien <jason.chien@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Use pointer to pass more information of target to disasembler, | 3 | In current implementation, the gdbstub allows reading vector registers |
4 | such as pass cpu.cfg related information in following commits. | 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. | ||
5 | 7 | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | Signed-off-by: Jason Chien <jason.chien@sifive.com> |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 9 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 10 | Reviewed-by: Max Chou <max.chou@sifive.com> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Message-ID: <20240328022343.6871-4-jason.chien@sifive.com> |
10 | Message-Id: <20230523093539.203909-2-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 13 | --- |
13 | include/disas/dis-asm.h | 2 +- | 14 | target/riscv/gdbstub.c | 2 +- |
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | 15 | 1 file changed, 1 insertion(+), 1 deletion(-) |
15 | 16 | ||
16 | diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h | 17 | diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c |
17 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/include/disas/dis-asm.h | 19 | --- a/target/riscv/gdbstub.c |
19 | +++ b/include/disas/dis-asm.h | 20 | +++ b/target/riscv/gdbstub.c |
20 | @@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info { | 21 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) |
21 | char * disassembler_options; | 22 | gdb_find_static_feature("riscv-32bit-fpu.xml"), |
22 | 23 | 0); | |
23 | /* Field intended to be used by targets in any way they deem suitable. */ | 24 | } |
24 | - int64_t target_info; | 25 | - if (env->misa_ext & RVV) { |
25 | + void *target_info; | 26 | + if (cpu->cfg.ext_zve32x) { |
26 | 27 | gdb_register_coprocessor(cs, riscv_gdb_get_vector, | |
27 | /* Options for Capstone disassembly. */ | 28 | riscv_gdb_set_vector, |
28 | int cap_arch; | 29 | ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs), |
29 | -- | 30 | -- |
30 | 2.40.1 | 31 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Mayuresh Chitale <mchitale@ventanamicro.com> | 1 | From: Huang Tao <eric.huang@linux.alibaba.com> |
---|---|---|---|
2 | 2 | ||
3 | Implement the s/h/mstateen.fcsr bit as defined in the smstateen spec | 3 | In RVV and vcrypto instructions, the masked and tail elements are set to 1s |
4 | and check for it when accessing the fcsr register and its fields. | 4 | using vext_set_elems_1s function if the vma/vta bit is set. It is the element |
5 | agnostic policy. | ||
5 | 6 | ||
6 | Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com> | 7 | However, this function can't deal the big endian situation. This patch fixes |
7 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | the problem by adding handling of such case. |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | |
9 | Message-Id: <20230518175058.2772506-2-mchitale@ventanamicro.com> | 10 | Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com> |
11 | Suggested-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
13 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
14 | Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 16 | --- |
12 | target/riscv/csr.c | 15 +++++++++++++++ | 17 | target/riscv/vector_internals.c | 22 ++++++++++++++++++++++ |
13 | 1 file changed, 15 insertions(+) | 18 | 1 file changed, 22 insertions(+) |
14 | 19 | ||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 20 | diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c |
16 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/csr.c | 22 | --- a/target/riscv/vector_internals.c |
18 | +++ b/target/riscv/csr.c | 23 | +++ b/target/riscv/vector_internals.c |
19 | @@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno) | 24 | @@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, |
20 | !riscv_cpu_cfg(env)->ext_zfinx) { | 25 | if (tot - cnt == 0) { |
21 | return RISCV_EXCP_ILLEGAL_INST; | 26 | return ; |
22 | } | 27 | } |
23 | + | 28 | + |
24 | + if (!env->debugger && !riscv_cpu_fp_enabled(env)) { | 29 | + if (HOST_BIG_ENDIAN) { |
25 | + return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR); | 30 | + /* |
31 | + * Deal the situation when the elements are insdie | ||
32 | + * only one uint64 block including setting the | ||
33 | + * masked-off element. | ||
34 | + */ | ||
35 | + if (((tot - 1) ^ cnt) < 8) { | ||
36 | + memset(base + H1(tot - 1), -1, tot - cnt); | ||
37 | + return; | ||
38 | + } | ||
39 | + /* | ||
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 */ | ||
26 | + } | 49 | + } |
27 | #endif | 50 | memset(base + cnt, -1, tot - cnt); |
28 | return RISCV_EXCP_NONE; | ||
29 | } | 51 | } |
30 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno, | ||
31 | target_ulong new_val) | ||
32 | { | ||
33 | uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; | ||
34 | + if (!riscv_has_ext(env, RVF)) { | ||
35 | + wr_mask |= SMSTATEEN0_FCSR; | ||
36 | + } | ||
37 | |||
38 | return write_mstateen(env, csrno, wr_mask, new_val); | ||
39 | } | ||
40 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno, | ||
41 | { | ||
42 | uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; | ||
43 | |||
44 | + if (!riscv_has_ext(env, RVF)) { | ||
45 | + wr_mask |= SMSTATEEN0_FCSR; | ||
46 | + } | ||
47 | + | ||
48 | return write_hstateen(env, csrno, wr_mask, new_val); | ||
49 | } | ||
50 | |||
51 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno, | ||
52 | { | ||
53 | uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; | ||
54 | |||
55 | + if (!riscv_has_ext(env, RVF)) { | ||
56 | + wr_mask |= SMSTATEEN0_FCSR; | ||
57 | + } | ||
58 | + | ||
59 | return write_sstateen(env, csrno, wr_mask, new_val); | ||
60 | } | ||
61 | 52 | ||
62 | -- | 53 | -- |
63 | 2.40.1 | 54 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Mayuresh Chitale <mchitale@ventanamicro.com> | 1 | From: Yangyu Chen <cyy@cyyself.name> |
---|---|---|---|
2 | 2 | ||
3 | Add knobs to allow users to enable smstateen and also export it via the | 3 | This code has a typo that writes zvkb to zvkg, causing users can't |
4 | ISA extension string. | 4 | enable zvkb through the config. This patch gets this fixed. |
5 | 5 | ||
6 | Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com> | 6 | Signed-off-by: Yangyu Chen <cyy@cyyself.name> |
7 | Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn> | 7 | Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions") |
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-Id: <20230518175058.2772506-4-mchitale@ventanamicro.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> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 15 | --- |
12 | target/riscv/cpu.c | 3 ++- | 16 | target/riscv/cpu.c | 2 +- |
13 | 1 file changed, 2 insertions(+), 1 deletion(-) | 17 | 1 file changed, 1 insertion(+), 1 deletion(-) |
14 | 18 | ||
15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 19 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
16 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu.c | 21 | --- a/target/riscv/cpu.c |
18 | +++ b/target/riscv/cpu.c | 22 | +++ b/target/riscv/cpu.c |
19 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | 23 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { |
20 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), | 24 | /* Vector cryptography extensions */ |
21 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), | 25 | MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false), |
22 | ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), | 26 | MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false), |
23 | + ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen), | 27 | - MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false), |
24 | ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia), | 28 | + MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false), |
25 | ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf), | 29 | MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false), |
26 | ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc), | 30 | MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false), |
27 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | 31 | MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false), |
28 | DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), | ||
29 | DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
30 | |||
31 | + DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false), | ||
32 | DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true), | ||
33 | - | ||
34 | DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), | ||
35 | DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), | ||
36 | DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false), | ||
37 | -- | 32 | -- |
38 | 2.40.1 | 33 | 2.45.1 |
34 | |||
35 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Huang Tao <eric.huang@linux.alibaba.com> |
---|---|---|---|
2 | 2 | ||
3 | Add a base pc_save for PC-relative translation(CF_PCREL). | 3 | In this patch, we modify the decoder to be a freely composable data |
4 | Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb. | 4 | structure instead of a hardcoded one. It can be dynamically builded up |
5 | Use gen_pc_plus_diff to get the pc-relative address. | 5 | according to the extensions. |
6 | Enable CF_PCREL in System mode. | 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. | ||
7 | 20 | ||
8 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 21 | Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com> |
9 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 22 | Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu> |
23 | Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 24 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 25 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
12 | Message-Id: <20230526072124.298466-7-liweiwei@iscas.ac.cn> | 26 | Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 27 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 28 | --- |
15 | target/riscv/cpu.c | 31 ++++++++++----- | 29 | target/riscv/cpu.h | 1 + |
16 | target/riscv/translate.c | 47 +++++++++++++++++++---- | 30 | target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++ |
17 | target/riscv/insn_trans/trans_rvi.c.inc | 12 +++++- | 31 | target/riscv/cpu.c | 1 + |
18 | target/riscv/insn_trans/trans_rvzce.c.inc | 4 +- | 32 | target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++ |
19 | 4 files changed, 74 insertions(+), 20 deletions(-) | 33 | target/riscv/translate.c | 31 +++++++++++++++---------------- |
34 | 5 files changed, 47 insertions(+), 16 deletions(-) | ||
20 | 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 | ||
21 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 72 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
22 | index XXXXXXX..XXXXXXX 100644 | 73 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/cpu.c | 74 | --- a/target/riscv/cpu.c |
24 | +++ b/target/riscv/cpu.c | 75 | +++ b/target/riscv/cpu.c |
25 | @@ -XXX,XX +XXX,XX @@ static vaddr riscv_cpu_get_pc(CPUState *cs) | 76 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp) |
26 | static void riscv_cpu_synchronize_from_tb(CPUState *cs, | 77 | error_propagate(errp, local_err); |
27 | const TranslationBlock *tb) | 78 | return; |
28 | { | 79 | } |
29 | - RISCVCPU *cpu = RISCV_CPU(cs); | 80 | + riscv_tcg_cpu_finalize_dynamic_decoder(cpu); |
30 | - CPURISCVState *env = &cpu->env; | 81 | } else if (kvm_enabled()) { |
31 | - RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); | 82 | riscv_kvm_cpu_finalize_features(cpu, &local_err); |
32 | + if (!(tb_cflags(tb) & CF_PCREL)) { | 83 | if (local_err != NULL) { |
33 | + RISCVCPU *cpu = RISCV_CPU(cs); | 84 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
34 | + CPURISCVState *env = &cpu->env; | 85 | index XXXXXXX..XXXXXXX 100644 |
35 | + RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); | 86 | --- a/target/riscv/tcg/tcg-cpu.c |
36 | 87 | +++ b/target/riscv/tcg/tcg-cpu.c | |
37 | - tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL)); | 88 | @@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) |
38 | + tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL)); | ||
39 | |||
40 | - if (xl == MXL_RV32) { | ||
41 | - env->pc = (int32_t) tb->pc; | ||
42 | - } else { | ||
43 | - env->pc = tb->pc; | ||
44 | + if (xl == MXL_RV32) { | ||
45 | + env->pc = (int32_t) tb->pc; | ||
46 | + } else { | ||
47 | + env->pc = tb->pc; | ||
48 | + } | ||
49 | } | 89 | } |
50 | } | 90 | } |
51 | 91 | ||
52 | @@ -XXX,XX +XXX,XX @@ static void riscv_restore_state_to_opc(CPUState *cs, | 92 | +void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu) |
53 | RISCVCPU *cpu = RISCV_CPU(cs); | 93 | +{ |
54 | CPURISCVState *env = &cpu->env; | 94 | + GPtrArray *dynamic_decoders; |
55 | RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); | 95 | + dynamic_decoders = g_ptr_array_sized_new(decoder_table_size); |
56 | + target_ulong pc; | 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 | + } | ||
57 | + | 103 | + |
58 | + if (tb_cflags(tb) & CF_PCREL) { | 104 | + cpu->decoders = dynamic_decoders; |
59 | + pc = (env->pc & TARGET_PAGE_MASK) | data[0]; | 105 | +} |
60 | + } else { | ||
61 | + pc = data[0]; | ||
62 | + } | ||
63 | |||
64 | if (xl == MXL_RV32) { | ||
65 | - env->pc = (int32_t)data[0]; | ||
66 | + env->pc = (int32_t)pc; | ||
67 | } else { | ||
68 | - env->pc = data[0]; | ||
69 | + env->pc = pc; | ||
70 | } | ||
71 | env->bins = data[1]; | ||
72 | } | ||
73 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
74 | } | ||
75 | |||
76 | #ifndef CONFIG_USER_ONLY | ||
77 | + cs->tcg_cflags |= CF_PCREL; | ||
78 | + | 106 | + |
79 | if (cpu->cfg.ext_sstc) { | 107 | bool riscv_cpu_tcg_compatible(RISCVCPU *cpu) |
80 | riscv_timer_init(cpu); | 108 | { |
81 | } | 109 | return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL; |
82 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 110 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c |
83 | index XXXXXXX..XXXXXXX 100644 | 111 | index XXXXXXX..XXXXXXX 100644 |
84 | --- a/target/riscv/translate.c | 112 | --- a/target/riscv/translate.c |
85 | +++ b/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 */ | ||
86 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | 123 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { |
87 | /* pc_succ_insn points to the instruction following base.pc_next */ | 124 | /* FRM is known to contain a valid value. */ |
88 | target_ulong pc_succ_insn; | 125 | bool frm_valid; |
89 | target_ulong cur_insn_len; | 126 | bool insn_start_updated; |
90 | + target_ulong pc_save; | 127 | + const GPtrArray *decoders; |
91 | target_ulong priv_ver; | 128 | } DisasContext; |
92 | RISCVMXL misa_mxl_max; | 129 | |
93 | RISCVMXL xl; | 130 | static inline bool has_ext(DisasContext *ctx, uint32_t ext) |
94 | @@ -XXX,XX +XXX,XX @@ static void gen_pc_plus_diff(TCGv target, DisasContext *ctx, | 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) | ||
95 | { | 144 | { |
96 | target_ulong dest = ctx->base.pc_next + diff; | 145 | - /* |
97 | 146 | - * A table with predicate (i.e., guard) functions and decoder functions | |
98 | - if (get_xl(ctx) == MXL_RV32) { | 147 | - * that are tested in-order until a decoder matches onto the opcode. |
99 | - dest = (int32_t)dest; | 148 | - */ |
100 | + assert(ctx->pc_save != -1); | 149 | - static const struct { |
101 | + if (tb_cflags(ctx->base.tb) & CF_PCREL) { | 150 | - bool (*guard_func)(const RISCVCPUConfig *); |
102 | + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save); | 151 | - bool (*decode_func)(DisasContext *, uint32_t); |
103 | + if (get_xl(ctx) == MXL_RV32) { | 152 | - } decoders[] = { |
104 | + tcg_gen_ext32s_tl(target, target); | 153 | - { always_true_p, decode_insn32 }, |
105 | + } | 154 | - { has_xthead_p, decode_xthead }, |
106 | + } else { | 155 | - { has_XVentanaCondOps_p, decode_XVentanaCodeOps }, |
107 | + if (get_xl(ctx) == MXL_RV32) { | 156 | - }; |
108 | + dest = (int32_t)dest; | 157 | - |
109 | + } | 158 | ctx->virt_inst_excp = false; |
110 | + tcg_gen_movi_tl(target, dest); | 159 | ctx->cur_insn_len = insn_len(opcode); |
111 | } | 160 | /* Check for compressed insn */ |
112 | - tcg_gen_movi_tl(target, dest); | 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; | ||
113 | } | 179 | } |
114 | 180 | ||
115 | static void gen_update_pc(DisasContext *ctx, target_long diff) | 181 | static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu) |
116 | { | ||
117 | gen_pc_plus_diff(cpu_pc, ctx, diff); | ||
118 | + ctx->pc_save = ctx->base.pc_next + diff; | ||
119 | } | ||
120 | |||
121 | static void generate_exception(DisasContext *ctx, int excp) | ||
122 | @@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_long diff) | ||
123 | * direct block chain benefits will be small. | ||
124 | */ | ||
125 | if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) { | ||
126 | - tcg_gen_goto_tb(n); | ||
127 | - gen_update_pc(ctx, diff); | ||
128 | + /* | ||
129 | + * For pcrel, the pc must always be up-to-date on entry to | ||
130 | + * the linked TB, so that it can use simple additions for all | ||
131 | + * further adjustments. For !pcrel, the linked TB is compiled | ||
132 | + * to know its full virtual address, so we can delay the | ||
133 | + * update to pc to the unlinked path. A long chain of links | ||
134 | + * can thus avoid many updates to the PC. | ||
135 | + */ | ||
136 | + if (tb_cflags(ctx->base.tb) & CF_PCREL) { | ||
137 | + gen_update_pc(ctx, diff); | ||
138 | + tcg_gen_goto_tb(n); | ||
139 | + } else { | ||
140 | + tcg_gen_goto_tb(n); | ||
141 | + gen_update_pc(ctx, diff); | ||
142 | + } | ||
143 | tcg_gen_exit_tb(ctx->base.tb, n); | ||
144 | } else { | ||
145 | gen_update_pc(ctx, diff); | ||
146 | @@ -XXX,XX +XXX,XX @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t) | ||
147 | |||
148 | static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
149 | { | ||
150 | + TCGv succ_pc = dest_gpr(ctx, rd); | ||
151 | + | ||
152 | /* check misaligned: */ | ||
153 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
154 | if ((imm & 0x3) != 0) { | ||
155 | @@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
156 | } | ||
157 | } | ||
158 | |||
159 | - gen_set_gpri(ctx, rd, ctx->pc_succ_insn); | ||
160 | + gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len); | ||
161 | + gen_set_gpr(ctx, rd, succ_pc); | ||
162 | + | ||
163 | gen_goto_tb(ctx, 0, imm); /* must use this for safety */ | ||
164 | ctx->base.is_jmp = DISAS_NORETURN; | ||
165 | } | ||
166 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
167 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
168 | uint32_t tb_flags = ctx->base.tb->flags; | ||
169 | |||
170 | + ctx->pc_save = ctx->base.pc_first; | ||
171 | ctx->pc_succ_insn = ctx->base.pc_first; | ||
172 | ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV); | ||
173 | ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX); | ||
174 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu) | ||
175 | static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) | ||
176 | { | ||
177 | DisasContext *ctx = container_of(dcbase, DisasContext, base); | ||
178 | + target_ulong pc_next = ctx->base.pc_next; | ||
179 | + | ||
180 | + if (tb_cflags(dcbase->tb) & CF_PCREL) { | ||
181 | + pc_next &= ~TARGET_PAGE_MASK; | ||
182 | + } | ||
183 | |||
184 | - tcg_gen_insn_start(ctx->base.pc_next, 0); | ||
185 | + tcg_gen_insn_start(pc_next, 0); | ||
186 | ctx->insn_start = tcg_last_op(); | ||
187 | } | ||
188 | |||
189 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
190 | index XXXXXXX..XXXXXXX 100644 | ||
191 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
192 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
193 | @@ -XXX,XX +XXX,XX @@ static bool trans_lui(DisasContext *ctx, arg_lui *a) | ||
194 | |||
195 | static bool trans_auipc(DisasContext *ctx, arg_auipc *a) | ||
196 | { | ||
197 | - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next); | ||
198 | + TCGv target_pc = dest_gpr(ctx, a->rd); | ||
199 | + gen_pc_plus_diff(target_pc, ctx, a->imm); | ||
200 | + gen_set_gpr(ctx, a->rd, target_pc); | ||
201 | return true; | ||
202 | } | ||
203 | |||
204 | @@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
205 | { | ||
206 | TCGLabel *misaligned = NULL; | ||
207 | TCGv target_pc = tcg_temp_new(); | ||
208 | + TCGv succ_pc = dest_gpr(ctx, a->rd); | ||
209 | |||
210 | tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm); | ||
211 | tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2); | ||
212 | @@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
213 | tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned); | ||
214 | } | ||
215 | |||
216 | - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn); | ||
217 | + gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len); | ||
218 | + gen_set_gpr(ctx, a->rd, succ_pc); | ||
219 | + | ||
220 | tcg_gen_mov_tl(cpu_pc, target_pc); | ||
221 | lookup_and_goto_ptr(ctx); | ||
222 | |||
223 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
224 | TCGLabel *l = gen_new_label(); | ||
225 | TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
226 | TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN); | ||
227 | + target_ulong orig_pc_save = ctx->pc_save; | ||
228 | |||
229 | if (get_xl(ctx) == MXL_RV128) { | ||
230 | TCGv src1h = get_gprh(ctx, a->rs1); | ||
231 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
232 | tcg_gen_brcond_tl(cond, src1, src2, l); | ||
233 | } | ||
234 | gen_goto_tb(ctx, 1, ctx->cur_insn_len); | ||
235 | + ctx->pc_save = orig_pc_save; | ||
236 | |||
237 | gen_set_label(l); /* branch taken */ | ||
238 | |||
239 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
240 | } else { | ||
241 | gen_goto_tb(ctx, 0, a->imm); | ||
242 | } | ||
243 | + ctx->pc_save = -1; | ||
244 | ctx->base.is_jmp = DISAS_NORETURN; | ||
245 | |||
246 | return true; | ||
247 | diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
248 | index XXXXXXX..XXXXXXX 100644 | ||
249 | --- a/target/riscv/insn_trans/trans_rvzce.c.inc | ||
250 | +++ b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
251 | @@ -XXX,XX +XXX,XX @@ static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a) | ||
252 | |||
253 | /* c.jt vs c.jalt depends on the index. */ | ||
254 | if (a->index >= 32) { | ||
255 | - gen_set_gpri(ctx, xRA, ctx->pc_succ_insn); | ||
256 | + TCGv succ_pc = dest_gpr(ctx, xRA); | ||
257 | + gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len); | ||
258 | + gen_set_gpr(ctx, xRA, succ_pc); | ||
259 | } | ||
260 | |||
261 | tcg_gen_lookup_and_goto_ptr(); | ||
262 | -- | 182 | -- |
263 | 2.40.1 | 183 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Christoph Müllner <christoph.muellner@vrull.eu> |
---|---|---|---|
2 | 2 | ||
3 | Split RISCVCPUConfig declarations to prepare for passing it to disas. | 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 | ||
4 | 6 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | An important property of this patch is, that the th.sxstatus MAEE field |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 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> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 21 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 22 | Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> |
9 | Message-Id: <20230523093539.203909-3-liweiwei@iscas.ac.cn> | 23 | Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 25 | --- |
12 | target/riscv/cpu.h | 114 +--------------------------------- | 26 | MAINTAINERS | 1 + |
13 | target/riscv/cpu_cfg.h | 136 +++++++++++++++++++++++++++++++++++++++++ | 27 | target/riscv/cpu.h | 3 ++ |
14 | 2 files changed, 137 insertions(+), 113 deletions(-) | 28 | target/riscv/cpu.c | 1 + |
15 | create mode 100644 target/riscv/cpu_cfg.h | 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 | ||
16 | 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 | ||
17 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 46 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
18 | index XXXXXXX..XXXXXXX 100644 | 47 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu.h | 48 | --- a/target/riscv/cpu.h |
20 | +++ b/target/riscv/cpu.h | 49 | +++ b/target/riscv/cpu.h |
21 | @@ -XXX,XX +XXX,XX @@ | 50 | @@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value, |
22 | #include "qom/object.h" | 51 | uint8_t satp_mode_max_from_map(uint32_t map); |
23 | #include "qemu/int128.h" | 52 | const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit); |
24 | #include "cpu_bits.h" | 53 | |
25 | +#include "cpu_cfg.h" | 54 | +/* Implemented in th_csr.c */ |
26 | #include "qapi/qapi-types-common.h" | 55 | +void th_register_custom_csrs(RISCVCPU *cpu); |
27 | #include "cpu-qom.h" | 56 | + |
28 | 57 | #endif /* RISCV_CPU_H */ | |
29 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | 58 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
30 | uint64_t kvm_timer_frequency; | 59 | index XXXXXXX..XXXXXXX 100644 |
31 | }; | 60 | --- a/target/riscv/cpu.c |
32 | 61 | +++ b/target/riscv/cpu.c | |
33 | -/* | 62 | @@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj) |
34 | - * map is a 16-bit bitmap: the most significant set bit in map is the maximum | 63 | cpu->cfg.mvendorid = THEAD_VENDOR_ID; |
35 | - * satp mode that is supported. It may be chosen by the user and must respect | 64 | #ifndef CONFIG_USER_ONLY |
36 | - * what qemu implements (valid_1_10_32/64) and what the hw is capable of | 65 | set_satp_mode_max_supported(cpu, VM_1_10_SV39); |
37 | - * (supported bitmap below). | 66 | + th_register_custom_csrs(cpu); |
38 | - * | 67 | #endif |
39 | - * init is a 16-bit bitmap used to make sure the user selected a correct | 68 | |
40 | - * configuration as per the specification. | 69 | /* inherited from parent obj via riscv_cpu_init() */ |
41 | - * | 70 | diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c |
42 | - * supported is a 16-bit bitmap used to reflect the hw capabilities. | ||
43 | - */ | ||
44 | -typedef struct { | ||
45 | - uint16_t map, init, supported; | ||
46 | -} RISCVSATPMap; | ||
47 | - | ||
48 | -struct RISCVCPUConfig { | ||
49 | - bool ext_zba; | ||
50 | - bool ext_zbb; | ||
51 | - bool ext_zbc; | ||
52 | - bool ext_zbkb; | ||
53 | - bool ext_zbkc; | ||
54 | - bool ext_zbkx; | ||
55 | - bool ext_zbs; | ||
56 | - bool ext_zca; | ||
57 | - bool ext_zcb; | ||
58 | - bool ext_zcd; | ||
59 | - bool ext_zce; | ||
60 | - bool ext_zcf; | ||
61 | - bool ext_zcmp; | ||
62 | - bool ext_zcmt; | ||
63 | - bool ext_zk; | ||
64 | - bool ext_zkn; | ||
65 | - bool ext_zknd; | ||
66 | - bool ext_zkne; | ||
67 | - bool ext_zknh; | ||
68 | - bool ext_zkr; | ||
69 | - bool ext_zks; | ||
70 | - bool ext_zksed; | ||
71 | - bool ext_zksh; | ||
72 | - bool ext_zkt; | ||
73 | - bool ext_ifencei; | ||
74 | - bool ext_icsr; | ||
75 | - bool ext_icbom; | ||
76 | - bool ext_icboz; | ||
77 | - bool ext_zicond; | ||
78 | - bool ext_zihintpause; | ||
79 | - bool ext_smstateen; | ||
80 | - bool ext_sstc; | ||
81 | - bool ext_svadu; | ||
82 | - bool ext_svinval; | ||
83 | - bool ext_svnapot; | ||
84 | - bool ext_svpbmt; | ||
85 | - bool ext_zdinx; | ||
86 | - bool ext_zawrs; | ||
87 | - bool ext_zfh; | ||
88 | - bool ext_zfhmin; | ||
89 | - bool ext_zfinx; | ||
90 | - bool ext_zhinx; | ||
91 | - bool ext_zhinxmin; | ||
92 | - bool ext_zve32f; | ||
93 | - bool ext_zve64f; | ||
94 | - bool ext_zve64d; | ||
95 | - bool ext_zmmul; | ||
96 | - bool ext_zvfh; | ||
97 | - bool ext_zvfhmin; | ||
98 | - bool ext_smaia; | ||
99 | - bool ext_ssaia; | ||
100 | - bool ext_sscofpmf; | ||
101 | - bool rvv_ta_all_1s; | ||
102 | - bool rvv_ma_all_1s; | ||
103 | - | ||
104 | - uint32_t mvendorid; | ||
105 | - uint64_t marchid; | ||
106 | - uint64_t mimpid; | ||
107 | - | ||
108 | - /* Vendor-specific custom extensions */ | ||
109 | - bool ext_xtheadba; | ||
110 | - bool ext_xtheadbb; | ||
111 | - bool ext_xtheadbs; | ||
112 | - bool ext_xtheadcmo; | ||
113 | - bool ext_xtheadcondmov; | ||
114 | - bool ext_xtheadfmemidx; | ||
115 | - bool ext_xtheadfmv; | ||
116 | - bool ext_xtheadmac; | ||
117 | - bool ext_xtheadmemidx; | ||
118 | - bool ext_xtheadmempair; | ||
119 | - bool ext_xtheadsync; | ||
120 | - bool ext_XVentanaCondOps; | ||
121 | - | ||
122 | - uint8_t pmu_num; | ||
123 | - char *priv_spec; | ||
124 | - char *user_spec; | ||
125 | - char *bext_spec; | ||
126 | - char *vext_spec; | ||
127 | - uint16_t vlen; | ||
128 | - uint16_t elen; | ||
129 | - uint16_t cbom_blocksize; | ||
130 | - uint16_t cboz_blocksize; | ||
131 | - bool mmu; | ||
132 | - bool pmp; | ||
133 | - bool epmp; | ||
134 | - bool debug; | ||
135 | - bool misa_w; | ||
136 | - | ||
137 | - bool short_isa_string; | ||
138 | - | ||
139 | -#ifndef CONFIG_USER_ONLY | ||
140 | - RISCVSATPMap satp_mode; | ||
141 | -#endif | ||
142 | -}; | ||
143 | - | ||
144 | -typedef struct RISCVCPUConfig RISCVCPUConfig; | ||
145 | - | ||
146 | /* | ||
147 | * RISCVCPU: | ||
148 | * @env: #CPURISCVState | ||
149 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
150 | new file mode 100644 | 71 | new file mode 100644 |
151 | index XXXXXXX..XXXXXXX | 72 | index XXXXXXX..XXXXXXX |
152 | --- /dev/null | 73 | --- /dev/null |
153 | +++ b/target/riscv/cpu_cfg.h | 74 | +++ b/target/riscv/th_csr.c |
154 | @@ -XXX,XX +XXX,XX @@ | 75 | @@ -XXX,XX +XXX,XX @@ |
155 | +/* | 76 | +/* |
156 | + * QEMU RISC-V CPU CFG | 77 | + * T-Head-specific CSRs. |
157 | + * | 78 | + * |
158 | + * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu | 79 | + * Copyright (c) 2024 VRULL GmbH |
159 | + * Copyright (c) 2017-2018 SiFive, Inc. | ||
160 | + * Copyright (c) 2021-2023 PLCT Lab | ||
161 | + * | 80 | + * |
162 | + * This program is free software; you can redistribute it and/or modify it | 81 | + * This program is free software; you can redistribute it and/or modify it |
163 | + * under the terms and conditions of the GNU General Public License, | 82 | + * under the terms and conditions of the GNU General Public License, |
164 | + * version 2 or later, as published by the Free Software Foundation. | 83 | + * version 2 or later, as published by the Free Software Foundation. |
165 | + * | 84 | + * |
... | ... | ||
170 | + * | 89 | + * |
171 | + * You should have received a copy of the GNU General Public License along with | 90 | + * You should have received a copy of the GNU General Public License along with |
172 | + * this program. If not, see <http://www.gnu.org/licenses/>. | 91 | + * this program. If not, see <http://www.gnu.org/licenses/>. |
173 | + */ | 92 | + */ |
174 | + | 93 | + |
175 | +#ifndef RISCV_CPU_CFG_H | 94 | +#include "qemu/osdep.h" |
176 | +#define RISCV_CPU_CFG_H | 95 | +#include "cpu.h" |
96 | +#include "cpu_vendorid.h" | ||
177 | + | 97 | + |
178 | +/* | 98 | +#define CSR_TH_SXSTATUS 0x5c0 |
179 | + * map is a 16-bit bitmap: the most significant set bit in map is the maximum | 99 | + |
180 | + * satp mode that is supported. It may be chosen by the user and must respect | 100 | +/* TH_SXSTATUS bits */ |
181 | + * what qemu implements (valid_1_10_32/64) and what the hw is capable of | 101 | +#define TH_SXSTATUS_UCME BIT(16) |
182 | + * (supported bitmap below). | 102 | +#define TH_SXSTATUS_MAEE BIT(21) |
183 | + * | 103 | +#define TH_SXSTATUS_THEADISAEE BIT(22) |
184 | + * init is a 16-bit bitmap used to make sure the user selected a correct | 104 | + |
185 | + * configuration as per the specification. | ||
186 | + * | ||
187 | + * supported is a 16-bit bitmap used to reflect the hw capabilities. | ||
188 | + */ | ||
189 | +typedef struct { | 105 | +typedef struct { |
190 | + uint16_t map, init, supported; | 106 | + int csrno; |
191 | +} RISCVSATPMap; | 107 | + int (*insertion_test)(RISCVCPU *cpu); |
108 | + riscv_csr_operations csr_ops; | ||
109 | +} riscv_csr; | ||
192 | + | 110 | + |
193 | +struct RISCVCPUConfig { | 111 | +static RISCVException smode(CPURISCVState *env, int csrno) |
194 | + bool ext_zba; | 112 | +{ |
195 | + bool ext_zbb; | 113 | + if (riscv_has_ext(env, RVS)) { |
196 | + bool ext_zbc; | 114 | + return RISCV_EXCP_NONE; |
197 | + bool ext_zbkb; | 115 | + } |
198 | + bool ext_zbkc; | ||
199 | + bool ext_zbkx; | ||
200 | + bool ext_zbs; | ||
201 | + bool ext_zca; | ||
202 | + bool ext_zcb; | ||
203 | + bool ext_zcd; | ||
204 | + bool ext_zce; | ||
205 | + bool ext_zcf; | ||
206 | + bool ext_zcmp; | ||
207 | + bool ext_zcmt; | ||
208 | + bool ext_zk; | ||
209 | + bool ext_zkn; | ||
210 | + bool ext_zknd; | ||
211 | + bool ext_zkne; | ||
212 | + bool ext_zknh; | ||
213 | + bool ext_zkr; | ||
214 | + bool ext_zks; | ||
215 | + bool ext_zksed; | ||
216 | + bool ext_zksh; | ||
217 | + bool ext_zkt; | ||
218 | + bool ext_ifencei; | ||
219 | + bool ext_icsr; | ||
220 | + bool ext_icbom; | ||
221 | + bool ext_icboz; | ||
222 | + bool ext_zicond; | ||
223 | + bool ext_zihintpause; | ||
224 | + bool ext_smstateen; | ||
225 | + bool ext_sstc; | ||
226 | + bool ext_svadu; | ||
227 | + bool ext_svinval; | ||
228 | + bool ext_svnapot; | ||
229 | + bool ext_svpbmt; | ||
230 | + bool ext_zdinx; | ||
231 | + bool ext_zawrs; | ||
232 | + bool ext_zfh; | ||
233 | + bool ext_zfhmin; | ||
234 | + bool ext_zfinx; | ||
235 | + bool ext_zhinx; | ||
236 | + bool ext_zhinxmin; | ||
237 | + bool ext_zve32f; | ||
238 | + bool ext_zve64f; | ||
239 | + bool ext_zve64d; | ||
240 | + bool ext_zmmul; | ||
241 | + bool ext_zvfh; | ||
242 | + bool ext_zvfhmin; | ||
243 | + bool ext_smaia; | ||
244 | + bool ext_ssaia; | ||
245 | + bool ext_sscofpmf; | ||
246 | + bool rvv_ta_all_1s; | ||
247 | + bool rvv_ma_all_1s; | ||
248 | + | 116 | + |
249 | + uint32_t mvendorid; | 117 | + return RISCV_EXCP_ILLEGAL_INST; |
250 | + uint64_t marchid; | 118 | +} |
251 | + uint64_t mimpid; | ||
252 | + | 119 | + |
253 | + /* Vendor-specific custom extensions */ | 120 | +static int test_thead_mvendorid(RISCVCPU *cpu) |
254 | + bool ext_xtheadba; | 121 | +{ |
255 | + bool ext_xtheadbb; | 122 | + if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) { |
256 | + bool ext_xtheadbs; | 123 | + return -1; |
257 | + bool ext_xtheadcmo; | 124 | + } |
258 | + bool ext_xtheadcondmov; | ||
259 | + bool ext_xtheadfmemidx; | ||
260 | + bool ext_xtheadfmv; | ||
261 | + bool ext_xtheadmac; | ||
262 | + bool ext_xtheadmemidx; | ||
263 | + bool ext_xtheadmempair; | ||
264 | + bool ext_xtheadsync; | ||
265 | + bool ext_XVentanaCondOps; | ||
266 | + | 125 | + |
267 | + uint8_t pmu_num; | 126 | + return 0; |
268 | + char *priv_spec; | 127 | +} |
269 | + char *user_spec; | ||
270 | + char *bext_spec; | ||
271 | + char *vext_spec; | ||
272 | + uint16_t vlen; | ||
273 | + uint16_t elen; | ||
274 | + uint16_t cbom_blocksize; | ||
275 | + uint16_t cboz_blocksize; | ||
276 | + bool mmu; | ||
277 | + bool pmp; | ||
278 | + bool epmp; | ||
279 | + bool debug; | ||
280 | + bool misa_w; | ||
281 | + | 128 | + |
282 | + bool short_isa_string; | 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 | +} | ||
283 | + | 136 | + |
284 | +#ifndef CONFIG_USER_ONLY | 137 | +static riscv_csr th_csr_list[] = { |
285 | + RISCVSATPMap satp_mode; | 138 | + { |
286 | +#endif | 139 | + .csrno = CSR_TH_SXSTATUS, |
140 | + .insertion_test = test_thead_mvendorid, | ||
141 | + .csr_ops = { "th.sxstatus", smode, read_th_sxstatus } | ||
142 | + } | ||
287 | +}; | 143 | +}; |
288 | + | 144 | + |
289 | +typedef struct RISCVCPUConfig RISCVCPUConfig; | 145 | +void th_register_custom_csrs(RISCVCPU *cpu) |
290 | +#endif | 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 | )) | ||
291 | -- | 167 | -- |
292 | 2.40.1 | 168 | 2.45.1 |
169 | |||
170 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Let's remove more code that is open coded in riscv_cpu_realize() and put | 3 | According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w |
4 | it into a helper. Let's also add an error message instead of just | 4 | instructions will be affected by Zvfhmin extension. |
5 | asserting out if env->misa_mxl_max != env->misa_mlx. | 5 | And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the |
6 | conversions of | ||
6 | 7 | ||
7 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 8 | * From 1*SEW(16/32) to 2*SEW(32/64) |
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 9 | * From 2*SEW(32/64) to 1*SEW(16/32) |
9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 10 | |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Max Chou <max.chou@sifive.com> |
11 | Message-Id: <20230517135714.211809-9-dbarboza@ventanamicro.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> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 16 | --- |
14 | target/riscv/cpu.c | 50 ++++++++++++++++++++++++++++++---------------- | 17 | target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++-- |
15 | 1 file changed, 33 insertions(+), 17 deletions(-) | 18 | 1 file changed, 18 insertions(+), 2 deletions(-) |
16 | 19 | ||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 20 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
18 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu.c | 22 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
20 | +++ b/target/riscv/cpu.c | 23 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
21 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) | 24 | @@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s) |
22 | } | 25 | } |
23 | } | 26 | } |
24 | 27 | ||
25 | +static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) | 28 | +static bool require_rvfmin(DisasContext *s) |
26 | +{ | 29 | +{ |
27 | + RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); | 30 | + if (s->mstatus_fs == EXT_STATUS_DISABLED) { |
28 | + CPUClass *cc = CPU_CLASS(mcc); | 31 | + return false; |
29 | + CPURISCVState *env = &cpu->env; | ||
30 | + | ||
31 | + /* Validate that MISA_MXL is set properly. */ | ||
32 | + switch (env->misa_mxl_max) { | ||
33 | +#ifdef TARGET_RISCV64 | ||
34 | + case MXL_RV64: | ||
35 | + case MXL_RV128: | ||
36 | + cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; | ||
37 | + break; | ||
38 | +#endif | ||
39 | + case MXL_RV32: | ||
40 | + cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; | ||
41 | + break; | ||
42 | + default: | ||
43 | + g_assert_not_reached(); | ||
44 | + } | 32 | + } |
45 | + | 33 | + |
46 | + if (env->misa_mxl_max != env->misa_mxl) { | 34 | + switch (s->sew) { |
47 | + error_setg(errp, "misa_mxl_max must be equal to misa_mxl"); | 35 | + case MO_16: |
48 | + return; | 36 | + return s->cfg_ptr->ext_zvfhmin; |
37 | + case MO_32: | ||
38 | + return s->cfg_ptr->ext_zve32f; | ||
39 | + default: | ||
40 | + return false; | ||
49 | + } | 41 | + } |
50 | +} | 42 | +} |
51 | + | 43 | + |
52 | /* | 44 | static bool require_scale_rvf(DisasContext *s) |
53 | * Check consistency between chosen extensions while setting | 45 | { |
54 | * cpu->cfg accordingly. | 46 | if (s->mstatus_fs == EXT_STATUS_DISABLED) { |
55 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | 47 | @@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s) |
56 | RISCVCPU *cpu = RISCV_CPU(dev); | ||
57 | CPURISCVState *env = &cpu->env; | ||
58 | RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); | ||
59 | - CPUClass *cc = CPU_CLASS(mcc); | ||
60 | Error *local_err = NULL; | ||
61 | |||
62 | cpu_exec_realizefn(cs, &local_err); | ||
63 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
64 | return; | ||
65 | } | 48 | } |
66 | 49 | ||
67 | + riscv_cpu_validate_misa_mxl(cpu, &local_err); | 50 | switch (s->sew) { |
68 | + if (local_err != NULL) { | 51 | - case MO_8: |
69 | + error_propagate(errp, local_err); | 52 | - return s->cfg_ptr->ext_zvfhmin; |
70 | + return; | 53 | case MO_16: |
71 | + } | 54 | return s->cfg_ptr->ext_zve32f; |
72 | + | 55 | case MO_32: |
73 | riscv_cpu_validate_priv_spec(cpu, &local_err); | 56 | @@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a) |
74 | if (local_err != NULL) { | 57 | static bool opffv_widen_check(DisasContext *s, arg_rmr *a) |
75 | error_propagate(errp, local_err); | 58 | { |
76 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | 59 | return opfv_widen_check(s, a) && |
77 | } | 60 | + require_rvfmin(s) && |
78 | #endif /* CONFIG_USER_ONLY */ | 61 | require_scale_rvfmin(s) && |
79 | 62 | (s->sew != MO_8); | |
80 | - /* Validate that MISA_MXL is set properly. */ | 63 | } |
81 | - switch (env->misa_mxl_max) { | 64 | @@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a) |
82 | -#ifdef TARGET_RISCV64 | 65 | static bool opffv_narrow_check(DisasContext *s, arg_rmr *a) |
83 | - case MXL_RV64: | 66 | { |
84 | - case MXL_RV128: | 67 | return opfv_narrow_check(s, a) && |
85 | - cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; | 68 | + require_rvfmin(s) && |
86 | - break; | 69 | require_scale_rvfmin(s) && |
87 | -#endif | 70 | (s->sew != MO_8); |
88 | - case MXL_RV32: | 71 | } |
89 | - cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; | ||
90 | - break; | ||
91 | - default: | ||
92 | - g_assert_not_reached(); | ||
93 | - } | ||
94 | - assert(env->misa_mxl_max == env->misa_mxl); | ||
95 | - | ||
96 | riscv_cpu_validate_set_extensions(cpu, &local_err); | ||
97 | if (local_err != NULL) { | ||
98 | error_propagate(errp, local_err); | ||
99 | -- | 72 | -- |
100 | 2.40.1 | 73 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Currently, pflash devices can be configured only via -pflash | 3 | The require_scale_rvf function only checks the double width operator for |
4 | or -drive options. This is the legacy way and the | 4 | the vector floating point widen instructions, so most of the widen |
5 | better way is to use -blockdev as in other architectures. | 5 | checking functions need to add require_rvf for single width operator. |
6 | libvirt also has moved to use -blockdev method. | ||
7 | 6 | ||
8 | To support -blockdev option, pflash devices need to be | 7 | The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width |
9 | created in instance_init itself. So, update the code to | 8 | integer to double width float, so the opfxv_widen_check function doesn’t |
10 | move the virt_flash_create() to instance_init. Also, use | 9 | need require_rvf for the single width operator(integer). |
11 | standard interfaces to detect whether pflash0 is | ||
12 | configured or not. | ||
13 | 10 | ||
14 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 11 | Signed-off-by: Max Chou <max.chou@sifive.com> |
15 | Reported-by: Andrea Bolognani <abologna@redhat.com> | 12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
16 | Tested-by: Andrea Bolognani <abologna@redhat.com> | 13 | Cc: qemu-stable <qemu-stable@nongnu.org> |
17 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 14 | Message-ID: <20240322092600.1198921-3-max.chou@sifive.com> |
18 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | Message-Id: <20230601045910.18646-3-sunilvl@ventanamicro.com> | ||
20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
21 | --- | 16 | --- |
22 | hw/riscv/virt.c | 8 +++++--- | 17 | target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++ |
23 | 1 file changed, 5 insertions(+), 3 deletions(-) | 18 | 1 file changed, 5 insertions(+) |
24 | 19 | ||
25 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 20 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
26 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/hw/riscv/virt.c | 22 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
28 | +++ b/hw/riscv/virt.c | 23 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
29 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) | 24 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check) |
30 | const char *firmware_name = riscv_default_firmware_name(&s->soc[0]); | 25 | static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) |
31 | uint32_t fdt_load_addr; | ||
32 | uint64_t kernel_entry = 0; | ||
33 | + BlockBackend *pflash_blk0; | ||
34 | |||
35 | /* | ||
36 | * Only direct boot kernel is currently supported for KVM VM, | ||
37 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) | ||
38 | firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, | ||
39 | start_addr, NULL); | ||
40 | |||
41 | - if (drive_get(IF_PFLASH, 0, 0)) { | ||
42 | + pflash_blk0 = pflash_cfi01_get_blk(s->flash[0]); | ||
43 | + if (pflash_blk0) { | ||
44 | if (machine->firmware && !strcmp(machine->firmware, "none") && | ||
45 | !kvm_enabled()) { | ||
46 | /* | ||
47 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | ||
48 | sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base, | ||
49 | qdev_get_gpio_in(mmio_irqchip, RTC_IRQ)); | ||
50 | |||
51 | - virt_flash_create(s); | ||
52 | - | ||
53 | for (i = 0; i < ARRAY_SIZE(s->flash); i++) { | ||
54 | /* Map legacy -drive if=pflash to machine properties */ | ||
55 | pflash_cfi01_legacy_drive(s->flash[i], | ||
56 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_instance_init(Object *obj) | ||
57 | { | 26 | { |
58 | RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); | 27 | return require_rvv(s) && |
59 | 28 | + require_rvf(s) && | |
60 | + virt_flash_create(s); | 29 | require_scale_rvf(s) && |
61 | + | 30 | (s->sew != MO_8) && |
62 | s->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); | 31 | vext_check_isa_ill(s) && |
63 | s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); | 32 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check) |
64 | s->acpi = ON_OFF_AUTO_AUTO; | 33 | static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a) |
34 | { | ||
35 | return require_rvv(s) && | ||
36 | + require_rvf(s) && | ||
37 | require_scale_rvf(s) && | ||
38 | (s->sew != MO_8) && | ||
39 | vext_check_isa_ill(s) && | ||
40 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf) | ||
41 | static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a) | ||
42 | { | ||
43 | return require_rvv(s) && | ||
44 | + require_rvf(s) && | ||
45 | require_scale_rvf(s) && | ||
46 | (s->sew != MO_8) && | ||
47 | vext_check_isa_ill(s) && | ||
48 | @@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv) | ||
49 | static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a) | ||
50 | { | ||
51 | return require_rvv(s) && | ||
52 | + require_rvf(s) && | ||
53 | require_scale_rvf(s) && | ||
54 | (s->sew != MO_8) && | ||
55 | vext_check_isa_ill(s) && | ||
56 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check) | ||
57 | static bool freduction_widen_check(DisasContext *s, arg_rmrr *a) | ||
58 | { | ||
59 | return reduction_widen_check(s, a) && | ||
60 | + require_rvf(s) && | ||
61 | require_scale_rvf(s) && | ||
62 | (s->sew != MO_8); | ||
63 | } | ||
65 | -- | 64 | -- |
66 | 2.40.1 | 65 | 2.45.1 |
67 | 66 | ||
68 | 67 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Reduce reliance on absolute values(by passing pc difference) to | 3 | The opfv_narrow_check needs to check the single width float operator by |
4 | prepare for PC-relative translation. | 4 | require_rvf. |
5 | 5 | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 6 | Signed-off-by: Max Chou <max.chou@sifive.com> |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 8 | Cc: qemu-stable <qemu-stable@nongnu.org> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Message-ID: <20240322092600.1198921-4-max.chou@sifive.com> |
10 | Message-Id: <20230526072124.298466-5-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 11 | --- |
13 | target/riscv/translate.c | 10 +++++----- | 12 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + |
14 | target/riscv/insn_trans/trans_privileged.c.inc | 2 +- | 13 | 1 file changed, 1 insertion(+) |
15 | target/riscv/insn_trans/trans_rvi.c.inc | 6 +++--- | ||
16 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
17 | target/riscv/insn_trans/trans_rvzawrs.c.inc | 2 +- | ||
18 | target/riscv/insn_trans/trans_xthead.c.inc | 2 +- | ||
19 | 6 files changed, 13 insertions(+), 13 deletions(-) | ||
20 | 14 | ||
21 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/translate.c | ||
24 | +++ b/target/riscv/translate.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static void gen_pc_plus_diff(TCGv target, DisasContext *ctx, | ||
26 | tcg_gen_movi_tl(target, dest); | ||
27 | } | ||
28 | |||
29 | -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest) | ||
30 | +static void gen_update_pc(DisasContext *ctx, target_long diff) | ||
31 | { | ||
32 | - gen_pc_plus_diff(cpu_pc, ctx, dest); | ||
33 | + gen_pc_plus_diff(cpu_pc, ctx, ctx->base.pc_next + diff); | ||
34 | } | ||
35 | |||
36 | static void generate_exception(DisasContext *ctx, int excp) | ||
37 | { | ||
38 | - gen_set_pc_imm(ctx, ctx->base.pc_next); | ||
39 | + gen_update_pc(ctx, 0); | ||
40 | gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); | ||
41 | ctx->base.is_jmp = DISAS_NORETURN; | ||
42 | } | ||
43 | @@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_long diff) | ||
44 | */ | ||
45 | if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) { | ||
46 | tcg_gen_goto_tb(n); | ||
47 | - gen_set_pc_imm(ctx, dest); | ||
48 | + gen_update_pc(ctx, diff); | ||
49 | tcg_gen_exit_tb(ctx->base.tb, n); | ||
50 | } else { | ||
51 | - gen_set_pc_imm(ctx, dest); | ||
52 | + gen_update_pc(ctx, diff); | ||
53 | lookup_and_goto_ptr(ctx); | ||
54 | } | ||
55 | } | ||
56 | diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/target/riscv/insn_trans/trans_privileged.c.inc | ||
59 | +++ b/target/riscv/insn_trans/trans_privileged.c.inc | ||
60 | @@ -XXX,XX +XXX,XX @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a) | ||
61 | { | ||
62 | #ifndef CONFIG_USER_ONLY | ||
63 | decode_save_opc(ctx); | ||
64 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
65 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
66 | gen_helper_wfi(cpu_env); | ||
67 | return true; | ||
68 | #else | ||
69 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
70 | index XXXXXXX..XXXXXXX 100644 | ||
71 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
72 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
73 | @@ -XXX,XX +XXX,XX @@ static bool trans_pause(DisasContext *ctx, arg_pause *a) | ||
74 | * PAUSE is a no-op in QEMU, | ||
75 | * end the TB and return to main loop | ||
76 | */ | ||
77 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
78 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
79 | exit_tb(ctx); | ||
80 | ctx->base.is_jmp = DISAS_NORETURN; | ||
81 | |||
82 | @@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a) | ||
83 | * FENCE_I is a no-op in QEMU, | ||
84 | * however we need to end the translation block | ||
85 | */ | ||
86 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
87 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
88 | exit_tb(ctx); | ||
89 | ctx->base.is_jmp = DISAS_NORETURN; | ||
90 | return true; | ||
91 | @@ -XXX,XX +XXX,XX @@ static bool do_csr_post(DisasContext *ctx) | ||
92 | /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */ | ||
93 | decode_save_opc(ctx); | ||
94 | /* We may have changed important cpu state -- exit to main loop. */ | ||
95 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
96 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
97 | exit_tb(ctx); | ||
98 | ctx->base.is_jmp = DISAS_NORETURN; | ||
99 | return true; | ||
100 | 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 |
101 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
102 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | 17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
103 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | 18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
104 | @@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2) | 19 | @@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a) |
105 | gen_set_gpr(s, rd, dst); | 20 | static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a) |
106 | mark_vs_dirty(s); | 21 | { |
107 | 22 | return opfv_narrow_check(s, a) && | |
108 | - gen_set_pc_imm(s, s->pc_succ_insn); | 23 | + require_rvf(s) && |
109 | + gen_update_pc(s, s->cur_insn_len); | 24 | require_scale_rvf(s) && |
110 | lookup_and_goto_ptr(s); | 25 | (s->sew != MO_8); |
111 | s->base.is_jmp = DISAS_NORETURN; | ||
112 | return true; | ||
113 | @@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2) | ||
114 | gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
115 | gen_set_gpr(s, rd, dst); | ||
116 | mark_vs_dirty(s); | ||
117 | - gen_set_pc_imm(s, s->pc_succ_insn); | ||
118 | + gen_update_pc(s, s->cur_insn_len); | ||
119 | lookup_and_goto_ptr(s); | ||
120 | s->base.is_jmp = DISAS_NORETURN; | ||
121 | |||
122 | diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc | ||
123 | index XXXXXXX..XXXXXXX 100644 | ||
124 | --- a/target/riscv/insn_trans/trans_rvzawrs.c.inc | ||
125 | +++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc | ||
126 | @@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx) | ||
127 | /* Clear the load reservation (if any). */ | ||
128 | tcg_gen_movi_tl(load_res, -1); | ||
129 | |||
130 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
131 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
132 | tcg_gen_exit_tb(NULL, 0); | ||
133 | ctx->base.is_jmp = DISAS_NORETURN; | ||
134 | |||
135 | diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc | ||
136 | index XXXXXXX..XXXXXXX 100644 | ||
137 | --- a/target/riscv/insn_trans/trans_xthead.c.inc | ||
138 | +++ b/target/riscv/insn_trans/trans_xthead.c.inc | ||
139 | @@ -XXX,XX +XXX,XX @@ static void gen_th_sync_local(DisasContext *ctx) | ||
140 | * Emulate out-of-order barriers with pipeline flush | ||
141 | * by exiting the translation block. | ||
142 | */ | ||
143 | - gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
144 | + gen_update_pc(ctx, ctx->cur_insn_len); | ||
145 | tcg_gen_exit_tb(NULL, 0); | ||
146 | ctx->base.is_jmp = DISAS_NORETURN; | ||
147 | } | 26 | } |
148 | -- | 27 | -- |
149 | 2.40.1 | 28 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Xiao Wang <xiao.w.wang@intel.com> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Commit 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector | 3 | If the checking functions check both the single and double width |
4 | load / store instructions") added an extra check for LMUL fragmentation, | 4 | operators at the same time, then the single width operator checking |
5 | intended for setting the "rest tail elements" in the last register for a | 5 | functions (require_rvf[min]) will check whether the SEW is 8. |
6 | segment load insn. | ||
7 | 6 | ||
8 | Actually, the max_elements derived in vext_ld*() won't be a fraction of | 7 | Signed-off-by: Max Chou <max.chou@sifive.com> |
9 | vector register size, since the lmul encoded in desc is emul, which has | ||
10 | already been adjusted to 1 for LMUL fragmentation case by vext_get_emul() | ||
11 | in trans_rvv.c.inc, for ld_stride(), ld_us(), ld_index() and ldff(). | ||
12 | |||
13 | Besides, vext_get_emul() has also taken EEW/SEW into consideration, so no | ||
14 | need to call vext_get_total_elems() which would base on the emul to derive | ||
15 | another emul, the second emul would be incorrect when esz differs from sew. | ||
16 | |||
17 | Thus this patch removes the check for extra tail elements. | ||
18 | |||
19 | Fixes: 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector load / store instructions") | ||
20 | |||
21 | Signed-off-by: Xiao Wang <xiao.w.wang@intel.com> | ||
22 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
23 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 9 | Cc: qemu-stable <qemu-stable@nongnu.org> |
24 | Message-Id: <20230607091646.4049428-1-xiao.w.wang@intel.com> | 10 | Message-ID: <20240322092600.1198921-5-max.chou@sifive.com> |
25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
26 | --- | 12 | --- |
27 | target/riscv/vector_helper.c | 22 ++++++---------------- | 13 | target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------ |
28 | 1 file changed, 6 insertions(+), 16 deletions(-) | 14 | 1 file changed, 4 insertions(+), 12 deletions(-) |
29 | 15 | ||
30 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | 16 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
31 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/target/riscv/vector_helper.c | 18 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
33 | +++ b/target/riscv/vector_helper.c | 19 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
34 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw) | 20 | @@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) |
35 | GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl) | 21 | return require_rvv(s) && |
36 | GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq) | 22 | require_rvf(s) && |
37 | 23 | require_scale_rvf(s) && | |
38 | -static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl, | 24 | - (s->sew != MO_8) && |
39 | - void *vd, uint32_t desc, uint32_t nf, | 25 | vext_check_isa_ill(s) && |
40 | +static void vext_set_tail_elems_1s(target_ulong vl, void *vd, | 26 | vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm); |
41 | + uint32_t desc, uint32_t nf, | 27 | } |
42 | uint32_t esz, uint32_t max_elems) | 28 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a) |
29 | return require_rvv(s) && | ||
30 | require_rvf(s) && | ||
31 | require_scale_rvf(s) && | ||
32 | - (s->sew != MO_8) && | ||
33 | vext_check_isa_ill(s) && | ||
34 | vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
35 | } | ||
36 | @@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a) | ||
37 | return require_rvv(s) && | ||
38 | require_rvf(s) && | ||
39 | require_scale_rvf(s) && | ||
40 | - (s->sew != MO_8) && | ||
41 | vext_check_isa_ill(s) && | ||
42 | vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm); | ||
43 | } | ||
44 | @@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a) | ||
45 | return require_rvv(s) && | ||
46 | require_rvf(s) && | ||
47 | require_scale_rvf(s) && | ||
48 | - (s->sew != MO_8) && | ||
49 | vext_check_isa_ill(s) && | ||
50 | vext_check_dd(s, a->rd, a->rs2, a->vm); | ||
51 | } | ||
52 | @@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a) | ||
43 | { | 53 | { |
44 | - uint32_t total_elems, vlenb, registers_used; | 54 | return opfv_widen_check(s, a) && |
45 | uint32_t vta = vext_vta(desc); | 55 | require_rvfmin(s) && |
46 | int k; | 56 | - require_scale_rvfmin(s) && |
47 | 57 | - (s->sew != MO_8); | |
48 | @@ -XXX,XX +XXX,XX @@ static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl, | 58 | + require_scale_rvfmin(s); |
49 | return; | ||
50 | } | ||
51 | |||
52 | - total_elems = vext_get_total_elems(env, desc, esz); | ||
53 | - vlenb = riscv_cpu_cfg(env)->vlen >> 3; | ||
54 | - | ||
55 | for (k = 0; k < nf; ++k) { | ||
56 | vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz, | ||
57 | (k * max_elems + max_elems) * esz); | ||
58 | } | ||
59 | - | ||
60 | - if (nf * max_elems % total_elems != 0) { | ||
61 | - registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb; | ||
62 | - vext_set_elems_1s(vd, vta, (nf * max_elems) * esz, | ||
63 | - registers_used * vlenb); | ||
64 | - } | ||
65 | } | 59 | } |
66 | 60 | ||
67 | /* | 61 | #define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \ |
68 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | 62 | @@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a) |
69 | } | 63 | { |
70 | env->vstart = 0; | 64 | return opfv_narrow_check(s, a) && |
71 | 65 | require_rvfmin(s) && | |
72 | - vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems); | 66 | - require_scale_rvfmin(s) && |
73 | + vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems); | 67 | - (s->sew != MO_8); |
68 | + require_scale_rvfmin(s); | ||
74 | } | 69 | } |
75 | 70 | ||
76 | #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN) \ | 71 | static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a) |
77 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | 72 | { |
78 | } | 73 | return opfv_narrow_check(s, a) && |
79 | env->vstart = 0; | 74 | require_rvf(s) && |
80 | 75 | - require_scale_rvf(s) && | |
81 | - vext_set_tail_elems_1s(env, evl, vd, desc, nf, esz, max_elems); | 76 | - (s->sew != MO_8); |
82 | + vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems); | 77 | + require_scale_rvf(s); |
83 | } | 78 | } |
84 | 79 | ||
85 | /* | 80 | #define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \ |
86 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | 81 | @@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a) |
87 | } | 82 | { |
88 | env->vstart = 0; | 83 | return reduction_widen_check(s, a) && |
89 | 84 | require_rvf(s) && | |
90 | - vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems); | 85 | - require_scale_rvf(s) && |
91 | + vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems); | 86 | - (s->sew != MO_8); |
87 | + require_scale_rvf(s); | ||
92 | } | 88 | } |
93 | 89 | ||
94 | #define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN) \ | 90 | GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check) |
95 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
96 | } | ||
97 | env->vstart = 0; | ||
98 | |||
99 | - vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems); | ||
100 | + vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems); | ||
101 | } | ||
102 | |||
103 | #define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN) \ | ||
104 | -- | 91 | -- |
105 | 2.40.1 | 92 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | pmp_get_tlb_size can be separated from get_physical_address_pmp and is only | 3 | raise_mmu_exception(), as is today, is prioritizing guest page faults by |
4 | needed when ret == TRANSLATE_SUCCESS. | 4 | checking first if virt_enabled && !first_stage, and then considering the |
5 | regular inst/load/store faults. | ||
5 | 6 | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | There's no mention in the spec about guest page fault being a higher |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 8 | priority that PMP faults. In fact, privileged spec section 3.7.1 says: |
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 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") | ||
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 | Message-Id: <20230517091519.34439-3-liweiwei@iscas.ac.cn> | 31 | Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com> |
32 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 33 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 34 | --- |
13 | target/riscv/cpu_helper.c | 16 ++++++---------- | 35 | target/riscv/cpu_helper.c | 22 ++++++++++++---------- |
14 | 1 file changed, 6 insertions(+), 10 deletions(-) | 36 | 1 file changed, 12 insertions(+), 10 deletions(-) |
15 | 37 | ||
16 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | 38 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c |
17 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/cpu_helper.c | 40 | --- a/target/riscv/cpu_helper.c |
19 | +++ b/target/riscv/cpu_helper.c | 41 | +++ b/target/riscv/cpu_helper.c |
20 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) | 42 | @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, |
21 | * | 43 | |
22 | * @env: CPURISCVState | 44 | switch (access_type) { |
23 | * @prot: The returned protection attributes | 45 | case MMU_INST_FETCH: |
24 | - * @tlb_size: TLB page size containing addr. It could be modified after PMP | 46 | - if (env->virt_enabled && !first_stage) { |
25 | - * permission checking. NULL if not set TLB page for addr. | 47 | + if (pmp_violation) { |
26 | * @addr: The physical address to be checked permission | 48 | + cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT; |
27 | * @access_type: The type of MMU access | 49 | + } else if (env->virt_enabled && !first_stage) { |
28 | * @mode: Indicates current privilege level. | 50 | cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT; |
29 | */ | 51 | } else { |
30 | -static int get_physical_address_pmp(CPURISCVState *env, int *prot, | 52 | - cs->exception_index = pmp_violation ? |
31 | - target_ulong *tlb_size, hwaddr addr, | 53 | - RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT; |
32 | +static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr, | 54 | + cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT; |
33 | int size, MMUAccessType access_type, | ||
34 | int mode) | ||
35 | { | ||
36 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, | ||
37 | } | ||
38 | |||
39 | *prot = pmp_priv_to_page_prot(pmp_priv); | ||
40 | - if (tlb_size != NULL) { | ||
41 | - *tlb_size = pmp_get_tlb_size(env, addr); | ||
42 | - } | ||
43 | |||
44 | return TRANSLATE_SUCCESS; | ||
45 | } | ||
46 | @@ -XXX,XX +XXX,XX @@ restart: | ||
47 | } | 55 | } |
48 | 56 | break; | |
49 | int pmp_prot; | 57 | case MMU_DATA_LOAD: |
50 | - int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr, | 58 | - if (two_stage && !first_stage) { |
51 | + int pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr, | 59 | + if (pmp_violation) { |
52 | sizeof(target_ulong), | 60 | + cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT; |
53 | MMU_DATA_LOAD, PRV_S); | 61 | + } else if (two_stage && !first_stage) { |
54 | if (pmp_ret != TRANSLATE_SUCCESS) { | 62 | cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT; |
55 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | 63 | } else { |
56 | prot &= prot2; | 64 | - cs->exception_index = pmp_violation ? |
57 | 65 | - RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT; | |
58 | if (ret == TRANSLATE_SUCCESS) { | 66 | + cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT; |
59 | - ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa, | 67 | } |
60 | + ret = get_physical_address_pmp(env, &prot_pmp, pa, | 68 | break; |
61 | size, access_type, mode); | 69 | case MMU_DATA_STORE: |
62 | + tlb_size = pmp_get_tlb_size(env, pa); | 70 | - if (two_stage && !first_stage) { |
63 | 71 | + if (pmp_violation) { | |
64 | qemu_log_mask(CPU_LOG_MMU, | 72 | + cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT; |
65 | "%s PMP address=" HWADDR_FMT_plx " ret %d prot" | 73 | + } else if (two_stage && !first_stage) { |
66 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | 74 | cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT; |
67 | __func__, address, ret, pa, prot); | 75 | } else { |
68 | 76 | - cs->exception_index = pmp_violation ? | |
69 | if (ret == TRANSLATE_SUCCESS) { | 77 | - RISCV_EXCP_STORE_AMO_ACCESS_FAULT : |
70 | - ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa, | 78 | - RISCV_EXCP_STORE_PAGE_FAULT; |
71 | + ret = get_physical_address_pmp(env, &prot_pmp, pa, | 79 | + cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT; |
72 | size, access_type, mode); | 80 | } |
73 | + tlb_size = pmp_get_tlb_size(env, pa); | 81 | break; |
74 | 82 | default: | |
75 | qemu_log_mask(CPU_LOG_MMU, | ||
76 | "%s PMP address=" HWADDR_FMT_plx " ret %d prot" | ||
77 | -- | 83 | -- |
78 | 2.40.1 | 84 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Mayuresh Chitale <mchitale@ventanamicro.com> | 1 | From: Alexei Filippov <alexei.filippov@syntacore.com> |
---|---|---|---|
2 | 2 | ||
3 | When misa.F is 0 tb->flags.FS field is unused and can be used to save | 3 | Previous patch fixed the PMP priority in raise_mmu_exception() but we're still |
4 | the current state of smstateen0.FCSR check which is needed by the | 4 | setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage |
5 | floating point translation routines. | 5 | translation part, mtval2 will be set in case of successes 2 stage translation but |
6 | failed pmp check. | ||
6 | 7 | ||
7 | Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com> | 8 | In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2 |
9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 10 | should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest |
10 | Message-Id: <20230518175058.2772506-3-mchitale@ventanamicro.com> | 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> | ||
17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com> | ||
19 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 21 | --- |
13 | target/riscv/cpu_helper.c | 6 ++++++ | 22 | target/riscv/cpu_helper.c | 12 ++++++------ |
14 | target/riscv/insn_trans/trans_rvf.c.inc | 7 ++++--- | 23 | 1 file changed, 6 insertions(+), 6 deletions(-) |
15 | 2 files changed, 10 insertions(+), 3 deletions(-) | ||
16 | 24 | ||
17 | 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 |
18 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu_helper.c | 27 | --- a/target/riscv/cpu_helper.c |
20 | +++ b/target/riscv/cpu_helper.c | 28 | +++ b/target/riscv/cpu_helper.c |
21 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | 29 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, |
22 | vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS)); | 30 | __func__, pa, ret, prot_pmp, tlb_size); |
23 | } | 31 | |
24 | 32 | prot &= prot_pmp; | |
25 | + /* With Zfinx, floating point is enabled/disabled by Smstateen. */ | 33 | - } |
26 | + if (!riscv_has_ext(env, RVF)) { | 34 | - |
27 | + fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE) | 35 | - if (ret != TRANSLATE_SUCCESS) { |
28 | + ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED; | 36 | + } else { |
29 | + } | 37 | /* |
30 | + | 38 | * Guest physical address translation failed, this is a HS |
31 | if (cpu->cfg.debug && !icount_enabled()) { | 39 | * level exception |
32 | flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled); | 40 | */ |
33 | } | 41 | first_stage_error = false; |
34 | diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc | 42 | - env->guest_phys_fault_addr = (im_address | |
35 | index XXXXXXX..XXXXXXX 100644 | 43 | - (address & |
36 | --- a/target/riscv/insn_trans/trans_rvf.c.inc | 44 | - (TARGET_PAGE_SIZE - 1))) >> 2; |
37 | +++ b/target/riscv/insn_trans/trans_rvf.c.inc | 45 | + if (ret != TRANSLATE_PMP_FAIL) { |
38 | @@ -XXX,XX +XXX,XX @@ | 46 | + env->guest_phys_fault_addr = (im_address | |
39 | */ | 47 | + (address & |
40 | 48 | + (TARGET_PAGE_SIZE - 1))) >> 2; | |
41 | #define REQUIRE_FPU do {\ | 49 | + } |
42 | - if (ctx->mstatus_fs == EXT_STATUS_DISABLED) \ | 50 | } |
43 | - if (!ctx->cfg_ptr->ext_zfinx) \ | 51 | } |
44 | - return false; \ | 52 | } else { |
45 | + if (ctx->mstatus_fs == EXT_STATUS_DISABLED) { \ | ||
46 | + ctx->virt_inst_excp = ctx->virt_enabled && ctx->cfg_ptr->ext_zfinx; \ | ||
47 | + return false; \ | ||
48 | + } \ | ||
49 | } while (0) | ||
50 | |||
51 | #define REQUIRE_ZFINX_OR_F(ctx) do {\ | ||
52 | -- | 53 | -- |
53 | 2.40.1 | 54 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Rob Bradford <rbradford@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | Zc* extensions (version 1.0) are ratified. | 3 | This extension has now been ratified: |
4 | https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be | ||
5 | removed. | ||
4 | 6 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | Since this is now a ratified extension add it to the list of extensions |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 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> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 13 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 14 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
9 | Message-Id: <20230510030040.20528-1-liweiwei@iscas.ac.cn> | 15 | Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 17 | --- |
12 | target/riscv/cpu.c | 16 ++++++++-------- | 18 | target/riscv/cpu.c | 2 +- |
13 | 1 file changed, 8 insertions(+), 8 deletions(-) | 19 | target/riscv/tcg/tcg-cpu.c | 2 +- |
20 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
14 | 21 | ||
15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 22 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
16 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu.c | 24 | --- a/target/riscv/cpu.c |
18 | +++ b/target/riscv/cpu.c | 25 | +++ b/target/riscv/cpu.c |
19 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | 26 | @@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = { |
20 | 27 | MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), | |
21 | DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false), | 28 | MISA_EXT_INFO(RVV, "v", "Vector operations"), |
22 | 29 | MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), | |
23 | + DEFINE_PROP_BOOL("zca", RISCVCPU, cfg.ext_zca, false), | 30 | - MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)") |
24 | + DEFINE_PROP_BOOL("zcb", RISCVCPU, cfg.ext_zcb, false), | 31 | + MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)") |
25 | + DEFINE_PROP_BOOL("zcd", RISCVCPU, cfg.ext_zcd, false), | 32 | }; |
26 | + DEFINE_PROP_BOOL("zce", RISCVCPU, cfg.ext_zce, false), | 33 | |
27 | + DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false), | 34 | static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc) |
28 | + DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false), | 35 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
29 | + DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false), | 36 | index XXXXXXX..XXXXXXX 100644 |
30 | + | 37 | --- a/target/riscv/tcg/tcg-cpu.c |
31 | /* Vendor-specific custom extensions */ | 38 | +++ b/target/riscv/tcg/tcg-cpu.c |
32 | DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false), | 39 | @@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj) |
33 | DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false), | 40 | const RISCVCPUMultiExtConfig *prop; |
34 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | 41 | |
35 | /* These are experimental so mark with 'x-' */ | 42 | /* Enable RVG, RVJ and RVV that are disabled by default */ |
36 | DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false), | 43 | - riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV); |
37 | 44 | + riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV); | |
38 | - DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false), | 45 | |
39 | - DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false), | 46 | for (prop = riscv_cpu_extensions; prop && prop->name; prop++) { |
40 | - DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false), | 47 | isa_ext_update_enabled(cpu, prop->offset, true); |
41 | - DEFINE_PROP_BOOL("x-zce", RISCVCPU, cfg.ext_zce, false), | ||
42 | - DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false), | ||
43 | - DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false), | ||
44 | - DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false), | ||
45 | - | ||
46 | /* ePMP 0.9.3 */ | ||
47 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | ||
48 | DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false), | ||
49 | -- | 48 | -- |
50 | 2.40.1 | 49 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Alistair Francis <alistair23@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Even though Zca/Zcf/Zcd can be included by C/F/D, however, their priv | 3 | When running the instruction |
4 | version is higher than the priv version of C/F/D. So if we use check | ||
5 | for them instead of check for C/F/D totally, it will trigger new | ||
6 | problem when we try to disable the extensions based on the configured | ||
7 | priv version. | ||
8 | 4 | ||
9 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 5 | ``` |
10 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 6 | cbo.flush 0(x0) |
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | ``` |
12 | Message-Id: <20230517135714.211809-7-dbarboza@ventanamicro.com> | 8 | |
9 | QEMU would segfault. | ||
10 | |||
11 | The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0] | ||
12 | allocated. | ||
13 | |||
14 | In order to fix this let's use the existing get_address() | ||
15 | helper. This also has the benefit of performing pointer mask | ||
16 | calculations on the address specified in rs1. | ||
17 | |||
18 | The pointer masking specificiation specifically states: | ||
19 | |||
20 | """ | ||
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") | ||
30 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
31 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
32 | Message-ID: <20240514023910.301766-1-alistair.francis@wdc.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/translate.c | 5 +++-- | 35 | target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++---- |
16 | target/riscv/insn_trans/trans_rvd.c.inc | 12 +++++++----- | 36 | 1 file changed, 12 insertions(+), 4 deletions(-) |
17 | target/riscv/insn_trans/trans_rvf.c.inc | 14 ++++++++------ | ||
18 | target/riscv/insn_trans/trans_rvi.c.inc | 5 +++-- | ||
19 | 4 files changed, 21 insertions(+), 15 deletions(-) | ||
20 | 37 | ||
21 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 38 | diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc |
22 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/translate.c | 40 | --- a/target/riscv/insn_trans/trans_rvzicbo.c.inc |
24 | +++ b/target/riscv/translate.c | 41 | +++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc |
25 | @@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
26 | |||
27 | /* check misaligned: */ | ||
28 | next_pc = ctx->base.pc_next + imm; | ||
29 | - if (!ctx->cfg_ptr->ext_zca) { | ||
30 | + if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
31 | if ((next_pc & 0x3) != 0) { | ||
32 | gen_exception_inst_addr_mis(ctx); | ||
33 | return; | ||
34 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | ||
35 | * The Zca extension is added as way to refer to instructions in the C | ||
36 | * extension that do not include the floating-point loads and stores | ||
37 | */ | ||
38 | - if (ctx->cfg_ptr->ext_zca && decode_insn16(ctx, opcode)) { | ||
39 | + if ((has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zca) && | ||
40 | + decode_insn16(ctx, opcode)) { | ||
41 | return; | ||
42 | } | ||
43 | } else { | ||
44 | diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/target/riscv/insn_trans/trans_rvd.c.inc | ||
47 | +++ b/target/riscv/insn_trans/trans_rvd.c.inc | ||
48 | @@ -XXX,XX +XXX,XX @@ | 42 | @@ -XXX,XX +XXX,XX @@ |
49 | } \ | 43 | static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a) |
50 | } while (0) | ||
51 | |||
52 | -#define REQUIRE_ZCD(ctx) do { \ | ||
53 | - if (!ctx->cfg_ptr->ext_zcd) { \ | ||
54 | - return false; \ | ||
55 | +#define REQUIRE_ZCD_OR_DC(ctx) do { \ | ||
56 | + if (!ctx->cfg_ptr->ext_zcd) { \ | ||
57 | + if (!has_ext(ctx, RVD) || !has_ext(ctx, RVC)) { \ | ||
58 | + return false; \ | ||
59 | + } \ | ||
60 | } \ | ||
61 | } while (0) | ||
62 | |||
63 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) | ||
64 | |||
65 | static bool trans_c_fld(DisasContext *ctx, arg_fld *a) | ||
66 | { | 44 | { |
67 | - REQUIRE_ZCD(ctx); | 45 | REQUIRE_ZICBOM(ctx); |
68 | + REQUIRE_ZCD_OR_DC(ctx); | 46 | - gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]); |
69 | return trans_fld(ctx, a); | 47 | + TCGv src = get_address(ctx, a->rs1, 0); |
48 | + | ||
49 | + gen_helper_cbo_clean_flush(tcg_env, src); | ||
50 | return true; | ||
70 | } | 51 | } |
71 | 52 | ||
72 | static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a) | 53 | static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a) |
73 | { | 54 | { |
74 | - REQUIRE_ZCD(ctx); | 55 | REQUIRE_ZICBOM(ctx); |
75 | + REQUIRE_ZCD_OR_DC(ctx); | 56 | - gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]); |
76 | return trans_fsd(ctx, a); | 57 | + TCGv src = get_address(ctx, a->rs1, 0); |
58 | + | ||
59 | + gen_helper_cbo_clean_flush(tcg_env, src); | ||
60 | return true; | ||
77 | } | 61 | } |
78 | 62 | ||
79 | diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc | 63 | static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a) |
80 | index XXXXXXX..XXXXXXX 100644 | ||
81 | --- a/target/riscv/insn_trans/trans_rvf.c.inc | ||
82 | +++ b/target/riscv/insn_trans/trans_rvf.c.inc | ||
83 | @@ -XXX,XX +XXX,XX @@ | ||
84 | } \ | ||
85 | } while (0) | ||
86 | |||
87 | -#define REQUIRE_ZCF(ctx) do { \ | ||
88 | - if (!ctx->cfg_ptr->ext_zcf) { \ | ||
89 | - return false; \ | ||
90 | - } \ | ||
91 | +#define REQUIRE_ZCF_OR_FC(ctx) do { \ | ||
92 | + if (!ctx->cfg_ptr->ext_zcf) { \ | ||
93 | + if (!has_ext(ctx, RVF) || !has_ext(ctx, RVC)) { \ | ||
94 | + return false; \ | ||
95 | + } \ | ||
96 | + } \ | ||
97 | } while (0) | ||
98 | |||
99 | static bool trans_flw(DisasContext *ctx, arg_flw *a) | ||
100 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a) | ||
101 | |||
102 | static bool trans_c_flw(DisasContext *ctx, arg_flw *a) | ||
103 | { | 64 | { |
104 | - REQUIRE_ZCF(ctx); | 65 | REQUIRE_ZICBOM(ctx); |
105 | + REQUIRE_ZCF_OR_FC(ctx); | 66 | - gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]); |
106 | return trans_flw(ctx, a); | 67 | + TCGv src = get_address(ctx, a->rs1, 0); |
68 | + | ||
69 | + gen_helper_cbo_inval(tcg_env, src); | ||
70 | return true; | ||
107 | } | 71 | } |
108 | 72 | ||
109 | static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a) | 73 | static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a) |
110 | { | 74 | { |
111 | - REQUIRE_ZCF(ctx); | 75 | REQUIRE_ZICBOZ(ctx); |
112 | + REQUIRE_ZCF_OR_FC(ctx); | 76 | - gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]); |
113 | return trans_fsw(ctx, a); | 77 | + TCGv src = get_address(ctx, a->rs1, 0); |
78 | + | ||
79 | + gen_helper_cbo_zero(tcg_env, src); | ||
80 | return true; | ||
114 | } | 81 | } |
115 | |||
116 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
119 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
120 | @@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
121 | tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2); | ||
122 | |||
123 | gen_set_pc(ctx, cpu_pc); | ||
124 | - if (!ctx->cfg_ptr->ext_zca) { | ||
125 | + if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
126 | TCGv t0 = tcg_temp_new(); | ||
127 | |||
128 | misaligned = gen_new_label(); | ||
129 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
130 | |||
131 | gen_set_label(l); /* branch taken */ | ||
132 | |||
133 | - if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) { | ||
134 | + if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca && | ||
135 | + ((ctx->base.pc_next + a->imm) & 0x3)) { | ||
136 | /* misaligned */ | ||
137 | gen_exception_inst_addr_mis(ctx); | ||
138 | } else { | ||
139 | -- | 82 | -- |
140 | 2.40.1 | 83 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Himanshu Chauhan <hchauhan@ventanamicro.com> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | On an address match, skip checking for default permissions and return error | 3 | In AIA spec, each hart (or each hart within a group) has a unique hart |
4 | based on access defined in PMP configuration. | 4 | number to locate the memory pages of interrupt files in the address |
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. | ||
5 | 8 | ||
6 | v3 Changes: | 9 | However, if the largest hart number among groups is a power of 2, QEMU |
7 | o Removed explicit return of boolean value from comparision | 10 | will pass an inaccurate hart-index-bit setting to Linux. For example, when |
8 | of priv/allowed_priv | 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. | ||
9 | 14 | ||
10 | v2 Changes: | 15 | Additionally, a Linux patch[1] is necessary to correctly recover the hart |
11 | o Removed goto to return in place when address matches | 16 | index when the guest OS has only 1 hart, where the hart-index-bit is 0. |
12 | o Call pmp_hart_has_privs_default at the end of the loop | ||
13 | 17 | ||
14 | Fixes: 90b1fafce06 ("target/riscv: Smepmp: Skip applying default rules when address matches") | 18 | [1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/ |
15 | Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com> | 19 | |
16 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 20 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
17 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 21 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
18 | Message-Id: <20230605164548.715336-1-hchauhan@ventanamicro.com> | 22 | Cc: qemu-stable <qemu-stable@nongnu.org> |
23 | Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com> | ||
19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
20 | --- | 25 | --- |
21 | target/riscv/pmp.c | 10 ++-------- | 26 | target/riscv/kvm/kvm-cpu.c | 9 ++++++++- |
22 | 1 file changed, 2 insertions(+), 8 deletions(-) | 27 | 1 file changed, 8 insertions(+), 1 deletion(-) |
23 | 28 | ||
24 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | 29 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c |
25 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/target/riscv/pmp.c | 31 | --- a/target/riscv/kvm/kvm-cpu.c |
27 | +++ b/target/riscv/pmp.c | 32 | +++ b/target/riscv/kvm/kvm-cpu.c |
28 | @@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | 33 | @@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, |
29 | pmp_priv_t *allowed_privs, target_ulong mode) | ||
30 | { | ||
31 | int i = 0; | ||
32 | - bool ret = false; | ||
33 | int pmp_size = 0; | ||
34 | target_ulong s = 0; | ||
35 | target_ulong e = 0; | ||
36 | @@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
37 | * defined with PMP must be used. We shouldn't fallback on | ||
38 | * finding default privileges. | ||
39 | */ | ||
40 | - ret = true; | ||
41 | - break; | ||
42 | + return (privs & *allowed_privs) == privs; | ||
43 | } | 34 | } |
44 | } | 35 | } |
45 | 36 | ||
46 | /* No rule matched */ | 37 | - hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1; |
47 | - if (!ret) { | 38 | + |
48 | - ret = pmp_hart_has_privs_default(env, privs, allowed_privs, mode); | 39 | + if (max_hart_per_socket > 1) { |
49 | - } | 40 | + max_hart_per_socket--; |
50 | - | 41 | + hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1; |
51 | - return ret; | 42 | + } else { |
52 | + return pmp_hart_has_privs_default(env, privs, allowed_privs, mode); | 43 | + hart_bits = 0; |
53 | } | 44 | + } |
54 | 45 | + | |
55 | /* | 46 | ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
47 | KVM_DEV_RISCV_AIA_CONFIG_HART_BITS, | ||
48 | &hart_bits, true, NULL); | ||
56 | -- | 49 | -- |
57 | 2.40.1 | 50 | 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 setter is doing nothing special. Just set env->priv_ver directly. | 3 | Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length |
4 | in bytes, when in this context we want 'reg_width' as the length in | ||
5 | bits. | ||
4 | 6 | ||
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") | ||
5 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 20 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
6 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 21 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
7 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | 22 | Acked-by: Alex Bennée <alex.bennee@linaro.org> |
23 | Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 24 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-Id: <20230517135714.211809-4-dbarboza@ventanamicro.com> | 25 | Cc: qemu-stable <qemu-stable@nongnu.org> |
26 | Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 27 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 28 | --- |
12 | target/riscv/cpu.c | 29 ++++++++++++----------------- | 29 | target/riscv/gdbstub.c | 6 +++--- |
13 | 1 file changed, 12 insertions(+), 17 deletions(-) | 30 | 1 file changed, 3 insertions(+), 3 deletions(-) |
14 | 31 | ||
15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 32 | diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c |
16 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu.c | 34 | --- a/target/riscv/gdbstub.c |
18 | +++ b/target/riscv/cpu.c | 35 | +++ b/target/riscv/gdbstub.c |
19 | @@ -XXX,XX +XXX,XX @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) | 36 | @@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg) |
20 | env->misa_ext_mask = env->misa_ext = ext; | 37 | static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) |
21 | } | ||
22 | |||
23 | -static void set_priv_version(CPURISCVState *env, int priv_ver) | ||
24 | -{ | ||
25 | - env->priv_ver = priv_ver; | ||
26 | -} | ||
27 | - | ||
28 | #ifndef CONFIG_USER_ONLY | ||
29 | static uint8_t satp_mode_from_str(const char *satp_mode_str) | ||
30 | { | 38 | { |
31 | @@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj) | 39 | RISCVCPU *cpu = RISCV_CPU(cs); |
32 | VM_1_10_SV32 : VM_1_10_SV57); | 40 | - int reg_width = cpu->cfg.vlenb; |
33 | #endif | 41 | + int bitsize = cpu->cfg.vlenb << 3; |
34 | 42 | GDBFeatureBuilder builder; | |
35 | - set_priv_version(env, PRIV_VERSION_1_12_0); | 43 | int i; |
36 | + env->priv_ver = PRIV_VERSION_1_12_0; | 44 | |
37 | } | 45 | @@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) |
38 | 46 | ||
39 | #if defined(TARGET_RISCV64) | 47 | /* First define types and totals in a whole VL */ |
40 | @@ -XXX,XX +XXX,XX @@ static void rv64_base_cpu_init(Object *obj) | 48 | for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { |
41 | set_misa(env, MXL_RV64, 0); | 49 | - int count = reg_width / vec_lanes[i].size; |
42 | riscv_cpu_add_user_properties(obj); | 50 | + int count = bitsize / vec_lanes[i].size; |
43 | /* Set latest version of privileged specification */ | 51 | gdb_feature_builder_append_tag( |
44 | - set_priv_version(env, PRIV_VERSION_1_12_0); | 52 | &builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", |
45 | + env->priv_ver = PRIV_VERSION_1_12_0; | 53 | vec_lanes[i].id, vec_lanes[i].gdb_type, count); |
46 | #ifndef CONFIG_USER_ONLY | 54 | @@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) |
47 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); | 55 | /* Define vector registers */ |
48 | #endif | 56 | for (i = 0; i < 32; i++) { |
49 | @@ -XXX,XX +XXX,XX @@ static void rv64_sifive_u_cpu_init(Object *obj) | 57 | gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i), |
50 | { | 58 | - reg_width, i, "riscv_vector", "vector"); |
51 | CPURISCVState *env = &RISCV_CPU(obj)->env; | 59 | + bitsize, i, "riscv_vector", "vector"); |
52 | set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | ||
53 | - set_priv_version(env, PRIV_VERSION_1_10_0); | ||
54 | + env->priv_ver = PRIV_VERSION_1_10_0; | ||
55 | #ifndef CONFIG_USER_ONLY | ||
56 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); | ||
57 | #endif | ||
58 | @@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj) | ||
59 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
60 | |||
61 | set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); | ||
62 | - set_priv_version(env, PRIV_VERSION_1_10_0); | ||
63 | + env->priv_ver = PRIV_VERSION_1_10_0; | ||
64 | cpu->cfg.mmu = false; | ||
65 | #ifndef CONFIG_USER_ONLY | ||
66 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
67 | @@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj) | ||
68 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
69 | |||
70 | set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU); | ||
71 | - set_priv_version(env, PRIV_VERSION_1_11_0); | ||
72 | + env->priv_ver = PRIV_VERSION_1_11_0; | ||
73 | |||
74 | cpu->cfg.ext_zfh = true; | ||
75 | cpu->cfg.mmu = true; | ||
76 | @@ -XXX,XX +XXX,XX @@ static void rv128_base_cpu_init(Object *obj) | ||
77 | set_misa(env, MXL_RV128, 0); | ||
78 | riscv_cpu_add_user_properties(obj); | ||
79 | /* Set latest version of privileged specification */ | ||
80 | - set_priv_version(env, PRIV_VERSION_1_12_0); | ||
81 | + env->priv_ver = PRIV_VERSION_1_12_0; | ||
82 | #ifndef CONFIG_USER_ONLY | ||
83 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); | ||
84 | #endif | ||
85 | @@ -XXX,XX +XXX,XX @@ static void rv32_base_cpu_init(Object *obj) | ||
86 | set_misa(env, MXL_RV32, 0); | ||
87 | riscv_cpu_add_user_properties(obj); | ||
88 | /* Set latest version of privileged specification */ | ||
89 | - set_priv_version(env, PRIV_VERSION_1_12_0); | ||
90 | + env->priv_ver = PRIV_VERSION_1_12_0; | ||
91 | #ifndef CONFIG_USER_ONLY | ||
92 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); | ||
93 | #endif | ||
94 | @@ -XXX,XX +XXX,XX @@ static void rv32_sifive_u_cpu_init(Object *obj) | ||
95 | { | ||
96 | CPURISCVState *env = &RISCV_CPU(obj)->env; | ||
97 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | ||
98 | - set_priv_version(env, PRIV_VERSION_1_10_0); | ||
99 | + env->priv_ver = PRIV_VERSION_1_10_0; | ||
100 | #ifndef CONFIG_USER_ONLY | ||
101 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); | ||
102 | #endif | ||
103 | @@ -XXX,XX +XXX,XX @@ static void rv32_sifive_e_cpu_init(Object *obj) | ||
104 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
105 | |||
106 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); | ||
107 | - set_priv_version(env, PRIV_VERSION_1_10_0); | ||
108 | + env->priv_ver = PRIV_VERSION_1_10_0; | ||
109 | cpu->cfg.mmu = false; | ||
110 | #ifndef CONFIG_USER_ONLY | ||
111 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
112 | @@ -XXX,XX +XXX,XX @@ static void rv32_ibex_cpu_init(Object *obj) | ||
113 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
114 | |||
115 | set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); | ||
116 | - set_priv_version(env, PRIV_VERSION_1_11_0); | ||
117 | + env->priv_ver = PRIV_VERSION_1_11_0; | ||
118 | cpu->cfg.mmu = false; | ||
119 | #ifndef CONFIG_USER_ONLY | ||
120 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
121 | @@ -XXX,XX +XXX,XX @@ static void rv32_imafcu_nommu_cpu_init(Object *obj) | ||
122 | RISCVCPU *cpu = RISCV_CPU(obj); | ||
123 | |||
124 | set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); | ||
125 | - set_priv_version(env, PRIV_VERSION_1_10_0); | ||
126 | + env->priv_ver = PRIV_VERSION_1_10_0; | ||
127 | cpu->cfg.mmu = false; | ||
128 | #ifndef CONFIG_USER_ONLY | ||
129 | set_satp_mode_max_supported(cpu, VM_1_10_MBARE); | ||
130 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
131 | } | 60 | } |
132 | 61 | ||
133 | if (priv_version >= PRIV_VERSION_1_10_0) { | 62 | gdb_feature_builder_end(&builder); |
134 | - set_priv_version(env, priv_version); | ||
135 | + env->priv_ver = priv_version; | ||
136 | } | ||
137 | |||
138 | riscv_cpu_validate_misa_priv(env, &local_err); | ||
139 | -- | 63 | -- |
140 | 2.40.1 | 64 | 2.45.1 |
65 | |||
66 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Using implicitly enabled extensions such as Zca/Zcf/Zcd instead of their | ||
4 | super extensions can simplify the extension related check. However, they | ||
5 | may have higher priv version than their super extensions. So we should mask | ||
6 | them in the isa_string based on priv version to make them invisible to user | ||
7 | if the specified priv version is lower than their minimal priv version. | ||
8 | |||
9 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
11 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
12 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-Id: <20230517135714.211809-6-dbarboza@ventanamicro.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/cpu.c | 3 ++- | ||
17 | 1 file changed, 2 insertions(+), 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 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, | ||
24 | int i; | ||
25 | |||
26 | for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { | ||
27 | - if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) { | ||
28 | + if (cpu->env.priv_ver >= isa_edata_arr[i].min_version && | ||
29 | + isa_ext_is_enabled(cpu, &isa_edata_arr[i])) { | ||
30 | new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL); | ||
31 | g_free(old); | ||
32 | old = new; | ||
33 | -- | ||
34 | 2.40.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Alistair Francis <alistair23@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Remove redundant parenthese and fix multi-line comments. | 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. | ||
4 | 6 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | Reported-by: Eric DeVolder <eric_devolder@yahoo.com> |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Fixes: ea10325917 ("RISC-V Disassembler") | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Cc: qemu-stable <qemu-stable@nongnu.org> |
9 | Message-Id: <20230523093539.203909-9-liweiwei@iscas.ac.cn> | 12 | Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 14 | --- |
12 | disas/riscv.c | 219 +++++++++++++++++++++++++------------------------- | 15 | disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++- |
13 | 1 file changed, 110 insertions(+), 109 deletions(-) | 16 | 1 file changed, 64 insertions(+), 1 deletion(-) |
14 | 17 | ||
15 | diff --git a/disas/riscv.c b/disas/riscv.c | 18 | diff --git a/disas/riscv.c b/disas/riscv.c |
16 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/disas/riscv.c | 20 | --- a/disas/riscv.c |
18 | +++ b/disas/riscv.c | 21 | +++ b/disas/riscv.c |
19 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 22 | @@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno) |
20 | { | 23 | case 0x0383: return "mibound"; |
21 | rv_inst inst = dec->inst; | 24 | case 0x0384: return "mdbase"; |
22 | rv_opcode op = rv_op_illegal; | 25 | case 0x0385: return "mdbound"; |
23 | - switch (((inst >> 0) & 0b11)) { | 26 | - case 0x03a0: return "pmpcfg3"; |
24 | + switch ((inst >> 0) & 0b11) { | 27 | + case 0x03a0: return "pmpcfg0"; |
25 | case 0: | 28 | + case 0x03a1: return "pmpcfg1"; |
26 | - switch (((inst >> 13) & 0b111)) { | 29 | + case 0x03a2: return "pmpcfg2"; |
27 | + switch ((inst >> 13) & 0b111) { | 30 | + case 0x03a3: return "pmpcfg3"; |
28 | case 0: op = rv_op_c_addi4spn; break; | 31 | + case 0x03a4: return "pmpcfg4"; |
29 | case 1: | 32 | + case 0x03a5: return "pmpcfg5"; |
30 | if (isa == rv128) { | 33 | + case 0x03a6: return "pmpcfg6"; |
31 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 34 | + case 0x03a7: return "pmpcfg7"; |
32 | } | 35 | + case 0x03a8: return "pmpcfg8"; |
33 | break; | 36 | + case 0x03a9: return "pmpcfg9"; |
34 | case 1: | 37 | + case 0x03aa: return "pmpcfg10"; |
35 | - switch (((inst >> 13) & 0b111)) { | 38 | + case 0x03ab: return "pmpcfg11"; |
36 | + switch ((inst >> 13) & 0b111) { | 39 | + case 0x03ac: return "pmpcfg12"; |
37 | case 0: | 40 | + case 0x03ad: return "pmpcfg13"; |
38 | - switch (((inst >> 2) & 0b11111111111)) { | 41 | + case 0x03ae: return "pmpcfg14"; |
39 | + switch ((inst >> 2) & 0b11111111111) { | 42 | + case 0x03af: return "pmpcfg15"; |
40 | case 0: op = rv_op_c_nop; break; | 43 | case 0x03b0: return "pmpaddr0"; |
41 | default: op = rv_op_c_addi; break; | 44 | case 0x03b1: return "pmpaddr1"; |
42 | } | 45 | case 0x03b2: return "pmpaddr2"; |
43 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 46 | @@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno) |
44 | break; | 47 | case 0x03bd: return "pmpaddr13"; |
45 | case 2: op = rv_op_c_li; break; | 48 | case 0x03be: return "pmpaddr14"; |
46 | case 3: | 49 | case 0x03bf: return "pmpaddr15"; |
47 | - switch (((inst >> 7) & 0b11111)) { | 50 | + case 0x03c0: return "pmpaddr16"; |
48 | + switch ((inst >> 7) & 0b11111) { | 51 | + case 0x03c1: return "pmpaddr17"; |
49 | case 2: op = rv_op_c_addi16sp; break; | 52 | + case 0x03c2: return "pmpaddr18"; |
50 | default: op = rv_op_c_lui; break; | 53 | + case 0x03c3: return "pmpaddr19"; |
51 | } | 54 | + case 0x03c4: return "pmpaddr20"; |
52 | break; | 55 | + case 0x03c5: return "pmpaddr21"; |
53 | case 4: | 56 | + case 0x03c6: return "pmpaddr22"; |
54 | - switch (((inst >> 10) & 0b11)) { | 57 | + case 0x03c7: return "pmpaddr23"; |
55 | + switch ((inst >> 10) & 0b11) { | 58 | + case 0x03c8: return "pmpaddr24"; |
56 | case 0: | 59 | + case 0x03c9: return "pmpaddr25"; |
57 | op = rv_op_c_srli; | 60 | + case 0x03ca: return "pmpaddr26"; |
58 | break; | 61 | + case 0x03cb: return "pmpaddr27"; |
59 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 62 | + case 0x03cc: return "pmpaddr28"; |
60 | } | 63 | + case 0x03cd: return "pmpaddr29"; |
61 | break; | 64 | + case 0x03ce: return "pmpaddr30"; |
62 | case 2: | 65 | + case 0x03cf: return "pmpaddr31"; |
63 | - switch (((inst >> 13) & 0b111)) { | 66 | + case 0x03d0: return "pmpaddr32"; |
64 | + switch ((inst >> 13) & 0b111) { | 67 | + case 0x03d1: return "pmpaddr33"; |
65 | case 0: | 68 | + case 0x03d2: return "pmpaddr34"; |
66 | op = rv_op_c_slli; | 69 | + case 0x03d3: return "pmpaddr35"; |
67 | break; | 70 | + case 0x03d4: return "pmpaddr36"; |
68 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 71 | + case 0x03d5: return "pmpaddr37"; |
69 | } | 72 | + case 0x03d6: return "pmpaddr38"; |
70 | break; | 73 | + case 0x03d7: return "pmpaddr39"; |
71 | case 4: | 74 | + case 0x03d8: return "pmpaddr40"; |
72 | - switch (((inst >> 12) & 0b1)) { | 75 | + case 0x03d9: return "pmpaddr41"; |
73 | + switch ((inst >> 12) & 0b1) { | 76 | + case 0x03da: return "pmpaddr42"; |
74 | case 0: | 77 | + case 0x03db: return "pmpaddr43"; |
75 | - switch (((inst >> 2) & 0b11111)) { | 78 | + case 0x03dc: return "pmpaddr44"; |
76 | + switch ((inst >> 2) & 0b11111) { | 79 | + case 0x03dd: return "pmpaddr45"; |
77 | case 0: op = rv_op_c_jr; break; | 80 | + case 0x03de: return "pmpaddr46"; |
78 | default: op = rv_op_c_mv; break; | 81 | + case 0x03df: return "pmpaddr47"; |
79 | } | 82 | + case 0x03e0: return "pmpaddr48"; |
80 | break; | 83 | + case 0x03e1: return "pmpaddr49"; |
81 | case 1: | 84 | + case 0x03e2: return "pmpaddr50"; |
82 | - switch (((inst >> 2) & 0b11111)) { | 85 | + case 0x03e3: return "pmpaddr51"; |
83 | + switch ((inst >> 2) & 0b11111) { | 86 | + case 0x03e4: return "pmpaddr52"; |
84 | case 0: | 87 | + case 0x03e5: return "pmpaddr53"; |
85 | - switch (((inst >> 7) & 0b11111)) { | 88 | + case 0x03e6: return "pmpaddr54"; |
86 | + switch ((inst >> 7) & 0b11111) { | 89 | + case 0x03e7: return "pmpaddr55"; |
87 | case 0: op = rv_op_c_ebreak; break; | 90 | + case 0x03e8: return "pmpaddr56"; |
88 | default: op = rv_op_c_jalr; break; | 91 | + case 0x03e9: return "pmpaddr57"; |
89 | } | 92 | + case 0x03ea: return "pmpaddr58"; |
90 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | 93 | + case 0x03eb: return "pmpaddr59"; |
91 | } | 94 | + case 0x03ec: return "pmpaddr60"; |
92 | break; | 95 | + case 0x03ed: return "pmpaddr61"; |
93 | case 3: | 96 | + case 0x03ee: return "pmpaddr62"; |
94 | - switch (((inst >> 2) & 0b11111)) { | 97 | + case 0x03ef: return "pmpaddr63"; |
95 | + switch ((inst >> 2) & 0b11111) { | 98 | case 0x0780: return "mtohost"; |
96 | case 0: | 99 | case 0x0781: return "mfromhost"; |
97 | - switch (((inst >> 12) & 0b111)) { | 100 | case 0x0782: return "mreset"; |
98 | + switch ((inst >> 12) & 0b111) { | ||
99 | case 0: op = rv_op_lb; break; | ||
100 | case 1: op = rv_op_lh; break; | ||
101 | case 2: op = rv_op_lw; break; | ||
102 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
103 | } | ||
104 | break; | ||
105 | case 1: | ||
106 | - switch (((inst >> 12) & 0b111)) { | ||
107 | + switch ((inst >> 12) & 0b111) { | ||
108 | case 0: | ||
109 | - switch (((inst >> 20) & 0b111111111111)) { | ||
110 | + switch ((inst >> 20) & 0b111111111111) { | ||
111 | case 40: op = rv_op_vl1re8_v; break; | ||
112 | case 552: op = rv_op_vl2re8_v; break; | ||
113 | case 1576: op = rv_op_vl4re8_v; break; | ||
114 | case 3624: op = rv_op_vl8re8_v; break; | ||
115 | } | ||
116 | - switch (((inst >> 26) & 0b111)) { | ||
117 | + switch ((inst >> 26) & 0b111) { | ||
118 | case 0: | ||
119 | - switch (((inst >> 20) & 0b11111)) { | ||
120 | + switch ((inst >> 20) & 0b11111) { | ||
121 | case 0: op = rv_op_vle8_v; break; | ||
122 | case 11: op = rv_op_vlm_v; break; | ||
123 | case 16: op = rv_op_vle8ff_v; break; | ||
124 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
125 | case 3: op = rv_op_fld; break; | ||
126 | case 4: op = rv_op_flq; break; | ||
127 | case 5: | ||
128 | - switch (((inst >> 20) & 0b111111111111)) { | ||
129 | + switch ((inst >> 20) & 0b111111111111) { | ||
130 | case 40: op = rv_op_vl1re16_v; break; | ||
131 | case 552: op = rv_op_vl2re16_v; break; | ||
132 | case 1576: op = rv_op_vl4re16_v; break; | ||
133 | case 3624: op = rv_op_vl8re16_v; break; | ||
134 | } | ||
135 | - switch (((inst >> 26) & 0b111)) { | ||
136 | + switch ((inst >> 26) & 0b111) { | ||
137 | case 0: | ||
138 | - switch (((inst >> 20) & 0b11111)) { | ||
139 | + switch ((inst >> 20) & 0b11111) { | ||
140 | case 0: op = rv_op_vle16_v; break; | ||
141 | case 16: op = rv_op_vle16ff_v; break; | ||
142 | } | ||
143 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
144 | } | ||
145 | break; | ||
146 | case 6: | ||
147 | - switch (((inst >> 20) & 0b111111111111)) { | ||
148 | + switch ((inst >> 20) & 0b111111111111) { | ||
149 | case 40: op = rv_op_vl1re32_v; break; | ||
150 | case 552: op = rv_op_vl2re32_v; break; | ||
151 | case 1576: op = rv_op_vl4re32_v; break; | ||
152 | case 3624: op = rv_op_vl8re32_v; break; | ||
153 | } | ||
154 | - switch (((inst >> 26) & 0b111)) { | ||
155 | + switch ((inst >> 26) & 0b111) { | ||
156 | case 0: | ||
157 | - switch (((inst >> 20) & 0b11111)) { | ||
158 | + switch ((inst >> 20) & 0b11111) { | ||
159 | case 0: op = rv_op_vle32_v; break; | ||
160 | case 16: op = rv_op_vle32ff_v; break; | ||
161 | } | ||
162 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
163 | } | ||
164 | break; | ||
165 | case 7: | ||
166 | - switch (((inst >> 20) & 0b111111111111)) { | ||
167 | + switch ((inst >> 20) & 0b111111111111) { | ||
168 | case 40: op = rv_op_vl1re64_v; break; | ||
169 | case 552: op = rv_op_vl2re64_v; break; | ||
170 | case 1576: op = rv_op_vl4re64_v; break; | ||
171 | case 3624: op = rv_op_vl8re64_v; break; | ||
172 | } | ||
173 | - switch (((inst >> 26) & 0b111)) { | ||
174 | + switch ((inst >> 26) & 0b111) { | ||
175 | case 0: | ||
176 | - switch (((inst >> 20) & 0b11111)) { | ||
177 | + switch ((inst >> 20) & 0b11111) { | ||
178 | case 0: op = rv_op_vle64_v; break; | ||
179 | case 16: op = rv_op_vle64ff_v; break; | ||
180 | } | ||
181 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
182 | } | ||
183 | break; | ||
184 | case 3: | ||
185 | - switch (((inst >> 12) & 0b111)) { | ||
186 | + switch ((inst >> 12) & 0b111) { | ||
187 | case 0: op = rv_op_fence; break; | ||
188 | case 1: op = rv_op_fence_i; break; | ||
189 | case 2: op = rv_op_lq; break; | ||
190 | } | ||
191 | break; | ||
192 | case 4: | ||
193 | - switch (((inst >> 12) & 0b111)) { | ||
194 | + switch ((inst >> 12) & 0b111) { | ||
195 | case 0: op = rv_op_addi; break; | ||
196 | case 1: | ||
197 | - switch (((inst >> 27) & 0b11111)) { | ||
198 | + switch ((inst >> 27) & 0b11111) { | ||
199 | case 0b00000: op = rv_op_slli; break; | ||
200 | case 0b00001: | ||
201 | - switch (((inst >> 20) & 0b1111111)) { | ||
202 | + switch ((inst >> 20) & 0b1111111) { | ||
203 | case 0b0001111: op = rv_op_zip; break; | ||
204 | } | ||
205 | break; | ||
206 | case 0b00010: | ||
207 | - switch (((inst >> 20) & 0b1111111)) { | ||
208 | + switch ((inst >> 20) & 0b1111111) { | ||
209 | case 0b0000000: op = rv_op_sha256sum0; break; | ||
210 | case 0b0000001: op = rv_op_sha256sum1; break; | ||
211 | case 0b0000010: op = rv_op_sha256sig0; break; | ||
212 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
213 | break; | ||
214 | case 0b00101: op = rv_op_bseti; break; | ||
215 | case 0b00110: | ||
216 | - switch (((inst >> 20) & 0b1111111)) { | ||
217 | + switch ((inst >> 20) & 0b1111111) { | ||
218 | case 0b0000000: op = rv_op_aes64im; break; | ||
219 | default: | ||
220 | if (((inst >> 24) & 0b0111) == 0b001) { | ||
221 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
222 | case 0b01001: op = rv_op_bclri; break; | ||
223 | case 0b01101: op = rv_op_binvi; break; | ||
224 | case 0b01100: | ||
225 | - switch (((inst >> 20) & 0b1111111)) { | ||
226 | + switch ((inst >> 20) & 0b1111111) { | ||
227 | case 0b0000000: op = rv_op_clz; break; | ||
228 | case 0b0000001: op = rv_op_ctz; break; | ||
229 | case 0b0000010: op = rv_op_cpop; break; | ||
230 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
231 | case 3: op = rv_op_sltiu; break; | ||
232 | case 4: op = rv_op_xori; break; | ||
233 | case 5: | ||
234 | - switch (((inst >> 27) & 0b11111)) { | ||
235 | + switch ((inst >> 27) & 0b11111) { | ||
236 | case 0b00000: op = rv_op_srli; break; | ||
237 | case 0b00001: | ||
238 | - switch (((inst >> 20) & 0b1111111)) { | ||
239 | + switch ((inst >> 20) & 0b1111111) { | ||
240 | case 0b0001111: op = rv_op_unzip; break; | ||
241 | } | ||
242 | break; | ||
243 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
244 | break; | ||
245 | case 5: op = rv_op_auipc; break; | ||
246 | case 6: | ||
247 | - switch (((inst >> 12) & 0b111)) { | ||
248 | + switch ((inst >> 12) & 0b111) { | ||
249 | case 0: op = rv_op_addiw; break; | ||
250 | case 1: | ||
251 | - switch (((inst >> 26) & 0b111111)) { | ||
252 | + switch ((inst >> 26) & 0b111111) { | ||
253 | case 0: op = rv_op_slliw; break; | ||
254 | case 2: op = rv_op_slli_uw; break; | ||
255 | case 24: | ||
256 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
257 | } | ||
258 | break; | ||
259 | case 5: | ||
260 | - switch (((inst >> 25) & 0b1111111)) { | ||
261 | + switch ((inst >> 25) & 0b1111111) { | ||
262 | case 0: op = rv_op_srliw; break; | ||
263 | case 32: op = rv_op_sraiw; break; | ||
264 | case 48: op = rv_op_roriw; break; | ||
265 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
266 | } | ||
267 | break; | ||
268 | case 8: | ||
269 | - switch (((inst >> 12) & 0b111)) { | ||
270 | + switch ((inst >> 12) & 0b111) { | ||
271 | case 0: op = rv_op_sb; break; | ||
272 | case 1: op = rv_op_sh; break; | ||
273 | case 2: op = rv_op_sw; break; | ||
274 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
275 | } | ||
276 | break; | ||
277 | case 9: | ||
278 | - switch (((inst >> 12) & 0b111)) { | ||
279 | + switch ((inst >> 12) & 0b111) { | ||
280 | case 0: | ||
281 | - switch (((inst >> 20) & 0b111111111111)) { | ||
282 | + switch ((inst >> 20) & 0b111111111111) { | ||
283 | case 40: op = rv_op_vs1r_v; break; | ||
284 | case 552: op = rv_op_vs2r_v; break; | ||
285 | case 1576: op = rv_op_vs4r_v; break; | ||
286 | case 3624: op = rv_op_vs8r_v; break; | ||
287 | } | ||
288 | - switch (((inst >> 26) & 0b111)) { | ||
289 | + switch ((inst >> 26) & 0b111) { | ||
290 | case 0: | ||
291 | - switch (((inst >> 20) & 0b11111)) { | ||
292 | + switch ((inst >> 20) & 0b11111) { | ||
293 | case 0: op = rv_op_vse8_v; break; | ||
294 | case 11: op = rv_op_vsm_v; break; | ||
295 | } | ||
296 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
297 | case 3: op = rv_op_fsd; break; | ||
298 | case 4: op = rv_op_fsq; break; | ||
299 | case 5: | ||
300 | - switch (((inst >> 26) & 0b111)) { | ||
301 | + switch ((inst >> 26) & 0b111) { | ||
302 | case 0: | ||
303 | - switch (((inst >> 20) & 0b11111)) { | ||
304 | + switch ((inst >> 20) & 0b11111) { | ||
305 | case 0: op = rv_op_vse16_v; break; | ||
306 | } | ||
307 | break; | ||
308 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
309 | } | ||
310 | break; | ||
311 | case 6: | ||
312 | - switch (((inst >> 26) & 0b111)) { | ||
313 | + switch ((inst >> 26) & 0b111) { | ||
314 | case 0: | ||
315 | - switch (((inst >> 20) & 0b11111)) { | ||
316 | + switch ((inst >> 20) & 0b11111) { | ||
317 | case 0: op = rv_op_vse32_v; break; | ||
318 | } | ||
319 | break; | ||
320 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
321 | } | ||
322 | break; | ||
323 | case 7: | ||
324 | - switch (((inst >> 26) & 0b111)) { | ||
325 | + switch ((inst >> 26) & 0b111) { | ||
326 | case 0: | ||
327 | - switch (((inst >> 20) & 0b11111)) { | ||
328 | + switch ((inst >> 20) & 0b11111) { | ||
329 | case 0: op = rv_op_vse64_v; break; | ||
330 | } | ||
331 | break; | ||
332 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
333 | case 11: op = rv_op_amoswap_d; break; | ||
334 | case 12: op = rv_op_amoswap_q; break; | ||
335 | case 18: | ||
336 | - switch (((inst >> 20) & 0b11111)) { | ||
337 | + switch ((inst >> 20) & 0b11111) { | ||
338 | case 0: op = rv_op_lr_w; break; | ||
339 | } | ||
340 | break; | ||
341 | case 19: | ||
342 | - switch (((inst >> 20) & 0b11111)) { | ||
343 | + switch ((inst >> 20) & 0b11111) { | ||
344 | case 0: op = rv_op_lr_d; break; | ||
345 | } | ||
346 | break; | ||
347 | case 20: | ||
348 | - switch (((inst >> 20) & 0b11111)) { | ||
349 | + switch ((inst >> 20) & 0b11111) { | ||
350 | case 0: op = rv_op_lr_q; break; | ||
351 | } | ||
352 | break; | ||
353 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
354 | } | ||
355 | break; | ||
356 | case 16: | ||
357 | - switch (((inst >> 25) & 0b11)) { | ||
358 | + switch ((inst >> 25) & 0b11) { | ||
359 | case 0: op = rv_op_fmadd_s; break; | ||
360 | case 1: op = rv_op_fmadd_d; break; | ||
361 | case 3: op = rv_op_fmadd_q; break; | ||
362 | } | ||
363 | break; | ||
364 | case 17: | ||
365 | - switch (((inst >> 25) & 0b11)) { | ||
366 | + switch ((inst >> 25) & 0b11) { | ||
367 | case 0: op = rv_op_fmsub_s; break; | ||
368 | case 1: op = rv_op_fmsub_d; break; | ||
369 | case 3: op = rv_op_fmsub_q; break; | ||
370 | } | ||
371 | break; | ||
372 | case 18: | ||
373 | - switch (((inst >> 25) & 0b11)) { | ||
374 | + switch ((inst >> 25) & 0b11) { | ||
375 | case 0: op = rv_op_fnmsub_s; break; | ||
376 | case 1: op = rv_op_fnmsub_d; break; | ||
377 | case 3: op = rv_op_fnmsub_q; break; | ||
378 | } | ||
379 | break; | ||
380 | case 19: | ||
381 | - switch (((inst >> 25) & 0b11)) { | ||
382 | + switch ((inst >> 25) & 0b11) { | ||
383 | case 0: op = rv_op_fnmadd_s; break; | ||
384 | case 1: op = rv_op_fnmadd_d; break; | ||
385 | case 3: op = rv_op_fnmadd_q; break; | ||
386 | } | ||
387 | break; | ||
388 | case 20: | ||
389 | - switch (((inst >> 25) & 0b1111111)) { | ||
390 | + switch ((inst >> 25) & 0b1111111) { | ||
391 | case 0: op = rv_op_fadd_s; break; | ||
392 | case 1: op = rv_op_fadd_d; break; | ||
393 | case 3: op = rv_op_fadd_q; break; | ||
394 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
395 | case 13: op = rv_op_fdiv_d; break; | ||
396 | case 15: op = rv_op_fdiv_q; break; | ||
397 | case 16: | ||
398 | - switch (((inst >> 12) & 0b111)) { | ||
399 | + switch ((inst >> 12) & 0b111) { | ||
400 | case 0: op = rv_op_fsgnj_s; break; | ||
401 | case 1: op = rv_op_fsgnjn_s; break; | ||
402 | case 2: op = rv_op_fsgnjx_s; break; | ||
403 | } | ||
404 | break; | ||
405 | case 17: | ||
406 | - switch (((inst >> 12) & 0b111)) { | ||
407 | + switch ((inst >> 12) & 0b111) { | ||
408 | case 0: op = rv_op_fsgnj_d; break; | ||
409 | case 1: op = rv_op_fsgnjn_d; break; | ||
410 | case 2: op = rv_op_fsgnjx_d; break; | ||
411 | } | ||
412 | break; | ||
413 | case 19: | ||
414 | - switch (((inst >> 12) & 0b111)) { | ||
415 | + switch ((inst >> 12) & 0b111) { | ||
416 | case 0: op = rv_op_fsgnj_q; break; | ||
417 | case 1: op = rv_op_fsgnjn_q; break; | ||
418 | case 2: op = rv_op_fsgnjx_q; break; | ||
419 | } | ||
420 | break; | ||
421 | case 20: | ||
422 | - switch (((inst >> 12) & 0b111)) { | ||
423 | + switch ((inst >> 12) & 0b111) { | ||
424 | case 0: op = rv_op_fmin_s; break; | ||
425 | case 1: op = rv_op_fmax_s; break; | ||
426 | } | ||
427 | break; | ||
428 | case 21: | ||
429 | - switch (((inst >> 12) & 0b111)) { | ||
430 | + switch ((inst >> 12) & 0b111) { | ||
431 | case 0: op = rv_op_fmin_d; break; | ||
432 | case 1: op = rv_op_fmax_d; break; | ||
433 | } | ||
434 | break; | ||
435 | case 23: | ||
436 | - switch (((inst >> 12) & 0b111)) { | ||
437 | + switch ((inst >> 12) & 0b111) { | ||
438 | case 0: op = rv_op_fmin_q; break; | ||
439 | case 1: op = rv_op_fmax_q; break; | ||
440 | } | ||
441 | break; | ||
442 | case 32: | ||
443 | - switch (((inst >> 20) & 0b11111)) { | ||
444 | + switch ((inst >> 20) & 0b11111) { | ||
445 | case 1: op = rv_op_fcvt_s_d; break; | ||
446 | case 3: op = rv_op_fcvt_s_q; break; | ||
447 | } | ||
448 | break; | ||
449 | case 33: | ||
450 | - switch (((inst >> 20) & 0b11111)) { | ||
451 | + switch ((inst >> 20) & 0b11111) { | ||
452 | case 0: op = rv_op_fcvt_d_s; break; | ||
453 | case 3: op = rv_op_fcvt_d_q; break; | ||
454 | } | ||
455 | break; | ||
456 | case 35: | ||
457 | - switch (((inst >> 20) & 0b11111)) { | ||
458 | + switch ((inst >> 20) & 0b11111) { | ||
459 | case 0: op = rv_op_fcvt_q_s; break; | ||
460 | case 1: op = rv_op_fcvt_q_d; break; | ||
461 | } | ||
462 | break; | ||
463 | case 44: | ||
464 | - switch (((inst >> 20) & 0b11111)) { | ||
465 | + switch ((inst >> 20) & 0b11111) { | ||
466 | case 0: op = rv_op_fsqrt_s; break; | ||
467 | } | ||
468 | break; | ||
469 | case 45: | ||
470 | - switch (((inst >> 20) & 0b11111)) { | ||
471 | + switch ((inst >> 20) & 0b11111) { | ||
472 | case 0: op = rv_op_fsqrt_d; break; | ||
473 | } | ||
474 | break; | ||
475 | case 47: | ||
476 | - switch (((inst >> 20) & 0b11111)) { | ||
477 | + switch ((inst >> 20) & 0b11111) { | ||
478 | case 0: op = rv_op_fsqrt_q; break; | ||
479 | } | ||
480 | break; | ||
481 | case 80: | ||
482 | - switch (((inst >> 12) & 0b111)) { | ||
483 | + switch ((inst >> 12) & 0b111) { | ||
484 | case 0: op = rv_op_fle_s; break; | ||
485 | case 1: op = rv_op_flt_s; break; | ||
486 | case 2: op = rv_op_feq_s; break; | ||
487 | } | ||
488 | break; | ||
489 | case 81: | ||
490 | - switch (((inst >> 12) & 0b111)) { | ||
491 | + switch ((inst >> 12) & 0b111) { | ||
492 | case 0: op = rv_op_fle_d; break; | ||
493 | case 1: op = rv_op_flt_d; break; | ||
494 | case 2: op = rv_op_feq_d; break; | ||
495 | } | ||
496 | break; | ||
497 | case 83: | ||
498 | - switch (((inst >> 12) & 0b111)) { | ||
499 | + switch ((inst >> 12) & 0b111) { | ||
500 | case 0: op = rv_op_fle_q; break; | ||
501 | case 1: op = rv_op_flt_q; break; | ||
502 | case 2: op = rv_op_feq_q; break; | ||
503 | } | ||
504 | break; | ||
505 | case 96: | ||
506 | - switch (((inst >> 20) & 0b11111)) { | ||
507 | + switch ((inst >> 20) & 0b11111) { | ||
508 | case 0: op = rv_op_fcvt_w_s; break; | ||
509 | case 1: op = rv_op_fcvt_wu_s; break; | ||
510 | case 2: op = rv_op_fcvt_l_s; break; | ||
511 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
512 | } | ||
513 | break; | ||
514 | case 97: | ||
515 | - switch (((inst >> 20) & 0b11111)) { | ||
516 | + switch ((inst >> 20) & 0b11111) { | ||
517 | case 0: op = rv_op_fcvt_w_d; break; | ||
518 | case 1: op = rv_op_fcvt_wu_d; break; | ||
519 | case 2: op = rv_op_fcvt_l_d; break; | ||
520 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
521 | } | ||
522 | break; | ||
523 | case 99: | ||
524 | - switch (((inst >> 20) & 0b11111)) { | ||
525 | + switch ((inst >> 20) & 0b11111) { | ||
526 | case 0: op = rv_op_fcvt_w_q; break; | ||
527 | case 1: op = rv_op_fcvt_wu_q; break; | ||
528 | case 2: op = rv_op_fcvt_l_q; break; | ||
529 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
530 | } | ||
531 | break; | ||
532 | case 104: | ||
533 | - switch (((inst >> 20) & 0b11111)) { | ||
534 | + switch ((inst >> 20) & 0b11111) { | ||
535 | case 0: op = rv_op_fcvt_s_w; break; | ||
536 | case 1: op = rv_op_fcvt_s_wu; break; | ||
537 | case 2: op = rv_op_fcvt_s_l; break; | ||
538 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
539 | } | ||
540 | break; | ||
541 | case 105: | ||
542 | - switch (((inst >> 20) & 0b11111)) { | ||
543 | + switch ((inst >> 20) & 0b11111) { | ||
544 | case 0: op = rv_op_fcvt_d_w; break; | ||
545 | case 1: op = rv_op_fcvt_d_wu; break; | ||
546 | case 2: op = rv_op_fcvt_d_l; break; | ||
547 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
548 | } | ||
549 | break; | ||
550 | case 107: | ||
551 | - switch (((inst >> 20) & 0b11111)) { | ||
552 | + switch ((inst >> 20) & 0b11111) { | ||
553 | case 0: op = rv_op_fcvt_q_w; break; | ||
554 | case 1: op = rv_op_fcvt_q_wu; break; | ||
555 | case 2: op = rv_op_fcvt_q_l; break; | ||
556 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
557 | } | ||
558 | break; | ||
559 | case 21: | ||
560 | - switch (((inst >> 12) & 0b111)) { | ||
561 | + switch ((inst >> 12) & 0b111) { | ||
562 | case 0: | ||
563 | - switch (((inst >> 26) & 0b111111)) { | ||
564 | + switch ((inst >> 26) & 0b111111) { | ||
565 | case 0: op = rv_op_vadd_vv; break; | ||
566 | case 2: op = rv_op_vsub_vv; break; | ||
567 | case 4: op = rv_op_vminu_vv; break; | ||
568 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
569 | } | ||
570 | break; | ||
571 | case 1: | ||
572 | - switch (((inst >> 26) & 0b111111)) { | ||
573 | + switch ((inst >> 26) & 0b111111) { | ||
574 | case 0: op = rv_op_vfadd_vv; break; | ||
575 | case 1: op = rv_op_vfredusum_vs; break; | ||
576 | case 2: op = rv_op_vfsub_vv; break; | ||
577 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
578 | case 9: op = rv_op_vfsgnjn_vv; break; | ||
579 | case 10: op = rv_op_vfsgnjx_vv; break; | ||
580 | case 16: | ||
581 | - switch (((inst >> 15) & 0b11111)) { | ||
582 | + switch ((inst >> 15) & 0b11111) { | ||
583 | case 0: if ((inst >> 25) & 1) op = rv_op_vfmv_f_s; break; | ||
584 | } | ||
585 | break; | ||
586 | case 18: | ||
587 | - switch (((inst >> 15) & 0b11111)) { | ||
588 | + switch ((inst >> 15) & 0b11111) { | ||
589 | case 0: op = rv_op_vfcvt_xu_f_v; break; | ||
590 | case 1: op = rv_op_vfcvt_x_f_v; break; | ||
591 | case 2: op = rv_op_vfcvt_f_xu_v; break; | ||
592 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
593 | } | ||
594 | break; | ||
595 | case 19: | ||
596 | - switch (((inst >> 15) & 0b11111)) { | ||
597 | + switch ((inst >> 15) & 0b11111) { | ||
598 | case 0: op = rv_op_vfsqrt_v; break; | ||
599 | case 4: op = rv_op_vfrsqrt7_v; break; | ||
600 | case 5: op = rv_op_vfrec7_v; break; | ||
601 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
602 | } | ||
603 | break; | ||
604 | case 2: | ||
605 | - switch (((inst >> 26) & 0b111111)) { | ||
606 | + switch ((inst >> 26) & 0b111111) { | ||
607 | case 0: op = rv_op_vredsum_vs; break; | ||
608 | case 1: op = rv_op_vredand_vs; break; | ||
609 | case 2: op = rv_op_vredor_vs; break; | ||
610 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
611 | case 10: op = rv_op_vasubu_vv; break; | ||
612 | case 11: op = rv_op_vasub_vv; break; | ||
613 | case 16: | ||
614 | - switch (((inst >> 15) & 0b11111)) { | ||
615 | + switch ((inst >> 15) & 0b11111) { | ||
616 | case 0: if ((inst >> 25) & 1) op = rv_op_vmv_x_s; break; | ||
617 | case 16: op = rv_op_vcpop_m; break; | ||
618 | case 17: op = rv_op_vfirst_m; break; | ||
619 | } | ||
620 | break; | ||
621 | case 18: | ||
622 | - switch (((inst >> 15) & 0b11111)) { | ||
623 | + switch ((inst >> 15) & 0b11111) { | ||
624 | case 2: op = rv_op_vzext_vf8; break; | ||
625 | case 3: op = rv_op_vsext_vf8; break; | ||
626 | case 4: op = rv_op_vzext_vf4; break; | ||
627 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
628 | } | ||
629 | break; | ||
630 | case 20: | ||
631 | - switch (((inst >> 15) & 0b11111)) { | ||
632 | + switch ((inst >> 15) & 0b11111) { | ||
633 | case 1: op = rv_op_vmsbf_m; break; | ||
634 | case 2: op = rv_op_vmsof_m; break; | ||
635 | case 3: op = rv_op_vmsif_m; break; | ||
636 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
637 | } | ||
638 | break; | ||
639 | case 3: | ||
640 | - switch (((inst >> 26) & 0b111111)) { | ||
641 | + switch ((inst >> 26) & 0b111111) { | ||
642 | case 0: op = rv_op_vadd_vi; break; | ||
643 | case 3: op = rv_op_vrsub_vi; break; | ||
644 | case 9: op = rv_op_vand_vi; break; | ||
645 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
646 | case 33: op = rv_op_vsadd_vi; break; | ||
647 | case 37: op = rv_op_vsll_vi; break; | ||
648 | case 39: | ||
649 | - switch (((inst >> 15) & 0b11111)) { | ||
650 | + switch ((inst >> 15) & 0b11111) { | ||
651 | case 0: op = rv_op_vmv1r_v; break; | ||
652 | case 1: op = rv_op_vmv2r_v; break; | ||
653 | case 3: op = rv_op_vmv4r_v; break; | ||
654 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
655 | } | ||
656 | break; | ||
657 | case 4: | ||
658 | - switch (((inst >> 26) & 0b111111)) { | ||
659 | + switch ((inst >> 26) & 0b111111) { | ||
660 | case 0: op = rv_op_vadd_vx; break; | ||
661 | case 2: op = rv_op_vsub_vx; break; | ||
662 | case 3: op = rv_op_vrsub_vx; break; | ||
663 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
664 | } | ||
665 | break; | ||
666 | case 5: | ||
667 | - switch (((inst >> 26) & 0b111111)) { | ||
668 | + switch ((inst >> 26) & 0b111111) { | ||
669 | case 0: op = rv_op_vfadd_vf; break; | ||
670 | case 2: op = rv_op_vfsub_vf; break; | ||
671 | case 4: op = rv_op_vfmin_vf; break; | ||
672 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
673 | case 14: op = rv_op_vfslide1up_vf; break; | ||
674 | case 15: op = rv_op_vfslide1down_vf; break; | ||
675 | case 16: | ||
676 | - switch (((inst >> 20) & 0b11111)) { | ||
677 | + switch ((inst >> 20) & 0b11111) { | ||
678 | case 0: if ((inst >> 25) & 1) op = rv_op_vfmv_s_f; break; | ||
679 | } | ||
680 | break; | ||
681 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
682 | } | ||
683 | break; | ||
684 | case 6: | ||
685 | - switch (((inst >> 26) & 0b111111)) { | ||
686 | + switch ((inst >> 26) & 0b111111) { | ||
687 | case 8: op = rv_op_vaaddu_vx; break; | ||
688 | case 9: op = rv_op_vaadd_vx; break; | ||
689 | case 10: op = rv_op_vasubu_vx; break; | ||
690 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
691 | case 14: op = rv_op_vslide1up_vx; break; | ||
692 | case 15: op = rv_op_vslide1down_vx; break; | ||
693 | case 16: | ||
694 | - switch (((inst >> 20) & 0b11111)) { | ||
695 | + switch ((inst >> 20) & 0b11111) { | ||
696 | case 0: if ((inst >> 25) & 1) op = rv_op_vmv_s_x; break; | ||
697 | } | ||
698 | break; | ||
699 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
700 | } | ||
701 | break; | ||
702 | case 22: | ||
703 | - switch (((inst >> 12) & 0b111)) { | ||
704 | + switch ((inst >> 12) & 0b111) { | ||
705 | case 0: op = rv_op_addid; break; | ||
706 | case 1: | ||
707 | - switch (((inst >> 26) & 0b111111)) { | ||
708 | + switch ((inst >> 26) & 0b111111) { | ||
709 | case 0: op = rv_op_sllid; break; | ||
710 | } | ||
711 | break; | ||
712 | case 5: | ||
713 | - switch (((inst >> 26) & 0b111111)) { | ||
714 | + switch ((inst >> 26) & 0b111111) { | ||
715 | case 0: op = rv_op_srlid; break; | ||
716 | case 16: op = rv_op_sraid; break; | ||
717 | } | ||
718 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
719 | } | ||
720 | break; | ||
721 | case 24: | ||
722 | - switch (((inst >> 12) & 0b111)) { | ||
723 | + switch ((inst >> 12) & 0b111) { | ||
724 | case 0: op = rv_op_beq; break; | ||
725 | case 1: op = rv_op_bne; break; | ||
726 | case 4: op = rv_op_blt; break; | ||
727 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
728 | } | ||
729 | break; | ||
730 | case 25: | ||
731 | - switch (((inst >> 12) & 0b111)) { | ||
732 | + switch ((inst >> 12) & 0b111) { | ||
733 | case 0: op = rv_op_jalr; break; | ||
734 | } | ||
735 | break; | ||
736 | case 27: op = rv_op_jal; break; | ||
737 | case 28: | ||
738 | - switch (((inst >> 12) & 0b111)) { | ||
739 | + switch ((inst >> 12) & 0b111) { | ||
740 | case 0: | ||
741 | switch (((inst >> 20) & 0b111111100000) | | ||
742 | ((inst >> 7) & 0b000000011111)) { | ||
743 | case 0: | ||
744 | - switch (((inst >> 15) & 0b1111111111)) { | ||
745 | + switch ((inst >> 15) & 0b1111111111) { | ||
746 | case 0: op = rv_op_ecall; break; | ||
747 | case 32: op = rv_op_ebreak; break; | ||
748 | case 64: op = rv_op_uret; break; | ||
749 | } | ||
750 | break; | ||
751 | case 256: | ||
752 | - switch (((inst >> 20) & 0b11111)) { | ||
753 | + switch ((inst >> 20) & 0b11111) { | ||
754 | case 2: | ||
755 | - switch (((inst >> 15) & 0b11111)) { | ||
756 | + switch ((inst >> 15) & 0b11111) { | ||
757 | case 0: op = rv_op_sret; break; | ||
758 | } | ||
759 | break; | ||
760 | case 4: op = rv_op_sfence_vm; break; | ||
761 | case 5: | ||
762 | - switch (((inst >> 15) & 0b11111)) { | ||
763 | + switch ((inst >> 15) & 0b11111) { | ||
764 | case 0: op = rv_op_wfi; break; | ||
765 | } | ||
766 | break; | ||
767 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
768 | break; | ||
769 | case 288: op = rv_op_sfence_vma; break; | ||
770 | case 512: | ||
771 | - switch (((inst >> 15) & 0b1111111111)) { | ||
772 | + switch ((inst >> 15) & 0b1111111111) { | ||
773 | case 64: op = rv_op_hret; break; | ||
774 | } | ||
775 | break; | ||
776 | case 768: | ||
777 | - switch (((inst >> 15) & 0b1111111111)) { | ||
778 | + switch ((inst >> 15) & 0b1111111111) { | ||
779 | case 64: op = rv_op_mret; break; | ||
780 | } | ||
781 | break; | ||
782 | case 1952: | ||
783 | - switch (((inst >> 15) & 0b1111111111)) { | ||
784 | + switch ((inst >> 15) & 0b1111111111) { | ||
785 | case 576: op = rv_op_dret; break; | ||
786 | } | ||
787 | break; | ||
788 | @@ -XXX,XX +XXX,XX @@ static size_t inst_length(rv_inst inst) | ||
789 | { | ||
790 | /* NOTE: supports maximum instruction size of 64-bits */ | ||
791 | |||
792 | - /* instruction length coding | ||
793 | + /* | ||
794 | + * instruction length coding | ||
795 | * | ||
796 | * aa - 16 bit aa != 11 | ||
797 | * bbb11 - 32 bit bbb != 111 | ||
798 | -- | 101 | -- |
799 | 2.40.1 | 102 | 2.45.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Yu-Ming Chang <yumin686@andestech.com> |
---|---|---|---|
2 | 2 | ||
3 | write_misa() must use as much common logic as possible. We want to open | 3 | Both CSRRS and CSRRC always read the addressed CSR and cause any read side |
4 | code just the bits that are exclusive to the CSR write operation and TCG | 4 | effects regardless of rs1 and rd fields. Note that if rs1 specifies a register |
5 | internals. | 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. | ||
6 | 7 | ||
7 | Our validation is done with riscv_cpu_validate_set_extensions(), but we | 8 | So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies |
8 | need a small tweak first. When enabling RVG we're doing: | 9 | a register holding a zero value, an illegal instruction exception should be |
10 | raised. | ||
9 | 11 | ||
10 | env->misa_ext |= RVI | RVM | RVA | RVF | RVD; | 12 | Signed-off-by: Yu-Ming Chang <yumin686@andestech.com> |
11 | env->misa_ext_mask = env->misa_ext; | 13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
12 | 14 | Message-ID: <20240403070823.80897-1-yumin686@andestech.com> | |
13 | This works fine for realize() time but this can potentially overwrite | ||
14 | env->misa_ext_mask if we reutilize the function for write_misa(). | ||
15 | |||
16 | Instead of doing misa_ext_mask = misa_ext, sum up the RVG extensions in | ||
17 | misa_ext_mask as well. This won't change realize() time behavior | ||
18 | (misa_ext_mask will be == misa_ext) and will ensure that write_misa() | ||
19 | won't change misa_ext_mask by accident. | ||
20 | |||
21 | After that, rewrite write_misa() to work as follows: | ||
22 | |||
23 | - mask the write using misa_ext_mask to avoid enabling unsupported | ||
24 | extensions; | ||
25 | |||
26 | - suppress RVC if the next insn isn't aligned; | ||
27 | |||
28 | - disable RVG if any of RVG dependencies are being disabled by the user; | ||
29 | |||
30 | - assign env->misa_ext and run riscv_cpu_validate_set_extensions(). On | ||
31 | error, rollback env->misa_ext to its original value, logging a | ||
32 | GUEST_ERROR to inform the user about the failed write; | ||
33 | |||
34 | - handle RVF and MSTATUS_FS and continue as usual. | ||
35 | |||
36 | Let's keep write_misa() as experimental for now until this logic gains | ||
37 | enough mileage. | ||
38 | |||
39 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
40 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
41 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
42 | Message-Id: <20230517135714.211809-12-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/cpu.h | 1 + | 17 | target/riscv/cpu.h | 4 ++++ |
46 | target/riscv/cpu.c | 4 ++-- | 18 | target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++---- |
47 | target/riscv/csr.c | 51 ++++++++++++++++++++++------------------------ | 19 | target/riscv/op_helper.c | 6 ++--- |
48 | 3 files changed, 27 insertions(+), 29 deletions(-) | 20 | 3 files changed, 53 insertions(+), 8 deletions(-) |
49 | 21 | ||
50 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 22 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
51 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
52 | --- a/target/riscv/cpu.h | 24 | --- a/target/riscv/cpu.h |
53 | +++ b/target/riscv/cpu.h | 25 | +++ b/target/riscv/cpu.h |
54 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | 26 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, |
55 | bool probe, uintptr_t retaddr); | 27 | void riscv_cpu_update_mask(CPURISCVState *env); |
56 | char *riscv_isa_string(RISCVCPU *cpu); | 28 | bool riscv_cpu_is_32bit(RISCVCPU *cpu); |
57 | void riscv_cpu_list(void); | 29 | |
58 | +void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp); | 30 | +RISCVException riscv_csrr(CPURISCVState *env, int csrno, |
59 | 31 | + target_ulong *ret_value); | |
60 | #define cpu_list riscv_cpu_list | 32 | RISCVException riscv_csrrw(CPURISCVState *env, int csrno, |
61 | #define cpu_mmu_index riscv_cpu_mmu_index | 33 | target_ulong *ret_value, |
62 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 34 | target_ulong new_value, target_ulong write_mask); |
63 | index XXXXXXX..XXXXXXX 100644 | 35 | @@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno, |
64 | --- a/target/riscv/cpu.c | 36 | target_ulong new_value, |
65 | +++ b/target/riscv/cpu.c | 37 | target_ulong write_mask); |
66 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) | 38 | |
67 | * Check consistency between chosen extensions while setting | 39 | +RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno, |
68 | * cpu->cfg accordingly. | 40 | + Int128 *ret_value); |
69 | */ | 41 | RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, |
70 | -static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 42 | Int128 *ret_value, |
71 | +void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 43 | Int128 new_value, Int128 write_mask); |
72 | { | ||
73 | CPURISCVState *env = &cpu->env; | ||
74 | Error *local_err = NULL; | ||
75 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
76 | cpu->cfg.ext_ifencei = true; | ||
77 | |||
78 | env->misa_ext |= RVI | RVM | RVA | RVF | RVD; | ||
79 | - env->misa_ext_mask = env->misa_ext; | ||
80 | + env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD; | ||
81 | } | ||
82 | |||
83 | if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) { | ||
84 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 44 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
85 | index XXXXXXX..XXXXXXX 100644 | 45 | index XXXXXXX..XXXXXXX 100644 |
86 | --- a/target/riscv/csr.c | 46 | --- a/target/riscv/csr.c |
87 | +++ b/target/riscv/csr.c | 47 | +++ b/target/riscv/csr.c |
88 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_misa(CPURISCVState *env, int csrno, | 48 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno, |
89 | static RISCVException write_misa(CPURISCVState *env, int csrno, | 49 | |
90 | target_ulong val) | 50 | static inline RISCVException riscv_csrrw_check(CPURISCVState *env, |
51 | int csrno, | ||
52 | - bool write_mask) | ||
53 | + bool write) | ||
91 | { | 54 | { |
92 | + RISCVCPU *cpu = env_archcpu(env); | 55 | /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */ |
93 | + uint32_t orig_misa_ext = env->misa_ext; | 56 | bool read_only = get_field(csrno, 0xC00) == 3; |
94 | + Error *local_err = NULL; | 57 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, |
95 | + | ||
96 | if (!riscv_cpu_cfg(env)->misa_w) { | ||
97 | /* drop write to misa */ | ||
98 | return RISCV_EXCP_NONE; | ||
99 | } | 58 | } |
100 | 59 | ||
101 | - /* 'I' or 'E' must be present */ | 60 | /* read / write check */ |
102 | - if (!(val & (RVI | RVE))) { | 61 | - if (write_mask && read_only) { |
103 | - /* It is not, drop write to misa */ | 62 | + if (write && read_only) { |
104 | - return RISCV_EXCP_NONE; | 63 | return RISCV_EXCP_ILLEGAL_INST; |
105 | - } | ||
106 | - | ||
107 | - /* 'E' excludes all other extensions */ | ||
108 | - if (val & RVE) { | ||
109 | - /* | ||
110 | - * when we support 'E' we can do "val = RVE;" however | ||
111 | - * for now we just drop writes if 'E' is present. | ||
112 | - */ | ||
113 | - return RISCV_EXCP_NONE; | ||
114 | - } | ||
115 | - | ||
116 | - /* | ||
117 | - * misa.MXL writes are not supported by QEMU. | ||
118 | - * Drop writes to those bits. | ||
119 | - */ | ||
120 | - | ||
121 | /* Mask extensions that are not supported by this hart */ | ||
122 | val &= env->misa_ext_mask; | ||
123 | |||
124 | - /* 'D' depends on 'F', so clear 'D' if 'F' is not present */ | ||
125 | - if ((val & RVD) && !(val & RVF)) { | ||
126 | - val &= ~RVD; | ||
127 | - } | ||
128 | - | ||
129 | /* | ||
130 | * Suppress 'C' if next instruction is not aligned | ||
131 | * TODO: this should check next_pc | ||
132 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_misa(CPURISCVState *env, int csrno, | ||
133 | val &= ~RVC; | ||
134 | } | 64 | } |
135 | 65 | ||
136 | + /* Disable RVG if any of its dependencies are disabled */ | 66 | @@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno, |
137 | + if (!(val & RVI && val & RVM && val & RVA && | 67 | return RISCV_EXCP_NONE; |
138 | + val & RVF && val & RVD)) { | 68 | } |
139 | + val &= ~RVG; | 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; | ||
140 | + } | 76 | + } |
141 | + | 77 | + |
142 | /* If nothing changed, do nothing. */ | 78 | + return riscv_csrrw_do64(env, csrno, ret_value, 0, 0); |
143 | if (val == env->misa_ext) { | 79 | +} |
144 | return RISCV_EXCP_NONE; | 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; | ||
145 | } | 89 | } |
146 | 90 | @@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno, | |
147 | - if (!(val & RVF)) { | 91 | return RISCV_EXCP_NONE; |
148 | + env->misa_ext = val; | 92 | } |
149 | + riscv_cpu_validate_set_extensions(cpu, &local_err); | 93 | |
150 | + if (local_err != NULL) { | 94 | +RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno, |
151 | + /* Rollback on validation error */ | 95 | + Int128 *ret_value) |
152 | + qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value " | 96 | +{ |
153 | + "0x%x, keeping existing MISA ext 0x%x\n", | 97 | + RISCVException ret; |
154 | + env->misa_ext, orig_misa_ext); | ||
155 | + | 98 | + |
156 | + env->misa_ext = orig_misa_ext; | 99 | + ret = riscv_csrrw_check(env, csrno, false); |
157 | + | 100 | + if (ret != RISCV_EXCP_NONE) { |
158 | + return RISCV_EXCP_NONE; | 101 | + return ret; |
159 | + } | 102 | + } |
160 | + | 103 | + |
161 | + if (!(env->misa_ext & RVF)) { | 104 | + if (csr_ops[csrno].read128) { |
162 | env->mstatus &= ~MSTATUS_FS; | 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; | ||
163 | } | 136 | } |
164 | 137 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c | |
165 | /* flush translation cache */ | 138 | index XXXXXXX..XXXXXXX 100644 |
166 | tb_flush(env_cpu(env)); | 139 | --- a/target/riscv/op_helper.c |
167 | - env->misa_ext = val; | 140 | +++ b/target/riscv/op_helper.c |
168 | env->xl = riscv_cpu_mxl(env); | 141 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr) |
169 | return RISCV_EXCP_NONE; | 142 | } |
170 | } | 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()); | ||
171 | -- | 161 | -- |
172 | 2.40.1 | 162 | 2.45.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | PMP entries before (including) the matched PMP entry may only cover partial | ||
4 | of the TLB page, and this may split the page into regions with different | ||
5 | permissions. Such as for PMP0 (0x80000008~0x8000000F, R) and PMP1 (0x80000000~ | ||
6 | 0x80000FFF, RWX), write access to 0x80000000 will match PMP1. However we cannot | ||
7 | cache the translation result in the TLB since this will make the write access | ||
8 | to 0x80000008 bypass the check of PMP0. So we should check all of them instead | ||
9 | of the matched PMP entry in pmp_get_tlb_size() and set the tlb_size to 1 in | ||
10 | this case. | ||
11 | Set tlb_size to TARGET_PAGE_SIZE if PMP is not support or there is no PMP rules. | ||
12 | |||
13 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
14 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
15 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
16 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | Message-Id: <20230517091519.34439-2-liweiwei@iscas.ac.cn> | ||
18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | --- | ||
20 | target/riscv/pmp.h | 3 +- | ||
21 | target/riscv/cpu_helper.c | 7 ++-- | ||
22 | target/riscv/pmp.c | 69 ++++++++++++++++++++++++++++++--------- | ||
23 | 3 files changed, 57 insertions(+), 22 deletions(-) | ||
24 | |||
25 | diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/target/riscv/pmp.h | ||
28 | +++ b/target/riscv/pmp.h | ||
29 | @@ -XXX,XX +XXX,XX @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
30 | target_ulong size, pmp_priv_t privs, | ||
31 | pmp_priv_t *allowed_privs, | ||
32 | target_ulong mode); | ||
33 | -target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index, | ||
34 | - target_ulong tlb_sa, target_ulong tlb_ea); | ||
35 | +target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr); | ||
36 | void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index); | ||
37 | void pmp_update_rule_nums(CPURISCVState *env); | ||
38 | uint32_t pmp_get_num_rules(CPURISCVState *env); | ||
39 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/target/riscv/cpu_helper.c | ||
42 | +++ b/target/riscv/cpu_helper.c | ||
43 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, | ||
44 | } | ||
45 | |||
46 | *prot = pmp_priv_to_page_prot(pmp_priv); | ||
47 | - if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) { | ||
48 | - target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1); | ||
49 | - target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1; | ||
50 | - | ||
51 | - *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea); | ||
52 | + if (tlb_size != NULL) { | ||
53 | + *tlb_size = pmp_get_tlb_size(env, addr); | ||
54 | } | ||
55 | |||
56 | return TRANSLATE_SUCCESS; | ||
57 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/target/riscv/pmp.c | ||
60 | +++ b/target/riscv/pmp.c | ||
61 | @@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env) | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | - * Calculate the TLB size if the start address or the end address of | ||
66 | - * PMP entry is presented in the TLB page. | ||
67 | + * Calculate the TLB size. | ||
68 | + * It's possible that PMP regions only cover partial of the TLB page, and | ||
69 | + * this may split the page into regions with different permissions. | ||
70 | + * For example if PMP0 is (0x80000008~0x8000000F, R) and PMP1 is (0x80000000 | ||
71 | + * ~0x80000FFF, RWX), then region 0x80000008~0x8000000F has R permission, and | ||
72 | + * the other regions in this page have RWX permissions. | ||
73 | + * A write access to 0x80000000 will match PMP1. However we cannot cache the | ||
74 | + * translation result in the TLB since this will make the write access to | ||
75 | + * 0x80000008 bypass the check of PMP0. | ||
76 | + * To avoid this we return a size of 1 (which means no caching) if the PMP | ||
77 | + * region only covers partial of the TLB page. | ||
78 | */ | ||
79 | -target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index, | ||
80 | - target_ulong tlb_sa, target_ulong tlb_ea) | ||
81 | +target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr) | ||
82 | { | ||
83 | - target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa; | ||
84 | - target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea; | ||
85 | + target_ulong pmp_sa; | ||
86 | + target_ulong pmp_ea; | ||
87 | + target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1); | ||
88 | + target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1; | ||
89 | + int i; | ||
90 | |||
91 | - if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) { | ||
92 | + /* | ||
93 | + * If PMP is not supported or there are no PMP rules, the TLB page will not | ||
94 | + * be split into regions with different permissions by PMP so we set the | ||
95 | + * size to TARGET_PAGE_SIZE. | ||
96 | + */ | ||
97 | + if (!riscv_cpu_cfg(env)->pmp || !pmp_get_num_rules(env)) { | ||
98 | return TARGET_PAGE_SIZE; | ||
99 | - } else { | ||
100 | + } | ||
101 | + | ||
102 | + for (i = 0; i < MAX_RISCV_PMPS; i++) { | ||
103 | + if (pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg) == PMP_AMATCH_OFF) { | ||
104 | + continue; | ||
105 | + } | ||
106 | + | ||
107 | + pmp_sa = env->pmp_state.addr[i].sa; | ||
108 | + pmp_ea = env->pmp_state.addr[i].ea; | ||
109 | + | ||
110 | /* | ||
111 | - * At this point we have a tlb_size that is the smallest possible size | ||
112 | - * That fits within a TARGET_PAGE_SIZE and the PMP region. | ||
113 | - * | ||
114 | - * If the size is less then TARGET_PAGE_SIZE we drop the size to 1. | ||
115 | - * This means the result isn't cached in the TLB and is only used for | ||
116 | - * a single translation. | ||
117 | + * Only the first PMP entry that covers (whole or partial of) the TLB | ||
118 | + * page really matters: | ||
119 | + * If it covers the whole TLB page, set the size to TARGET_PAGE_SIZE, | ||
120 | + * since the following PMP entries have lower priority and will not | ||
121 | + * affect the permissions of the page. | ||
122 | + * If it only covers partial of the TLB page, set the size to 1 since | ||
123 | + * the allowed permissions of the region may be different from other | ||
124 | + * region of the page. | ||
125 | */ | ||
126 | - return 1; | ||
127 | + if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) { | ||
128 | + return TARGET_PAGE_SIZE; | ||
129 | + } else if ((pmp_sa >= tlb_sa && pmp_sa <= tlb_ea) || | ||
130 | + (pmp_ea >= tlb_sa && pmp_ea <= tlb_ea)) { | ||
131 | + return 1; | ||
132 | + } | ||
133 | } | ||
134 | + | ||
135 | + /* | ||
136 | + * If no PMP entry matches the TLB page, the TLB page will also not be | ||
137 | + * split into regions with different permissions by PMP so we set the size | ||
138 | + * to TARGET_PAGE_SIZE. | ||
139 | + */ | ||
140 | + return TARGET_PAGE_SIZE; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | -- | ||
145 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Return the result directly for short cut, since We needn't do the | ||
4 | following check on the PMP entries if there is no PMP rules. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20230517091519.34439-4-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/pmp.c | 1 + | ||
13 | 1 file changed, 1 insertion(+) | ||
14 | |||
15 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/pmp.c | ||
18 | +++ b/target/riscv/pmp.c | ||
19 | @@ -XXX,XX +XXX,XX @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
20 | allowed_privs, mode)) { | ||
21 | ret = MAX_RISCV_PMPS; | ||
22 | } | ||
23 | + return ret; | ||
24 | } | ||
25 | |||
26 | if (size == 0) { | ||
27 | -- | ||
28 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | We no longer need the pmp_index for matched PMP entry now. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20230517091519.34439-5-liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/pmp.h | 8 ++++---- | ||
12 | target/riscv/cpu_helper.c | 8 ++++---- | ||
13 | target/riscv/pmp.c | 32 +++++++++++++------------------- | ||
14 | 3 files changed, 21 insertions(+), 27 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/pmp.h | ||
19 | +++ b/target/riscv/pmp.h | ||
20 | @@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env); | ||
21 | void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
22 | target_ulong val); | ||
23 | target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index); | ||
24 | -int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
25 | - target_ulong size, pmp_priv_t privs, | ||
26 | - pmp_priv_t *allowed_privs, | ||
27 | - target_ulong mode); | ||
28 | +bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
29 | + target_ulong size, pmp_priv_t privs, | ||
30 | + pmp_priv_t *allowed_privs, | ||
31 | + target_ulong mode); | ||
32 | target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr); | ||
33 | void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index); | ||
34 | void pmp_update_rule_nums(CPURISCVState *env); | ||
35 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/target/riscv/cpu_helper.c | ||
38 | +++ b/target/riscv/cpu_helper.c | ||
39 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr, | ||
40 | int mode) | ||
41 | { | ||
42 | pmp_priv_t pmp_priv; | ||
43 | - int pmp_index = -1; | ||
44 | + bool pmp_has_privs; | ||
45 | |||
46 | if (!riscv_cpu_cfg(env)->pmp) { | ||
47 | *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | ||
48 | return TRANSLATE_SUCCESS; | ||
49 | } | ||
50 | |||
51 | - pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type, | ||
52 | - &pmp_priv, mode); | ||
53 | - if (pmp_index < 0) { | ||
54 | + pmp_has_privs = pmp_hart_has_privs(env, addr, size, 1 << access_type, | ||
55 | + &pmp_priv, mode); | ||
56 | + if (!pmp_has_privs) { | ||
57 | *prot = 0; | ||
58 | return TRANSLATE_PMP_FAIL; | ||
59 | } | ||
60 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/target/riscv/pmp.c | ||
63 | +++ b/target/riscv/pmp.c | ||
64 | @@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr, | ||
65 | |||
66 | /* | ||
67 | * Check if the address has required RWX privs to complete desired operation | ||
68 | - * Return PMP rule index if a pmp rule match | ||
69 | - * Return MAX_RISCV_PMPS if default match | ||
70 | - * Return negtive value if no match | ||
71 | + * Return true if a pmp rule match or default match | ||
72 | + * Return false if no match | ||
73 | */ | ||
74 | -int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
75 | - target_ulong size, pmp_priv_t privs, | ||
76 | - pmp_priv_t *allowed_privs, target_ulong mode) | ||
77 | +bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
78 | + target_ulong size, pmp_priv_t privs, | ||
79 | + pmp_priv_t *allowed_privs, target_ulong mode) | ||
80 | { | ||
81 | int i = 0; | ||
82 | - int ret = -1; | ||
83 | + bool ret = false; | ||
84 | int pmp_size = 0; | ||
85 | target_ulong s = 0; | ||
86 | target_ulong e = 0; | ||
87 | |||
88 | /* Short cut if no rules */ | ||
89 | if (0 == pmp_get_num_rules(env)) { | ||
90 | - if (pmp_hart_has_privs_default(env, addr, size, privs, | ||
91 | - allowed_privs, mode)) { | ||
92 | - ret = MAX_RISCV_PMPS; | ||
93 | - } | ||
94 | - return ret; | ||
95 | + return pmp_hart_has_privs_default(env, addr, size, privs, | ||
96 | + allowed_privs, mode); | ||
97 | } | ||
98 | |||
99 | if (size == 0) { | ||
100 | @@ -XXX,XX +XXX,XX @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
101 | if ((s + e) == 1) { | ||
102 | qemu_log_mask(LOG_GUEST_ERROR, | ||
103 | "pmp violation - access is partially inside\n"); | ||
104 | - ret = -1; | ||
105 | + ret = false; | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | @@ -XXX,XX +XXX,XX @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
110 | * defined with PMP must be used. We shouldn't fallback on | ||
111 | * finding default privileges. | ||
112 | */ | ||
113 | - ret = i; | ||
114 | + ret = true; | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* No rule matched */ | ||
120 | - if (ret == -1) { | ||
121 | - if (pmp_hart_has_privs_default(env, addr, size, privs, | ||
122 | - allowed_privs, mode)) { | ||
123 | - ret = MAX_RISCV_PMPS; | ||
124 | - } | ||
125 | + if (!ret) { | ||
126 | + ret = pmp_hart_has_privs_default(env, addr, size, privs, | ||
127 | + allowed_privs, mode); | ||
128 | } | ||
129 | |||
130 | return ret; | ||
131 | -- | ||
132 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | RLB/MML/MMWP bits in mseccfg CSR are introduced by Smepmp extension. | ||
4 | So they can only be writable and set to 1s when cfg.epmp is true. | ||
5 | Then we also need't check on epmp in pmp_hart_has_privs_default(). | ||
6 | |||
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230517091519.34439-6-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/pmp.c | 50 ++++++++++++++++++++++++---------------------- | ||
14 | 1 file changed, 26 insertions(+), 24 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/pmp.c | ||
19 | +++ b/target/riscv/pmp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr, | ||
21 | { | ||
22 | bool ret; | ||
23 | |||
24 | - if (riscv_cpu_cfg(env)->epmp) { | ||
25 | - if (MSECCFG_MMWP_ISSET(env)) { | ||
26 | - /* | ||
27 | - * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set | ||
28 | - * so we default to deny all, even for M-mode. | ||
29 | - */ | ||
30 | + if (MSECCFG_MMWP_ISSET(env)) { | ||
31 | + /* | ||
32 | + * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set | ||
33 | + * so we default to deny all, even for M-mode. | ||
34 | + */ | ||
35 | + *allowed_privs = 0; | ||
36 | + return false; | ||
37 | + } else if (MSECCFG_MML_ISSET(env)) { | ||
38 | + /* | ||
39 | + * The Machine Mode Lockdown (mseccfg.MML) bit is set | ||
40 | + * so we can only execute code in M-mode with an applicable | ||
41 | + * rule. Other modes are disabled. | ||
42 | + */ | ||
43 | + if (mode == PRV_M && !(privs & PMP_EXEC)) { | ||
44 | + ret = true; | ||
45 | + *allowed_privs = PMP_READ | PMP_WRITE; | ||
46 | + } else { | ||
47 | + ret = false; | ||
48 | *allowed_privs = 0; | ||
49 | - return false; | ||
50 | - } else if (MSECCFG_MML_ISSET(env)) { | ||
51 | - /* | ||
52 | - * The Machine Mode Lockdown (mseccfg.MML) bit is set | ||
53 | - * so we can only execute code in M-mode with an applicable | ||
54 | - * rule. Other modes are disabled. | ||
55 | - */ | ||
56 | - if (mode == PRV_M && !(privs & PMP_EXEC)) { | ||
57 | - ret = true; | ||
58 | - *allowed_privs = PMP_READ | PMP_WRITE; | ||
59 | - } else { | ||
60 | - ret = false; | ||
61 | - *allowed_privs = 0; | ||
62 | - } | ||
63 | - | ||
64 | - return ret; | ||
65 | } | ||
66 | + | ||
67 | + return ret; | ||
68 | } | ||
69 | |||
70 | if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) { | ||
71 | @@ -XXX,XX +XXX,XX @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) | ||
72 | } | ||
73 | } | ||
74 | |||
75 | - /* Sticky bits */ | ||
76 | - val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML)); | ||
77 | + if (riscv_cpu_cfg(env)->epmp) { | ||
78 | + /* Sticky bits */ | ||
79 | + val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML)); | ||
80 | + } else { | ||
81 | + val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB); | ||
82 | + } | ||
83 | |||
84 | env->mseccfg = val; | ||
85 | } | ||
86 | -- | ||
87 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | The addr and size parameters in pmp_hart_has_privs_default() are unused. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20230517091519.34439-7-liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/pmp.c | 9 +++------ | ||
12 | 1 file changed, 3 insertions(+), 6 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/pmp.c | ||
17 | +++ b/target/riscv/pmp.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, | ||
19 | /* | ||
20 | * Check if the address has required RWX privs when no PMP entry is matched. | ||
21 | */ | ||
22 | -static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr, | ||
23 | - target_ulong size, pmp_priv_t privs, | ||
24 | +static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs, | ||
25 | pmp_priv_t *allowed_privs, | ||
26 | target_ulong mode) | ||
27 | { | ||
28 | @@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
29 | |||
30 | /* Short cut if no rules */ | ||
31 | if (0 == pmp_get_num_rules(env)) { | ||
32 | - return pmp_hart_has_privs_default(env, addr, size, privs, | ||
33 | - allowed_privs, mode); | ||
34 | + return pmp_hart_has_privs_default(env, privs, allowed_privs, mode); | ||
35 | } | ||
36 | |||
37 | if (size == 0) { | ||
38 | @@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
39 | |||
40 | /* No rule matched */ | ||
41 | if (!ret) { | ||
42 | - ret = pmp_hart_has_privs_default(env, addr, size, privs, | ||
43 | - allowed_privs, mode); | ||
44 | + ret = pmp_hart_has_privs_default(env, privs, allowed_privs, mode); | ||
45 | } | ||
46 | |||
47 | return ret; | ||
48 | -- | ||
49 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | MMWP and MML bits may affect the allowed privs of PMP entries and the | ||
4 | default privs, both of which may change the allowed privs of exsited | ||
5 | TLB entries. So we need flush TLB when they are changed. | ||
6 | |||
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230517091519.34439-8-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/pmp.c | 3 +++ | ||
14 | 1 file changed, 3 insertions(+) | ||
15 | |||
16 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/pmp.c | ||
19 | +++ b/target/riscv/pmp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) | ||
21 | if (riscv_cpu_cfg(env)->epmp) { | ||
22 | /* Sticky bits */ | ||
23 | val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML)); | ||
24 | + if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) { | ||
25 | + tlb_flush(env_cpu(env)); | ||
26 | + } | ||
27 | } else { | ||
28 | val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB); | ||
29 | } | ||
30 | -- | ||
31 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Currently only the rule addr of the same index of pmpaddr is updated | ||
4 | when pmpaddr CSR is modified. However, the rule addr of next PMP entry | ||
5 | may also be affected if its A field is PMP_AMATCH_TOR. So we should | ||
6 | also update it in this case. | ||
7 | |||
8 | Write to pmpaddr CSR will not affect the rule nums, So we needn't update | ||
9 | call pmp_update_rule_nums() in pmpaddr_csr_write(). | ||
10 | |||
11 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
12 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Message-Id: <20230517091519.34439-9-liweiwei@iscas.ac.cn> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | target/riscv/pmp.c | 10 +++++++--- | ||
18 | 1 file changed, 7 insertions(+), 3 deletions(-) | ||
19 | |||
20 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/pmp.c | ||
23 | +++ b/target/riscv/pmp.c | ||
24 | @@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
25 | target_ulong val) | ||
26 | { | ||
27 | trace_pmpaddr_csr_write(env->mhartid, addr_index, val); | ||
28 | + bool is_next_cfg_tor = false; | ||
29 | |||
30 | if (addr_index < MAX_RISCV_PMPS) { | ||
31 | /* | ||
32 | @@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
33 | */ | ||
34 | if (addr_index + 1 < MAX_RISCV_PMPS) { | ||
35 | uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg; | ||
36 | + is_next_cfg_tor = PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg); | ||
37 | |||
38 | - if (pmp_cfg & PMP_LOCK && | ||
39 | - PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) { | ||
40 | + if (pmp_cfg & PMP_LOCK && is_next_cfg_tor) { | ||
41 | qemu_log_mask(LOG_GUEST_ERROR, | ||
42 | "ignoring pmpaddr write - pmpcfg + 1 locked\n"); | ||
43 | return; | ||
44 | @@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
45 | |||
46 | if (!pmp_is_locked(env, addr_index)) { | ||
47 | env->pmp_state.pmp[addr_index].addr_reg = val; | ||
48 | - pmp_update_rule(env, addr_index); | ||
49 | + pmp_update_rule_addr(env, addr_index); | ||
50 | + if (is_next_cfg_tor) { | ||
51 | + pmp_update_rule_addr(env, addr_index + 1); | ||
52 | + } | ||
53 | } else { | ||
54 | qemu_log_mask(LOG_GUEST_ERROR, | ||
55 | "ignoring pmpaddr write - locked\n"); | ||
56 | -- | ||
57 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | TLB should be flushed not only for pmpcfg csr changes, but also for | ||
4 | pmpaddr csr changes. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
10 | Message-Id: <20230517091519.34439-10-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/pmp.c | 1 + | ||
14 | 1 file changed, 1 insertion(+) | ||
15 | |||
16 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/pmp.c | ||
19 | +++ b/target/riscv/pmp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
21 | if (is_next_cfg_tor) { | ||
22 | pmp_update_rule_addr(env, addr_index + 1); | ||
23 | } | ||
24 | + tlb_flush(env_cpu(env)); | ||
25 | } else { | ||
26 | qemu_log_mask(LOG_GUEST_ERROR, | ||
27 | "ignoring pmpaddr write - locked\n"); | ||
28 | -- | ||
29 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | TLB needn't be flushed when pmpcfg/pmpaddr don't changes. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Message-Id: <20230517091519.34439-11-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/pmp.c | 28 ++++++++++++++++++---------- | ||
13 | 1 file changed, 18 insertions(+), 10 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/pmp.c | ||
18 | +++ b/target/riscv/pmp.c | ||
19 | @@ -XXX,XX +XXX,XX @@ | ||
20 | #include "trace.h" | ||
21 | #include "exec/exec-all.h" | ||
22 | |||
23 | -static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index, | ||
24 | +static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index, | ||
25 | uint8_t val); | ||
26 | static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index); | ||
27 | static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index); | ||
28 | @@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index) | ||
29 | * Accessor to set the cfg reg for a specific PMP/HART | ||
30 | * Bounds checks and relevant lock bit. | ||
31 | */ | ||
32 | -static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) | ||
33 | +static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) | ||
34 | { | ||
35 | if (pmp_index < MAX_RISCV_PMPS) { | ||
36 | bool locked = true; | ||
37 | @@ -XXX,XX +XXX,XX @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) | ||
38 | |||
39 | if (locked) { | ||
40 | qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n"); | ||
41 | - } else { | ||
42 | + } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) { | ||
43 | env->pmp_state.pmp[pmp_index].cfg_reg = val; | ||
44 | pmp_update_rule(env, pmp_index); | ||
45 | + return true; | ||
46 | } | ||
47 | } else { | ||
48 | qemu_log_mask(LOG_GUEST_ERROR, | ||
49 | "ignoring pmpcfg write - out of bounds\n"); | ||
50 | } | ||
51 | + | ||
52 | + return false; | ||
53 | } | ||
54 | |||
55 | static void pmp_decode_napot(target_ulong a, target_ulong *sa, | ||
56 | @@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index, | ||
57 | int i; | ||
58 | uint8_t cfg_val; | ||
59 | int pmpcfg_nums = 2 << riscv_cpu_mxl(env); | ||
60 | + bool modified = false; | ||
61 | |||
62 | trace_pmpcfg_csr_write(env->mhartid, reg_index, val); | ||
63 | |||
64 | for (i = 0; i < pmpcfg_nums; i++) { | ||
65 | cfg_val = (val >> 8 * i) & 0xff; | ||
66 | - pmp_write_cfg(env, (reg_index * 4) + i, cfg_val); | ||
67 | + modified |= pmp_write_cfg(env, (reg_index * 4) + i, cfg_val); | ||
68 | } | ||
69 | |||
70 | /* If PMP permission of any addr has been changed, flush TLB pages. */ | ||
71 | - tlb_flush(env_cpu(env)); | ||
72 | + if (modified) { | ||
73 | + tlb_flush(env_cpu(env)); | ||
74 | + } | ||
75 | } | ||
76 | |||
77 | |||
78 | @@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
79 | } | ||
80 | |||
81 | if (!pmp_is_locked(env, addr_index)) { | ||
82 | - env->pmp_state.pmp[addr_index].addr_reg = val; | ||
83 | - pmp_update_rule_addr(env, addr_index); | ||
84 | - if (is_next_cfg_tor) { | ||
85 | - pmp_update_rule_addr(env, addr_index + 1); | ||
86 | + if (env->pmp_state.pmp[addr_index].addr_reg != val) { | ||
87 | + env->pmp_state.pmp[addr_index].addr_reg = val; | ||
88 | + pmp_update_rule_addr(env, addr_index); | ||
89 | + if (is_next_cfg_tor) { | ||
90 | + pmp_update_rule_addr(env, addr_index + 1); | ||
91 | + } | ||
92 | + tlb_flush(env_cpu(env)); | ||
93 | } | ||
94 | - tlb_flush(env_cpu(env)); | ||
95 | } else { | ||
96 | qemu_log_mask(LOG_GUEST_ERROR, | ||
97 | "ignoring pmpaddr write - locked\n"); | ||
98 | -- | ||
99 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Use pmp_update_rule_addr() and pmp_update_rule_nums() separately to | ||
4 | update rule nums only once for each pmpcfg_csr_write. Then remove | ||
5 | pmp_update_rule() since it become unused. | ||
6 | |||
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230517091519.34439-12-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/pmp.c | 16 ++-------------- | ||
14 | 1 file changed, 2 insertions(+), 14 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/pmp.c | ||
19 | +++ b/target/riscv/pmp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index, | ||
22 | uint8_t val); | ||
23 | static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index); | ||
24 | -static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index); | ||
25 | |||
26 | /* | ||
27 | * Accessor method to extract address matching type 'a field' from cfg reg | ||
28 | @@ -XXX,XX +XXX,XX @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) | ||
29 | qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n"); | ||
30 | } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) { | ||
31 | env->pmp_state.pmp[pmp_index].cfg_reg = val; | ||
32 | - pmp_update_rule(env, pmp_index); | ||
33 | + pmp_update_rule_addr(env, pmp_index); | ||
34 | return true; | ||
35 | } | ||
36 | } else { | ||
37 | @@ -XXX,XX +XXX,XX @@ void pmp_update_rule_nums(CPURISCVState *env) | ||
38 | } | ||
39 | } | ||
40 | |||
41 | -/* | ||
42 | - * Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea' | ||
43 | - * end address values. | ||
44 | - * This function is called relatively infrequently whereas the check that | ||
45 | - * an address is within a pmp rule is called often, so optimise that one | ||
46 | - */ | ||
47 | -static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index) | ||
48 | -{ | ||
49 | - pmp_update_rule_addr(env, pmp_index); | ||
50 | - pmp_update_rule_nums(env); | ||
51 | -} | ||
52 | - | ||
53 | static int pmp_is_in_range(CPURISCVState *env, int pmp_index, | ||
54 | target_ulong addr) | ||
55 | { | ||
56 | @@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index, | ||
57 | |||
58 | /* If PMP permission of any addr has been changed, flush TLB pages. */ | ||
59 | if (modified) { | ||
60 | + pmp_update_rule_nums(env); | ||
61 | tlb_flush(env_cpu(env)); | ||
62 | } | ||
63 | } | ||
64 | -- | ||
65 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Access will fail if access is partially inside the PMP entry. | ||
4 | However,only setting ret = false doesn't really mean pmp violation | ||
5 | since pmp_hart_has_privs_default() may return true at the end of | ||
6 | pmp_hart_has_privs(). | ||
7 | |||
8 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-Id: <20230517091519.34439-13-liweiwei@iscas.ac.cn> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/pmp.c | 4 ++-- | ||
15 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/pmp.c | ||
20 | +++ b/target/riscv/pmp.c | ||
21 | @@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
22 | if ((s + e) == 1) { | ||
23 | qemu_log_mask(LOG_GUEST_ERROR, | ||
24 | "pmp violation - access is partially inside\n"); | ||
25 | - ret = false; | ||
26 | - break; | ||
27 | + *allowed_privs = 0; | ||
28 | + return false; | ||
29 | } | ||
30 | |||
31 | /* fully inside */ | ||
32 | -- | ||
33 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
2 | 1 | ||
3 | When multiple QOM types are registered in the same file, | ||
4 | it is simpler to use the the DEFINE_TYPES() macro. Replace | ||
5 | the type_init() / type_register_static() combination. This | ||
6 | is in preparation of adding the OpenTitan machine type to | ||
7 | this array in a pair of commits. | ||
8 | |||
9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
12 | Message-Id: <20230520054510.68822-3-philmd@linaro.org> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | hw/riscv/opentitan.c | 21 +++++++++------------ | ||
16 | 1 file changed, 9 insertions(+), 12 deletions(-) | ||
17 | |||
18 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/riscv/opentitan.c | ||
21 | +++ b/hw/riscv/opentitan.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data) | ||
23 | dc->user_creatable = false; | ||
24 | } | ||
25 | |||
26 | -static const TypeInfo lowrisc_ibex_soc_type_info = { | ||
27 | - .name = TYPE_RISCV_IBEX_SOC, | ||
28 | - .parent = TYPE_DEVICE, | ||
29 | - .instance_size = sizeof(LowRISCIbexSoCState), | ||
30 | - .instance_init = lowrisc_ibex_soc_init, | ||
31 | - .class_init = lowrisc_ibex_soc_class_init, | ||
32 | +static const TypeInfo open_titan_types[] = { | ||
33 | + { | ||
34 | + .name = TYPE_RISCV_IBEX_SOC, | ||
35 | + .parent = TYPE_DEVICE, | ||
36 | + .instance_size = sizeof(LowRISCIbexSoCState), | ||
37 | + .instance_init = lowrisc_ibex_soc_init, | ||
38 | + .class_init = lowrisc_ibex_soc_class_init, | ||
39 | + } | ||
40 | }; | ||
41 | |||
42 | -static void lowrisc_ibex_soc_register_types(void) | ||
43 | -{ | ||
44 | - type_register_static(&lowrisc_ibex_soc_type_info); | ||
45 | -} | ||
46 | - | ||
47 | -type_init(lowrisc_ibex_soc_register_types) | ||
48 | +DEFINE_TYPES(open_titan_types) | ||
49 | -- | ||
50 | 2.40.1 | ||
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
2 | 1 | ||
3 | QOM type names are usually defined as TYPE_FOO. | ||
4 | |||
5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Message-Id: <20230520054510.68822-4-philmd@linaro.org> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | include/hw/riscv/opentitan.h | 2 ++ | ||
12 | hw/riscv/opentitan.c | 2 +- | ||
13 | 2 files changed, 3 insertions(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/hw/riscv/opentitan.h | ||
18 | +++ b/include/hw/riscv/opentitan.h | ||
19 | @@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState { | ||
20 | MemoryRegion flash_alias; | ||
21 | }; | ||
22 | |||
23 | +#define TYPE_OPENTITAN_MACHINE "opentitan" | ||
24 | + | ||
25 | typedef struct OpenTitanState { | ||
26 | /*< private >*/ | ||
27 | SysBusDevice parent_obj; | ||
28 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/hw/riscv/opentitan.c | ||
31 | +++ b/hw/riscv/opentitan.c | ||
32 | @@ -XXX,XX +XXX,XX @@ static void opentitan_machine_class_init(MachineClass *mc) | ||
33 | mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size; | ||
34 | } | ||
35 | |||
36 | -DEFINE_MACHINE("opentitan", opentitan_machine_class_init) | ||
37 | +DEFINE_MACHINE(TYPE_OPENTITAN_MACHINE, opentitan_machine_class_init) | ||
38 | |||
39 | static void lowrisc_ibex_soc_init(Object *obj) | ||
40 | { | ||
41 | -- | ||
42 | 2.40.1 | ||
43 | |||
44 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
2 | 1 | ||
3 | Expand the DEFINE_MACHINE() macro, converting the class_init() | ||
4 | handler. | ||
5 | |||
6 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Message-Id: <20230520054510.68822-5-philmd@linaro.org> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | include/hw/riscv/opentitan.h | 3 ++- | ||
13 | hw/riscv/opentitan.c | 10 +++++++--- | ||
14 | 2 files changed, 9 insertions(+), 4 deletions(-) | ||
15 | |||
16 | diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/hw/riscv/opentitan.h | ||
19 | +++ b/include/hw/riscv/opentitan.h | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | #include "hw/char/ibex_uart.h" | ||
22 | #include "hw/timer/ibex_timer.h" | ||
23 | #include "hw/ssi/ibex_spi_host.h" | ||
24 | +#include "hw/boards.h" | ||
25 | #include "qom/object.h" | ||
26 | |||
27 | #define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc" | ||
28 | @@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState { | ||
29 | MemoryRegion flash_alias; | ||
30 | }; | ||
31 | |||
32 | -#define TYPE_OPENTITAN_MACHINE "opentitan" | ||
33 | +#define TYPE_OPENTITAN_MACHINE MACHINE_TYPE_NAME("opentitan") | ||
34 | |||
35 | typedef struct OpenTitanState { | ||
36 | /*< private >*/ | ||
37 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/hw/riscv/opentitan.c | ||
40 | +++ b/hw/riscv/opentitan.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineState *machine) | ||
42 | } | ||
43 | } | ||
44 | |||
45 | -static void opentitan_machine_class_init(MachineClass *mc) | ||
46 | +static void opentitan_machine_class_init(ObjectClass *oc, void *data) | ||
47 | { | ||
48 | + MachineClass *mc = MACHINE_CLASS(oc); | ||
49 | + | ||
50 | mc->desc = "RISC-V Board compatible with OpenTitan"; | ||
51 | mc->init = opentitan_machine_init; | ||
52 | mc->max_cpus = 1; | ||
53 | @@ -XXX,XX +XXX,XX @@ static void opentitan_machine_class_init(MachineClass *mc) | ||
54 | mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size; | ||
55 | } | ||
56 | |||
57 | -DEFINE_MACHINE(TYPE_OPENTITAN_MACHINE, opentitan_machine_class_init) | ||
58 | - | ||
59 | static void lowrisc_ibex_soc_init(Object *obj) | ||
60 | { | ||
61 | LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj); | ||
62 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo open_titan_types[] = { | ||
63 | .instance_size = sizeof(LowRISCIbexSoCState), | ||
64 | .instance_init = lowrisc_ibex_soc_init, | ||
65 | .class_init = lowrisc_ibex_soc_class_init, | ||
66 | + }, { | ||
67 | + .name = TYPE_OPENTITAN_MACHINE, | ||
68 | + .parent = TYPE_MACHINE, | ||
69 | + .class_init = opentitan_machine_class_init, | ||
70 | } | ||
71 | }; | ||
72 | |||
73 | -- | ||
74 | 2.40.1 | ||
75 | |||
76 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
2 | 1 | ||
3 | OpenTitanState is the 'machine' (or 'board') state: it isn't | ||
4 | a SysBus device, but inherits from the MachineState type. | ||
5 | Correct the instance size. | ||
6 | Doing so we avoid leaking an OpenTitanState pointer in | ||
7 | opentitan_machine_init(). | ||
8 | |||
9 | Fixes: fe0fe4735e ("riscv: Initial commit of OpenTitan machine") | ||
10 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
13 | Message-Id: <20230520054510.68822-6-philmd@linaro.org> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | include/hw/riscv/opentitan.h | 3 ++- | ||
17 | hw/riscv/opentitan.c | 3 ++- | ||
18 | 2 files changed, 4 insertions(+), 2 deletions(-) | ||
19 | |||
20 | diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/include/hw/riscv/opentitan.h | ||
23 | +++ b/include/hw/riscv/opentitan.h | ||
24 | @@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState { | ||
25 | }; | ||
26 | |||
27 | #define TYPE_OPENTITAN_MACHINE MACHINE_TYPE_NAME("opentitan") | ||
28 | +OBJECT_DECLARE_SIMPLE_TYPE(OpenTitanState, OPENTITAN_MACHINE) | ||
29 | |||
30 | typedef struct OpenTitanState { | ||
31 | /*< private >*/ | ||
32 | - SysBusDevice parent_obj; | ||
33 | + MachineState parent_obj; | ||
34 | |||
35 | /*< public >*/ | ||
36 | LowRISCIbexSoCState soc; | ||
37 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/hw/riscv/opentitan.c | ||
40 | +++ b/hw/riscv/opentitan.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = { | ||
42 | static void opentitan_machine_init(MachineState *machine) | ||
43 | { | ||
44 | MachineClass *mc = MACHINE_GET_CLASS(machine); | ||
45 | + OpenTitanState *s = OPENTITAN_MACHINE(machine); | ||
46 | const MemMapEntry *memmap = ibex_memmap; | ||
47 | - OpenTitanState *s = g_new0(OpenTitanState, 1); | ||
48 | MemoryRegion *sys_mem = get_system_memory(); | ||
49 | |||
50 | if (machine->ram_size != mc->default_ram_size) { | ||
51 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo open_titan_types[] = { | ||
52 | }, { | ||
53 | .name = TYPE_OPENTITAN_MACHINE, | ||
54 | .parent = TYPE_MACHINE, | ||
55 | + .instance_size = sizeof(OpenTitanState), | ||
56 | .class_init = opentitan_machine_class_init, | ||
57 | } | ||
58 | }; | ||
59 | -- | ||
60 | 2.40.1 | ||
61 | |||
62 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Yin Wang <yin.wang@intel.com> | ||
2 | 1 | ||
3 | Command "qemu-system-riscv64 -machine virt | ||
4 | -m 2G -smp 1 -numa node,mem=1G -numa node,mem=1G" | ||
5 | would trigger this problem.Backtrace with: | ||
6 | #0 0x0000555555b5b1a4 in riscv_numa_get_default_cpu_node_id at ../hw/riscv/numa.c:211 | ||
7 | #1 0x00005555558ce510 in machine_numa_finish_cpu_init at ../hw/core/machine.c:1230 | ||
8 | #2 0x00005555558ce9d3 in machine_run_board_init at ../hw/core/machine.c:1346 | ||
9 | #3 0x0000555555aaedc3 in qemu_init_board at ../softmmu/vl.c:2513 | ||
10 | #4 0x0000555555aaf064 in qmp_x_exit_preconfig at ../softmmu/vl.c:2609 | ||
11 | #5 0x0000555555ab1916 in qemu_init at ../softmmu/vl.c:3617 | ||
12 | #6 0x000055555585463b in main at ../softmmu/main.c:47 | ||
13 | This commit fixes the issue by adding parameter checks. | ||
14 | |||
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
17 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
18 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
19 | Signed-off-by: Yin Wang <yin.wang@intel.com> | ||
20 | Message-Id: <20230519023758.1759434-1-yin.wang@intel.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | --- | ||
23 | hw/riscv/numa.c | 6 ++++++ | ||
24 | 1 file changed, 6 insertions(+) | ||
25 | |||
26 | diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/hw/riscv/numa.c | ||
29 | +++ b/hw/riscv/numa.c | ||
30 | @@ -XXX,XX +XXX,XX @@ int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx) | ||
31 | { | ||
32 | int64_t nidx = 0; | ||
33 | |||
34 | + if (ms->numa_state->num_nodes > ms->smp.cpus) { | ||
35 | + error_report("Number of NUMA nodes (%d)" | ||
36 | + " cannot exceed the number of available CPUs (%d).", | ||
37 | + ms->numa_state->num_nodes, ms->smp.max_cpus); | ||
38 | + exit(EXIT_FAILURE); | ||
39 | + } | ||
40 | if (ms->numa_state->num_nodes) { | ||
41 | nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes); | ||
42 | if (ms->numa_state->num_nodes <= nidx) { | ||
43 | -- | ||
44 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | actual_address = (requested_address & ~mpmmask) | mpmbase. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Message-Id: <20230524015933.17349-2-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/vector_helper.c | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/vector_helper.c | ||
18 | +++ b/target/riscv/vector_helper.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc, | ||
20 | |||
21 | static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) | ||
22 | { | ||
23 | - return (addr & env->cur_pmmask) | env->cur_pmbase; | ||
24 | + return (addr & ~env->cur_pmmask) | env->cur_pmbase; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | -- | ||
29 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | write_mstatus() can only change current xl when in debug mode. | ||
4 | And we need update cur_pmmask/base in this case. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Message-Id: <20230524015933.17349-3-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/csr.c | 9 ++++++++- | ||
13 | 1 file changed, 8 insertions(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/csr.c | ||
18 | +++ b/target/riscv/csr.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, | ||
20 | mstatus = set_field(mstatus, MSTATUS64_SXL, xl); | ||
21 | } | ||
22 | env->mstatus = mstatus; | ||
23 | - env->xl = cpu_recompute_xl(env); | ||
24 | |||
25 | + /* | ||
26 | + * Except in debug mode, UXL/SXL can only be modified by higher | ||
27 | + * privilege mode. So xl will not be changed in normal mode. | ||
28 | + */ | ||
29 | + if (env->debugger) { | ||
30 | + env->xl = cpu_recompute_xl(env); | ||
31 | + riscv_cpu_update_mask(env); | ||
32 | + } | ||
33 | return RISCV_EXCP_NONE; | ||
34 | } | ||
35 | |||
36 | -- | ||
37 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Pass RISCVCPUConfig as disassemble_info.target_info to support disas | ||
4 | of conflict instructions related to specific extensions. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230523093539.203909-4-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | disas/riscv.c | 10 +++++++--- | ||
14 | target/riscv/cpu.c | 1 + | ||
15 | 2 files changed, 8 insertions(+), 3 deletions(-) | ||
16 | |||
17 | diff --git a/disas/riscv.c b/disas/riscv.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/disas/riscv.c | ||
20 | +++ b/disas/riscv.c | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | |||
23 | #include "qemu/osdep.h" | ||
24 | #include "disas/dis-asm.h" | ||
25 | - | ||
26 | +#include "target/riscv/cpu_cfg.h" | ||
27 | |||
28 | /* types */ | ||
29 | |||
30 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
31 | /* structures */ | ||
32 | |||
33 | typedef struct { | ||
34 | + RISCVCPUConfig *cfg; | ||
35 | uint64_t pc; | ||
36 | uint64_t inst; | ||
37 | int32_t imm; | ||
38 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa) | ||
39 | /* disassemble instruction */ | ||
40 | |||
41 | static void | ||
42 | -disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst) | ||
43 | +disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst, | ||
44 | + RISCVCPUConfig *cfg) | ||
45 | { | ||
46 | rv_decode dec = { 0 }; | ||
47 | dec.pc = pc; | ||
48 | dec.inst = inst; | ||
49 | + dec.cfg = cfg; | ||
50 | decode_inst_opcode(&dec, isa); | ||
51 | decode_inst_operands(&dec, isa); | ||
52 | decode_inst_decompress(&dec, isa); | ||
53 | @@ -XXX,XX +XXX,XX @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa) | ||
54 | break; | ||
55 | } | ||
56 | |||
57 | - disasm_inst(buf, sizeof(buf), isa, memaddr, inst); | ||
58 | + disasm_inst(buf, sizeof(buf), isa, memaddr, inst, | ||
59 | + (RISCVCPUConfig *)info->target_info); | ||
60 | (*info->fprintf_func)(info->stream, "%s", buf); | ||
61 | |||
62 | return len; | ||
63 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
64 | index XXXXXXX..XXXXXXX 100644 | ||
65 | --- a/target/riscv/cpu.c | ||
66 | +++ b/target/riscv/cpu.c | ||
67 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj) | ||
68 | static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) | ||
69 | { | ||
70 | RISCVCPU *cpu = RISCV_CPU(s); | ||
71 | + info->target_info = &cpu->cfg; | ||
72 | |||
73 | switch (riscv_cpu_mxl(&cpu->env)) { | ||
74 | case MXL_RV32: | ||
75 | -- | ||
76 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Support disas for Zcmt* instructions only when related extensions | ||
4 | are supported. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230523093539.203909-5-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | disas/riscv.c | 8 +++++++- | ||
14 | 1 file changed, 7 insertions(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/disas/riscv.c b/disas/riscv.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/disas/riscv.c | ||
19 | +++ b/disas/riscv.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
21 | op = rv_op_c_sqsp; | ||
22 | } else { | ||
23 | op = rv_op_c_fsdsp; | ||
24 | - if (((inst >> 12) & 0b01)) { | ||
25 | + if (dec->cfg->ext_zcmp && ((inst >> 12) & 0b01)) { | ||
26 | switch ((inst >> 8) & 0b01111) { | ||
27 | case 8: | ||
28 | if (((inst >> 4) & 0b01111) >= 4) { | ||
29 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
30 | } else { | ||
31 | switch ((inst >> 10) & 0b011) { | ||
32 | case 0: | ||
33 | + if (!dec->cfg->ext_zcmt) { | ||
34 | + break; | ||
35 | + } | ||
36 | if (((inst >> 2) & 0xFF) >= 32) { | ||
37 | op = rv_op_cm_jalt; | ||
38 | } else { | ||
39 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
40 | } | ||
41 | break; | ||
42 | case 3: | ||
43 | + if (!dec->cfg->ext_zcmp) { | ||
44 | + break; | ||
45 | + } | ||
46 | switch ((inst >> 5) & 0b011) { | ||
47 | case 1: op = rv_op_cm_mvsa01; break; | ||
48 | case 3: op = rv_op_cm_mva01s; break; | ||
49 | -- | ||
50 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Support disas for Z*inx instructions only when Zfinx extension is supported. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20230523093539.203909-6-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | disas/riscv.c | 16 ++++++++++++---- | ||
13 | 1 file changed, 12 insertions(+), 4 deletions(-) | ||
14 | |||
15 | diff --git a/disas/riscv.c b/disas/riscv.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/disas/riscv.c | ||
18 | +++ b/disas/riscv.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec) | ||
20 | append(buf, rv_ireg_name_sym[dec->rs2], buflen); | ||
21 | break; | ||
22 | case '3': | ||
23 | - append(buf, rv_freg_name_sym[dec->rd], buflen); | ||
24 | + append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rd] : | ||
25 | + rv_freg_name_sym[dec->rd], | ||
26 | + buflen); | ||
27 | break; | ||
28 | case '4': | ||
29 | - append(buf, rv_freg_name_sym[dec->rs1], buflen); | ||
30 | + append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs1] : | ||
31 | + rv_freg_name_sym[dec->rs1], | ||
32 | + buflen); | ||
33 | break; | ||
34 | case '5': | ||
35 | - append(buf, rv_freg_name_sym[dec->rs2], buflen); | ||
36 | + append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs2] : | ||
37 | + rv_freg_name_sym[dec->rs2], | ||
38 | + buflen); | ||
39 | break; | ||
40 | case '6': | ||
41 | - append(buf, rv_freg_name_sym[dec->rs3], buflen); | ||
42 | + append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs3] : | ||
43 | + rv_freg_name_sym[dec->rs3], | ||
44 | + buflen); | ||
45 | break; | ||
46 | case '7': | ||
47 | snprintf(tmp, sizeof(tmp), "%d", dec->rs1); | ||
48 | -- | ||
49 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Currently decomp_rv32 and decomp_rv64 value in opcode_data for vector | ||
4 | instructions are the same op index as their own. And they have no | ||
5 | functional decomp_data. So they have no functional difference from just | ||
6 | leaving them as zero. | ||
7 | |||
8 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
11 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20230523093539.203909-7-liweiwei@iscas.ac.cn> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | disas/riscv.c | 740 +++++++++++++++++++++++++------------------------- | ||
16 | 1 file changed, 370 insertions(+), 370 deletions(-) | ||
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 @@ const rv_opcode_data opcode_data[] = { | ||
23 | { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
24 | { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
25 | { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
26 | - { "vle8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle8_v, rv_op_vle8_v, 0 }, | ||
27 | - { "vle16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle16_v, rv_op_vle16_v, 0 }, | ||
28 | - { "vle32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle32_v, rv_op_vle32_v, 0 }, | ||
29 | - { "vle64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle64_v, rv_op_vle64_v, 0 }, | ||
30 | - { "vse8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse8_v, rv_op_vse8_v, 0 }, | ||
31 | - { "vse16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse16_v, rv_op_vse16_v, 0 }, | ||
32 | - { "vse32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse32_v, rv_op_vse32_v, 0 }, | ||
33 | - { "vse64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse64_v, rv_op_vse64_v, 0 }, | ||
34 | - { "vlm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vlm_v, rv_op_vlm_v, 0 }, | ||
35 | - { "vsm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vsm_v, rv_op_vsm_v, 0 }, | ||
36 | - { "vlse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse8_v, rv_op_vlse8_v, 0 }, | ||
37 | - { "vlse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse16_v, rv_op_vlse16_v, 0 }, | ||
38 | - { "vlse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse32_v, rv_op_vlse32_v, 0 }, | ||
39 | - { "vlse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse64_v, rv_op_vlse64_v, 0 }, | ||
40 | - { "vsse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse8_v, rv_op_vsse8_v, 0 }, | ||
41 | - { "vsse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse16_v, rv_op_vsse16_v, 0 }, | ||
42 | - { "vsse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse32_v, rv_op_vsse32_v, 0 }, | ||
43 | - { "vsse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse64_v, rv_op_vsse64_v, 0 }, | ||
44 | - { "vluxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei8_v, rv_op_vluxei8_v, 0 }, | ||
45 | - { "vluxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei16_v, rv_op_vluxei16_v, 0 }, | ||
46 | - { "vluxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei32_v, rv_op_vluxei32_v, 0 }, | ||
47 | - { "vluxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei64_v, rv_op_vluxei64_v, 0 }, | ||
48 | - { "vloxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei8_v, rv_op_vloxei8_v, 0 }, | ||
49 | - { "vloxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei16_v, rv_op_vloxei16_v, 0 }, | ||
50 | - { "vloxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei32_v, rv_op_vloxei32_v, 0 }, | ||
51 | - { "vloxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei64_v, rv_op_vloxei64_v, 0 }, | ||
52 | - { "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei8_v, rv_op_vsuxei8_v, 0 }, | ||
53 | - { "vsuxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei16_v, rv_op_vsuxei16_v, 0 }, | ||
54 | - { "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei32_v, rv_op_vsuxei32_v, 0 }, | ||
55 | - { "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei64_v, rv_op_vsuxei64_v, 0 }, | ||
56 | - { "vsoxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei8_v, rv_op_vsoxei8_v, 0 }, | ||
57 | - { "vsoxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei16_v, rv_op_vsoxei16_v, 0 }, | ||
58 | - { "vsoxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei32_v, rv_op_vsoxei32_v, 0 }, | ||
59 | - { "vsoxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei64_v, rv_op_vsoxei64_v, 0 }, | ||
60 | - { "vle8ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle8ff_v, rv_op_vle8ff_v, 0 }, | ||
61 | - { "vle16ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle16ff_v, rv_op_vle16ff_v, 0 }, | ||
62 | - { "vle32ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle32ff_v, rv_op_vle32ff_v, 0 }, | ||
63 | - { "vle64ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle64ff_v, rv_op_vle64ff_v, 0 }, | ||
64 | - { "vl1re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re8_v, rv_op_vl1re8_v, 0 }, | ||
65 | - { "vl1re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re16_v, rv_op_vl1re16_v, 0 }, | ||
66 | - { "vl1re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re32_v, rv_op_vl1re32_v, 0 }, | ||
67 | - { "vl1re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re64_v, rv_op_vl1re64_v, 0 }, | ||
68 | - { "vl2re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re8_v, rv_op_vl2re8_v, 0 }, | ||
69 | - { "vl2re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re16_v, rv_op_vl2re16_v, 0 }, | ||
70 | - { "vl2re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re32_v, rv_op_vl2re32_v, 0 }, | ||
71 | - { "vl2re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re64_v, rv_op_vl2re64_v, 0 }, | ||
72 | - { "vl4re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re8_v, rv_op_vl4re8_v, 0 }, | ||
73 | - { "vl4re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re16_v, rv_op_vl4re16_v, 0 }, | ||
74 | - { "vl4re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re32_v, rv_op_vl4re32_v, 0 }, | ||
75 | - { "vl4re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re64_v, rv_op_vl4re64_v, 0 }, | ||
76 | - { "vl8re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re8_v, rv_op_vl8re8_v, 0 }, | ||
77 | - { "vl8re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re16_v, rv_op_vl8re16_v, 0 }, | ||
78 | - { "vl8re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re32_v, rv_op_vl8re32_v, 0 }, | ||
79 | - { "vl8re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re64_v, rv_op_vl8re64_v, 0 }, | ||
80 | - { "vs1r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs1r_v, rv_op_vs1r_v, 0 }, | ||
81 | - { "vs2r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs2r_v, rv_op_vs2r_v, 0 }, | ||
82 | - { "vs4r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs4r_v, rv_op_vs4r_v, 0 }, | ||
83 | - { "vs8r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs8r_v, rv_op_vs8r_v, 0 }, | ||
84 | - { "vadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vadd_vv, rv_op_vadd_vv, 0 }, | ||
85 | - { "vadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vadd_vx, rv_op_vadd_vx, 0 }, | ||
86 | - { "vadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vadd_vi, rv_op_vadd_vi, 0 }, | ||
87 | - { "vsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsub_vv, rv_op_vsub_vv, 0 }, | ||
88 | - { "vsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsub_vx, rv_op_vsub_vx, 0 }, | ||
89 | - { "vrsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrsub_vx, rv_op_vrsub_vx, 0 }, | ||
90 | - { "vrsub.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vrsub_vi, rv_op_vrsub_vi, 0 }, | ||
91 | - { "vwaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwaddu_vv, rv_op_vwaddu_vv, 0 }, | ||
92 | - { "vwaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwaddu_vx, rv_op_vwaddu_vx, 0 }, | ||
93 | - { "vwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwadd_vv, rv_op_vwadd_vv, 0 }, | ||
94 | - { "vwadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwadd_vx, rv_op_vwadd_vx, 0 }, | ||
95 | - { "vwsubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsubu_vv, rv_op_vwsubu_vv, 0 }, | ||
96 | - { "vwsubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsubu_vx, rv_op_vwsubu_vx, 0 }, | ||
97 | - { "vwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsub_vv, rv_op_vwsub_vv, 0 }, | ||
98 | - { "vwsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsub_vx, rv_op_vwsub_vx, 0 }, | ||
99 | - { "vwaddu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwaddu_wv, rv_op_vwaddu_wv, 0 }, | ||
100 | - { "vwaddu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwaddu_wx, rv_op_vwaddu_wx, 0 }, | ||
101 | - { "vwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwadd_wv, rv_op_vwadd_wv, 0 }, | ||
102 | - { "vwadd.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwadd_wx, rv_op_vwadd_wx, 0 }, | ||
103 | - { "vwsubu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsubu_wv, rv_op_vwsubu_wv, 0 }, | ||
104 | - { "vwsubu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsubu_wx, rv_op_vwsubu_wx, 0 }, | ||
105 | - { "vwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsub_wv, rv_op_vwsub_wv, 0 }, | ||
106 | - { "vwsub.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsub_wx, rv_op_vwsub_wx, 0 }, | ||
107 | - { "vadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vadc_vvm, rv_op_vadc_vvm, 0 }, | ||
108 | - { "vadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vadc_vxm, rv_op_vadc_vxm, 0 }, | ||
109 | - { "vadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vadc_vim, rv_op_vadc_vim, 0 }, | ||
110 | - { "vmadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmadc_vvm, rv_op_vmadc_vvm, 0 }, | ||
111 | - { "vmadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmadc_vxm, rv_op_vmadc_vxm, 0 }, | ||
112 | - { "vmadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vmadc_vim, rv_op_vmadc_vim, 0 }, | ||
113 | - { "vsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vsbc_vvm, rv_op_vsbc_vvm, 0 }, | ||
114 | - { "vsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vsbc_vxm, rv_op_vsbc_vxm, 0 }, | ||
115 | - { "vmsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmsbc_vvm, rv_op_vmsbc_vvm, 0 }, | ||
116 | - { "vmsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmsbc_vxm, rv_op_vmsbc_vxm, 0 }, | ||
117 | - { "vand.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vand_vv, rv_op_vand_vv, 0 }, | ||
118 | - { "vand.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vand_vx, rv_op_vand_vx, 0 }, | ||
119 | - { "vand.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vand_vi, rv_op_vand_vi, 0 }, | ||
120 | - { "vor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vor_vv, rv_op_vor_vv, 0 }, | ||
121 | - { "vor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vor_vx, rv_op_vor_vx, 0 }, | ||
122 | - { "vor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vor_vi, rv_op_vor_vi, 0 }, | ||
123 | - { "vxor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vxor_vv, rv_op_vxor_vv, 0 }, | ||
124 | - { "vxor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vxor_vx, rv_op_vxor_vx, 0 }, | ||
125 | - { "vxor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vxor_vi, rv_op_vxor_vi, 0 }, | ||
126 | - { "vsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsll_vv, rv_op_vsll_vv, 0 }, | ||
127 | - { "vsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsll_vx, rv_op_vsll_vx, 0 }, | ||
128 | - { "vsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsll_vi, rv_op_vsll_vi, 0 }, | ||
129 | - { "vsrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsrl_vv, rv_op_vsrl_vv, 0 }, | ||
130 | - { "vsrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsrl_vx, rv_op_vsrl_vx, 0 }, | ||
131 | - { "vsrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsrl_vi, rv_op_vsrl_vi, 0 }, | ||
132 | - { "vsra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsra_vv, rv_op_vsra_vv, 0 }, | ||
133 | - { "vsra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsra_vx, rv_op_vsra_vx, 0 }, | ||
134 | - { "vsra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsra_vi, rv_op_vsra_vi, 0 }, | ||
135 | - { "vnsrl.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnsrl_wv, rv_op_vnsrl_wv, 0 }, | ||
136 | - { "vnsrl.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnsrl_wx, rv_op_vnsrl_wx, 0 }, | ||
137 | - { "vnsrl.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnsrl_wi, rv_op_vnsrl_wi, 0 }, | ||
138 | - { "vnsra.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnsra_wv, rv_op_vnsra_wv, 0 }, | ||
139 | - { "vnsra.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnsra_wx, rv_op_vnsra_wx, 0 }, | ||
140 | - { "vnsra.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnsra_wi, rv_op_vnsra_wi, 0 }, | ||
141 | - { "vmseq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmseq_vv, rv_op_vmseq_vv, 0 }, | ||
142 | - { "vmseq.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmseq_vx, rv_op_vmseq_vx, 0 }, | ||
143 | - { "vmseq.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmseq_vi, rv_op_vmseq_vi, 0 }, | ||
144 | - { "vmsne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsne_vv, rv_op_vmsne_vv, 0 }, | ||
145 | - { "vmsne.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsne_vx, rv_op_vmsne_vx, 0 }, | ||
146 | - { "vmsne.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsne_vi, rv_op_vmsne_vi, 0 }, | ||
147 | - { "vmsltu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsltu_vv, rv_op_vmsltu_vv, 0 }, | ||
148 | - { "vmsltu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsltu_vx, rv_op_vmsltu_vx, 0 }, | ||
149 | - { "vmslt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmslt_vv, rv_op_vmslt_vv, 0 }, | ||
150 | - { "vmslt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmslt_vx, rv_op_vmslt_vx, 0 }, | ||
151 | - { "vmsleu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsleu_vv, rv_op_vmsleu_vv, 0 }, | ||
152 | - { "vmsleu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsleu_vx, rv_op_vmsleu_vx, 0 }, | ||
153 | - { "vmsleu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsleu_vi, rv_op_vmsleu_vi, 0 }, | ||
154 | - { "vmsle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsle_vv, rv_op_vmsle_vv, 0 }, | ||
155 | - { "vmsle.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsle_vx, rv_op_vmsle_vx, 0 }, | ||
156 | - { "vmsle.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsle_vi, rv_op_vmsle_vi, 0 }, | ||
157 | - { "vmsgtu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsgtu_vx, rv_op_vmsgtu_vx, 0 }, | ||
158 | - { "vmsgtu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsgtu_vi, rv_op_vmsgtu_vi, 0 }, | ||
159 | - { "vmsgt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsgt_vx, rv_op_vmsgt_vx, 0 }, | ||
160 | - { "vmsgt.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsgt_vi, rv_op_vmsgt_vi, 0 }, | ||
161 | - { "vminu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vminu_vv, rv_op_vminu_vv, 0 }, | ||
162 | - { "vminu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vminu_vx, rv_op_vminu_vx, 0 }, | ||
163 | - { "vmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmin_vv, rv_op_vmin_vv, 0 }, | ||
164 | - { "vmin.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmin_vx, rv_op_vmin_vx, 0 }, | ||
165 | - { "vmaxu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmaxu_vv, rv_op_vmaxu_vv, 0 }, | ||
166 | - { "vmaxu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmaxu_vx, rv_op_vmaxu_vx, 0 }, | ||
167 | - { "vmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmax_vv, rv_op_vmax_vv, 0 }, | ||
168 | - { "vmax.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmax_vx, rv_op_vmax_vx, 0 }, | ||
169 | - { "vmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmul_vv, rv_op_vmul_vv, 0 }, | ||
170 | - { "vmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmul_vx, rv_op_vmul_vx, 0 }, | ||
171 | - { "vmulh.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulh_vv, rv_op_vmulh_vv, 0 }, | ||
172 | - { "vmulh.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulh_vx, rv_op_vmulh_vx, 0 }, | ||
173 | - { "vmulhu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulhu_vv, rv_op_vmulhu_vv, 0 }, | ||
174 | - { "vmulhu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulhu_vx, rv_op_vmulhu_vx, 0 }, | ||
175 | - { "vmulhsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulhsu_vv, rv_op_vmulhsu_vv, 0 }, | ||
176 | - { "vmulhsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulhsu_vx, rv_op_vmulhsu_vx, 0 }, | ||
177 | - { "vdivu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vdivu_vv, rv_op_vdivu_vv, 0 }, | ||
178 | - { "vdivu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vdivu_vx, rv_op_vdivu_vx, 0 }, | ||
179 | - { "vdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vdiv_vv, rv_op_vdiv_vv, 0 }, | ||
180 | - { "vdiv.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vdiv_vx, rv_op_vdiv_vx, 0 }, | ||
181 | - { "vremu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vremu_vv, rv_op_vremu_vv, 0 }, | ||
182 | - { "vremu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vremu_vx, rv_op_vremu_vx, 0 }, | ||
183 | - { "vrem.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrem_vv, rv_op_vrem_vv, 0 }, | ||
184 | - { "vrem.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrem_vx, rv_op_vrem_vx, 0 }, | ||
185 | - { "vwmulu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmulu_vv, rv_op_vwmulu_vv, 0 }, | ||
186 | - { "vwmulu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmulu_vx, rv_op_vwmulu_vx, 0 }, | ||
187 | - { "vwmulsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmulsu_vv, rv_op_vwmulsu_vv, 0 }, | ||
188 | - { "vwmulsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmulsu_vx, rv_op_vwmulsu_vx, 0 }, | ||
189 | - { "vwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmul_vv, rv_op_vwmul_vv, 0 }, | ||
190 | - { "vwmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmul_vx, rv_op_vwmul_vx, 0 }, | ||
191 | - { "vmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vmacc_vv, rv_op_vmacc_vv, 0 }, | ||
192 | - { "vmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vmacc_vx, rv_op_vmacc_vx, 0 }, | ||
193 | - { "vnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vnmsac_vv, rv_op_vnmsac_vv, 0 }, | ||
194 | - { "vnmsac.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vnmsac_vx, rv_op_vnmsac_vx, 0 }, | ||
195 | - { "vmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vmadd_vv, rv_op_vmadd_vv, 0 }, | ||
196 | - { "vmadd.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vmadd_vx, rv_op_vmadd_vx, 0 }, | ||
197 | - { "vnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vnmsub_vv, rv_op_vnmsub_vv, 0 }, | ||
198 | - { "vnmsub.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vnmsub_vx, rv_op_vnmsub_vx, 0 }, | ||
199 | - { "vwmaccu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmaccu_vv, rv_op_vwmaccu_vv, 0 }, | ||
200 | - { "vwmaccu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccu_vx, rv_op_vwmaccu_vx, 0 }, | ||
201 | - { "vwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmacc_vv, rv_op_vwmacc_vv, 0 }, | ||
202 | - { "vwmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmacc_vx, rv_op_vwmacc_vx, 0 }, | ||
203 | - { "vwmaccsu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmaccsu_vv, rv_op_vwmaccsu_vv, 0 }, | ||
204 | - { "vwmaccsu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccsu_vx, rv_op_vwmaccsu_vx, 0 }, | ||
205 | - { "vwmaccus.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccus_vx, rv_op_vwmaccus_vx, 0 }, | ||
206 | - { "vmv.v.v", rv_codec_v_r, rv_fmt_vd_vs1, NULL, rv_op_vmv_v_v, rv_op_vmv_v_v, 0 }, | ||
207 | - { "vmv.v.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, rv_op_vmv_v_x, rv_op_vmv_v_x, 0 }, | ||
208 | - { "vmv.v.i", rv_codec_v_i, rv_fmt_vd_imm, NULL, rv_op_vmv_v_i, rv_op_vmv_v_i, 0 }, | ||
209 | - { "vmerge.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmerge_vvm, rv_op_vmerge_vvm, 0 }, | ||
210 | - { "vmerge.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmerge_vxm, rv_op_vmerge_vxm, 0 }, | ||
211 | - { "vmerge.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vmerge_vim, rv_op_vmerge_vim, 0 }, | ||
212 | - { "vsaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsaddu_vv, rv_op_vsaddu_vv, 0 }, | ||
213 | - { "vsaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsaddu_vx, rv_op_vsaddu_vx, 0 }, | ||
214 | - { "vsaddu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vsaddu_vi, rv_op_vsaddu_vi, 0 }, | ||
215 | - { "vsadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsadd_vv, rv_op_vsadd_vv, 0 }, | ||
216 | - { "vsadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsadd_vx, rv_op_vsadd_vx, 0 }, | ||
217 | - { "vsadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vsadd_vi, rv_op_vsadd_vi, 0 }, | ||
218 | - { "vssubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssubu_vv, rv_op_vssubu_vv, 0 }, | ||
219 | - { "vssubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssubu_vx, rv_op_vssubu_vx, 0 }, | ||
220 | - { "vssub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssub_vv, rv_op_vssub_vv, 0 }, | ||
221 | - { "vssub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssub_vx, rv_op_vssub_vx, 0 }, | ||
222 | - { "vaadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vaadd_vv, rv_op_vaadd_vv, 0 }, | ||
223 | - { "vaadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vaadd_vx, rv_op_vaadd_vx, 0 }, | ||
224 | - { "vaaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vaaddu_vv, rv_op_vaaddu_vv, 0 }, | ||
225 | - { "vaaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vaaddu_vx, rv_op_vaaddu_vx, 0 }, | ||
226 | - { "vasub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vasub_vv, rv_op_vasub_vv, 0 }, | ||
227 | - { "vasub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vasub_vx, rv_op_vasub_vx, 0 }, | ||
228 | - { "vasubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vasubu_vv, rv_op_vasubu_vv, 0 }, | ||
229 | - { "vasubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vasubu_vx, rv_op_vasubu_vx, 0 }, | ||
230 | - { "vsmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsmul_vv, rv_op_vsmul_vv, 0 }, | ||
231 | - { "vsmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsmul_vx, rv_op_vsmul_vx, 0 }, | ||
232 | - { "vssrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssrl_vv, rv_op_vssrl_vv, 0 }, | ||
233 | - { "vssrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssrl_vx, rv_op_vssrl_vx, 0 }, | ||
234 | - { "vssrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vssrl_vi, rv_op_vssrl_vi, 0 }, | ||
235 | - { "vssra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssra_vv, rv_op_vssra_vv, 0 }, | ||
236 | - { "vssra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssra_vx, rv_op_vssra_vx, 0 }, | ||
237 | - { "vssra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vssra_vi, rv_op_vssra_vi, 0 }, | ||
238 | - { "vnclipu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnclipu_wv, rv_op_vnclipu_wv, 0 }, | ||
239 | - { "vnclipu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnclipu_wx, rv_op_vnclipu_wx, 0 }, | ||
240 | - { "vnclipu.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnclipu_wi, rv_op_vnclipu_wi, 0 }, | ||
241 | - { "vnclip.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnclip_wv, rv_op_vnclip_wv, 0 }, | ||
242 | - { "vnclip.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnclip_wx, rv_op_vnclip_wx, 0 }, | ||
243 | - { "vnclip.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnclip_wi, rv_op_vnclip_wi, 0 }, | ||
244 | - { "vfadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfadd_vv, rv_op_vfadd_vv, 0 }, | ||
245 | - { "vfadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfadd_vf, rv_op_vfadd_vf, 0 }, | ||
246 | - { "vfsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsub_vv, rv_op_vfsub_vv, 0 }, | ||
247 | - { "vfsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsub_vf, rv_op_vfsub_vf, 0 }, | ||
248 | - { "vfrsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfrsub_vf, rv_op_vfrsub_vf, 0 }, | ||
249 | - { "vfwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwadd_vv, rv_op_vfwadd_vv, 0 }, | ||
250 | - { "vfwadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwadd_vf, rv_op_vfwadd_vf, 0 }, | ||
251 | - { "vfwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwadd_wv, rv_op_vfwadd_wv, 0 }, | ||
252 | - { "vfwadd.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwadd_wf, rv_op_vfwadd_wf, 0 }, | ||
253 | - { "vfwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwsub_vv, rv_op_vfwsub_vv, 0 }, | ||
254 | - { "vfwsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwsub_vf, rv_op_vfwsub_vf, 0 }, | ||
255 | - { "vfwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwsub_wv, rv_op_vfwsub_wv, 0 }, | ||
256 | - { "vfwsub.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwsub_wf, rv_op_vfwsub_wf, 0 }, | ||
257 | - { "vfmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmul_vv, rv_op_vfmul_vv, 0 }, | ||
258 | - { "vfmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmul_vf, rv_op_vfmul_vf, 0 }, | ||
259 | - { "vfdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfdiv_vv, rv_op_vfdiv_vv, 0 }, | ||
260 | - { "vfdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfdiv_vf, rv_op_vfdiv_vf, 0 }, | ||
261 | - { "vfrdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfrdiv_vf, rv_op_vfrdiv_vf, 0 }, | ||
262 | - { "vfwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwmul_vv, rv_op_vfwmul_vv, 0 }, | ||
263 | - { "vfwmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwmul_vf, rv_op_vfwmul_vf, 0 }, | ||
264 | - { "vfmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmacc_vv, rv_op_vfmacc_vv, 0 }, | ||
265 | - { "vfmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmacc_vf, rv_op_vfmacc_vf, 0 }, | ||
266 | - { "vfnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmacc_vv, rv_op_vfnmacc_vv, 0 }, | ||
267 | - { "vfnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmacc_vf, rv_op_vfnmacc_vf, 0 }, | ||
268 | - { "vfmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmsac_vv, rv_op_vfmsac_vv, 0 }, | ||
269 | - { "vfmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmsac_vf, rv_op_vfmsac_vf, 0 }, | ||
270 | - { "vfnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmsac_vv, rv_op_vfnmsac_vv, 0 }, | ||
271 | - { "vfnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmsac_vf, rv_op_vfnmsac_vf, 0 }, | ||
272 | - { "vfmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmadd_vv, rv_op_vfmadd_vv, 0 }, | ||
273 | - { "vfmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmadd_vf, rv_op_vfmadd_vf, 0 }, | ||
274 | - { "vfnmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmadd_vv, rv_op_vfnmadd_vv, 0 }, | ||
275 | - { "vfnmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmadd_vf, rv_op_vfnmadd_vf, 0 }, | ||
276 | - { "vfmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmsub_vv, rv_op_vfmsub_vv, 0 }, | ||
277 | - { "vfmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmsub_vf, rv_op_vfmsub_vf, 0 }, | ||
278 | - { "vfnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmsub_vv, rv_op_vfnmsub_vv, 0 }, | ||
279 | - { "vfnmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmsub_vf, rv_op_vfnmsub_vf, 0 }, | ||
280 | - { "vfwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwmacc_vv, rv_op_vfwmacc_vv, 0 }, | ||
281 | - { "vfwmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwmacc_vf, rv_op_vfwmacc_vf, 0 }, | ||
282 | - { "vfwnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwnmacc_vv, rv_op_vfwnmacc_vv, 0 }, | ||
283 | - { "vfwnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwnmacc_vf, rv_op_vfwnmacc_vf, 0 }, | ||
284 | - { "vfwmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwmsac_vv, rv_op_vfwmsac_vv, 0 }, | ||
285 | - { "vfwmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwmsac_vf, rv_op_vfwmsac_vf, 0 }, | ||
286 | - { "vfwnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwnmsac_vv, rv_op_vfwnmsac_vv, 0 }, | ||
287 | - { "vfwnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwnmsac_vf, rv_op_vfwnmsac_vf, 0 }, | ||
288 | - { "vfsqrt.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfsqrt_v, rv_op_vfsqrt_v, 0 }, | ||
289 | - { "vfrsqrt7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfrsqrt7_v, rv_op_vfrsqrt7_v, 0 }, | ||
290 | - { "vfrec7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfrec7_v, rv_op_vfrec7_v, 0 }, | ||
291 | - { "vfmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmin_vv, rv_op_vfmin_vv, 0 }, | ||
292 | - { "vfmin.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmin_vf, rv_op_vfmin_vf, 0 }, | ||
293 | - { "vfmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmax_vv, rv_op_vfmax_vv, 0 }, | ||
294 | - { "vfmax.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmax_vf, rv_op_vfmax_vf, 0 }, | ||
295 | - { "vfsgnj.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnj_vv, rv_op_vfsgnj_vv, 0 }, | ||
296 | - { "vfsgnj.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnj_vf, rv_op_vfsgnj_vf, 0 }, | ||
297 | - { "vfsgnjn.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnjn_vv, rv_op_vfsgnjn_vv, 0 }, | ||
298 | - { "vfsgnjn.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnjn_vf, rv_op_vfsgnjn_vf, 0 }, | ||
299 | - { "vfsgnjx.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnjx_vv, rv_op_vfsgnjx_vv, 0 }, | ||
300 | - { "vfsgnjx.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnjx_vf, rv_op_vfsgnjx_vf, 0 }, | ||
301 | - { "vfslide1up.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfslide1up_vf, rv_op_vfslide1up_vf, 0 }, | ||
302 | - { "vfslide1down.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfslide1down_vf, rv_op_vfslide1down_vf, 0 }, | ||
303 | - { "vmfeq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfeq_vv, rv_op_vmfeq_vv, 0 }, | ||
304 | - { "vmfeq.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfeq_vf, rv_op_vmfeq_vf, 0 }, | ||
305 | - { "vmfne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfne_vv, rv_op_vmfne_vv, 0 }, | ||
306 | - { "vmfne.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfne_vf, rv_op_vmfne_vf, 0 }, | ||
307 | - { "vmflt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmflt_vv, rv_op_vmflt_vv, 0 }, | ||
308 | - { "vmflt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmflt_vf, rv_op_vmflt_vf, 0 }, | ||
309 | - { "vmfle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfle_vv, rv_op_vmfle_vv, 0 }, | ||
310 | - { "vmfle.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfle_vf, rv_op_vmfle_vf, 0 }, | ||
311 | - { "vmfgt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfgt_vf, rv_op_vmfgt_vf, 0 }, | ||
312 | - { "vmfge.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfge_vf, rv_op_vmfge_vf, 0 }, | ||
313 | - { "vfclass.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfclass_v, rv_op_vfclass_v, 0 }, | ||
314 | - { "vfmerge.vfm", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vl, NULL, rv_op_vfmerge_vfm, rv_op_vfmerge_vfm, 0 }, | ||
315 | - { "vfmv.v.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, rv_op_vfmv_v_f, rv_op_vfmv_v_f, 0 }, | ||
316 | - { "vfcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_xu_f_v, rv_op_vfcvt_xu_f_v, 0 }, | ||
317 | - { "vfcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_x_f_v, rv_op_vfcvt_x_f_v, 0 }, | ||
318 | - { "vfcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_f_xu_v, rv_op_vfcvt_f_xu_v, 0 }, | ||
319 | - { "vfcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_f_x_v, rv_op_vfcvt_f_x_v, 0 }, | ||
320 | - { "vfcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_rtz_xu_f_v, rv_op_vfcvt_rtz_xu_f_v, 0 }, | ||
321 | - { "vfcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_rtz_x_f_v, rv_op_vfcvt_rtz_x_f_v, 0 }, | ||
322 | - { "vfwcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_xu_f_v, rv_op_vfwcvt_xu_f_v, 0 }, | ||
323 | - { "vfwcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_x_f_v, rv_op_vfwcvt_x_f_v, 0 }, | ||
324 | - { "vfwcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_xu_v, rv_op_vfwcvt_f_xu_v, 0 }, | ||
325 | - { "vfwcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_x_v, rv_op_vfwcvt_f_x_v, 0 }, | ||
326 | - { "vfwcvt.f.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_f_v, rv_op_vfwcvt_f_f_v, 0 }, | ||
327 | - { "vfwcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_rtz_xu_f_v, rv_op_vfwcvt_rtz_xu_f_v, 0 }, | ||
328 | - { "vfwcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_rtz_x_f_v, rv_op_vfwcvt_rtz_x_f_v, 0 }, | ||
329 | - { "vfncvt.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_xu_f_w, rv_op_vfncvt_xu_f_w, 0 }, | ||
330 | - { "vfncvt.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_x_f_w, rv_op_vfncvt_x_f_w, 0 }, | ||
331 | - { "vfncvt.f.xu.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_xu_w, rv_op_vfncvt_f_xu_w, 0 }, | ||
332 | - { "vfncvt.f.x.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_x_w, rv_op_vfncvt_f_x_w, 0 }, | ||
333 | - { "vfncvt.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_f_w, rv_op_vfncvt_f_f_w, 0 }, | ||
334 | - { "vfncvt.rod.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rod_f_f_w, rv_op_vfncvt_rod_f_f_w, 0 }, | ||
335 | - { "vfncvt.rtz.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rtz_xu_f_w, rv_op_vfncvt_rtz_xu_f_w, 0 }, | ||
336 | - { "vfncvt.rtz.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rtz_x_f_w, rv_op_vfncvt_rtz_x_f_w, 0 }, | ||
337 | - { "vredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredsum_vs, rv_op_vredsum_vs, 0 }, | ||
338 | - { "vredand.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredand_vs, rv_op_vredand_vs, 0 }, | ||
339 | - { "vredor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredor_vs, rv_op_vredor_vs, 0 }, | ||
340 | - { "vredxor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredxor_vs, rv_op_vredxor_vs, 0 }, | ||
341 | - { "vredminu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredminu_vs, rv_op_vredminu_vs, 0 }, | ||
342 | - { "vredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmin_vs, rv_op_vredmin_vs, 0 }, | ||
343 | - { "vredmaxu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmaxu_vs, rv_op_vredmaxu_vs, 0 }, | ||
344 | - { "vredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmax_vs, rv_op_vredmax_vs, 0 }, | ||
345 | - { "vwredsumu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwredsumu_vs, rv_op_vwredsumu_vs, 0 }, | ||
346 | - { "vwredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwredsum_vs, rv_op_vwredsum_vs, 0 }, | ||
347 | - { "vfredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredusum_vs, rv_op_vfredusum_vs, 0 }, | ||
348 | - { "vfredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredosum_vs, rv_op_vfredosum_vs, 0 }, | ||
349 | - { "vfredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredmin_vs, rv_op_vfredmin_vs, 0 }, | ||
350 | - { "vfredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredmax_vs, rv_op_vfredmax_vs, 0 }, | ||
351 | - { "vfwredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwredusum_vs, rv_op_vfwredusum_vs, 0 }, | ||
352 | - { "vfwredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwredosum_vs, rv_op_vfwredosum_vs, 0 }, | ||
353 | - { "vmand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmand_mm, rv_op_vmand_mm, 0 }, | ||
354 | - { "vmnand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmnand_mm, rv_op_vmnand_mm, 0 }, | ||
355 | - { "vmandn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmandn_mm, rv_op_vmandn_mm, 0 }, | ||
356 | - { "vmxor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmxor_mm, rv_op_vmxor_mm, 0 }, | ||
357 | - { "vmor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmor_mm, rv_op_vmor_mm, 0 }, | ||
358 | - { "vmnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmnor_mm, rv_op_vmnor_mm, 0 }, | ||
359 | - { "vmorn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmorn_mm, rv_op_vmorn_mm, 0 }, | ||
360 | - { "vmxnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmxnor_mm, rv_op_vmxnor_mm, 0 }, | ||
361 | - { "vcpop.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, rv_op_vcpop_m, rv_op_vcpop_m, 0 }, | ||
362 | - { "vfirst.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, rv_op_vfirst_m, rv_op_vfirst_m, 0 }, | ||
363 | - { "vmsbf.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsbf_m, rv_op_vmsbf_m, 0 }, | ||
364 | - { "vmsif.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsif_m, rv_op_vmsif_m, 0 }, | ||
365 | - { "vmsof.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsof_m, rv_op_vmsof_m, 0 }, | ||
366 | - { "viota.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_viota_m, rv_op_viota_m, 0 }, | ||
367 | - { "vid.v", rv_codec_v_r, rv_fmt_vd_vm, NULL, rv_op_vid_v, rv_op_vid_v, 0 }, | ||
368 | - { "vmv.x.s", rv_codec_v_r, rv_fmt_rd_vs2, NULL, rv_op_vmv_x_s, rv_op_vmv_x_s, 0 }, | ||
369 | - { "vmv.s.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, rv_op_vmv_s_x, rv_op_vmv_s_x, 0 }, | ||
370 | - { "vfmv.f.s", rv_codec_v_r, rv_fmt_fd_vs2, NULL, rv_op_vfmv_f_s, rv_op_vfmv_f_s, 0 }, | ||
371 | - { "vfmv.s.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, rv_op_vfmv_s_f, rv_op_vfmv_s_f, 0 }, | ||
372 | - { "vslideup.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslideup_vx, rv_op_vslideup_vx, 0 }, | ||
373 | - { "vslideup.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vslideup_vi, rv_op_vslideup_vi, 0 }, | ||
374 | - { "vslide1up.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslide1up_vx, rv_op_vslide1up_vx, 0 }, | ||
375 | - { "vslidedown.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslidedown_vx, rv_op_vslidedown_vx, 0 }, | ||
376 | - { "vslidedown.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vslidedown_vi, rv_op_vslidedown_vi, 0 }, | ||
377 | - { "vslide1down.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslide1down_vx, rv_op_vslide1down_vx, 0 }, | ||
378 | - { "vrgather.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrgather_vv, rv_op_vrgather_vv, 0 }, | ||
379 | - { "vrgatherei16.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrgatherei16_vv, rv_op_vrgatherei16_vv, 0 }, | ||
380 | - { "vrgather.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrgather_vx, rv_op_vrgather_vx, 0 }, | ||
381 | - { "vrgather.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vrgather_vi, rv_op_vrgather_vi, 0 }, | ||
382 | - { "vcompress.vm", rv_codec_v_r, rv_fmt_vd_vs2_vs1, NULL, rv_op_vcompress_vm, rv_op_vcompress_vm, 0 }, | ||
383 | - { "vmv1r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv1r_v, rv_op_vmv1r_v, 0 }, | ||
384 | - { "vmv2r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv2r_v, rv_op_vmv2r_v, 0 }, | ||
385 | - { "vmv4r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv4r_v, rv_op_vmv4r_v, 0 }, | ||
386 | - { "vmv8r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv8r_v, rv_op_vmv8r_v, 0 }, | ||
387 | - { "vzext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf2, rv_op_vzext_vf2, 0 }, | ||
388 | - { "vzext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf4, rv_op_vzext_vf4, 0 }, | ||
389 | - { "vzext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf8, rv_op_vzext_vf8, 0 }, | ||
390 | - { "vsext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf2, rv_op_vsext_vf2, 0 }, | ||
391 | - { "vsext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf4, rv_op_vsext_vf4, 0 }, | ||
392 | - { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 }, | ||
393 | - { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 }, | ||
394 | - { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 }, | ||
395 | - { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 }, | ||
396 | + { "vle8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
397 | + { "vle16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
398 | + { "vle32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
399 | + { "vle64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
400 | + { "vse8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
401 | + { "vse16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
402 | + { "vse32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
403 | + { "vse64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
404 | + { "vlm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
405 | + { "vsm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
406 | + { "vlse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
407 | + { "vlse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
408 | + { "vlse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
409 | + { "vlse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
410 | + { "vsse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
411 | + { "vsse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
412 | + { "vsse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
413 | + { "vsse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 }, | ||
414 | + { "vluxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
415 | + { "vluxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
416 | + { "vluxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
417 | + { "vluxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
418 | + { "vloxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
419 | + { "vloxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
420 | + { "vloxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
421 | + { "vloxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
422 | + { "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
423 | + { "vsuxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
424 | + { "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
425 | + { "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
426 | + { "vsoxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
427 | + { "vsoxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
428 | + { "vsoxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
429 | + { "vsoxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
430 | + { "vle8ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
431 | + { "vle16ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
432 | + { "vle32ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
433 | + { "vle64ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
434 | + { "vl1re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
435 | + { "vl1re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
436 | + { "vl1re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
437 | + { "vl1re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
438 | + { "vl2re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
439 | + { "vl2re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
440 | + { "vl2re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
441 | + { "vl2re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
442 | + { "vl4re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
443 | + { "vl4re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
444 | + { "vl4re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
445 | + { "vl4re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
446 | + { "vl8re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
447 | + { "vl8re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
448 | + { "vl8re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
449 | + { "vl8re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
450 | + { "vs1r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
451 | + { "vs2r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
452 | + { "vs4r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
453 | + { "vs8r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 }, | ||
454 | + { "vadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
455 | + { "vadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
456 | + { "vadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
457 | + { "vsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
458 | + { "vsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
459 | + { "vrsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
460 | + { "vrsub.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
461 | + { "vwaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
462 | + { "vwaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
463 | + { "vwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
464 | + { "vwadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
465 | + { "vwsubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
466 | + { "vwsubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
467 | + { "vwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
468 | + { "vwsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
469 | + { "vwaddu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
470 | + { "vwaddu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
471 | + { "vwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
472 | + { "vwadd.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
473 | + { "vwsubu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
474 | + { "vwsubu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
475 | + { "vwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
476 | + { "vwsub.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
477 | + { "vadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 }, | ||
478 | + { "vadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 }, | ||
479 | + { "vadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 }, | ||
480 | + { "vmadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 }, | ||
481 | + { "vmadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 }, | ||
482 | + { "vmadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 }, | ||
483 | + { "vsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 }, | ||
484 | + { "vsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 }, | ||
485 | + { "vmsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 }, | ||
486 | + { "vmsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 }, | ||
487 | + { "vand.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
488 | + { "vand.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
489 | + { "vand.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
490 | + { "vor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
491 | + { "vor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
492 | + { "vor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
493 | + { "vxor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
494 | + { "vxor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
495 | + { "vxor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
496 | + { "vsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
497 | + { "vsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
498 | + { "vsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
499 | + { "vsrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
500 | + { "vsrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
501 | + { "vsrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
502 | + { "vsra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
503 | + { "vsra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
504 | + { "vsra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
505 | + { "vnsrl.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
506 | + { "vnsrl.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
507 | + { "vnsrl.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
508 | + { "vnsra.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
509 | + { "vnsra.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
510 | + { "vnsra.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
511 | + { "vmseq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
512 | + { "vmseq.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
513 | + { "vmseq.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
514 | + { "vmsne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
515 | + { "vmsne.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
516 | + { "vmsne.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
517 | + { "vmsltu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
518 | + { "vmsltu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
519 | + { "vmslt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
520 | + { "vmslt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
521 | + { "vmsleu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
522 | + { "vmsleu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
523 | + { "vmsleu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
524 | + { "vmsle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
525 | + { "vmsle.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
526 | + { "vmsle.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
527 | + { "vmsgtu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
528 | + { "vmsgtu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
529 | + { "vmsgt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
530 | + { "vmsgt.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
531 | + { "vminu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
532 | + { "vminu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
533 | + { "vmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
534 | + { "vmin.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
535 | + { "vmaxu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
536 | + { "vmaxu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
537 | + { "vmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
538 | + { "vmax.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
539 | + { "vmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
540 | + { "vmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
541 | + { "vmulh.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
542 | + { "vmulh.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
543 | + { "vmulhu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
544 | + { "vmulhu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
545 | + { "vmulhsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
546 | + { "vmulhsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
547 | + { "vdivu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
548 | + { "vdivu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
549 | + { "vdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
550 | + { "vdiv.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
551 | + { "vremu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
552 | + { "vremu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
553 | + { "vrem.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
554 | + { "vrem.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
555 | + { "vwmulu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
556 | + { "vwmulu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
557 | + { "vwmulsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
558 | + { "vwmulsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
559 | + { "vwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
560 | + { "vwmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
561 | + { "vmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
562 | + { "vmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
563 | + { "vnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
564 | + { "vnmsac.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
565 | + { "vmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
566 | + { "vmadd.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
567 | + { "vnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
568 | + { "vnmsub.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
569 | + { "vwmaccu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
570 | + { "vwmaccu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
571 | + { "vwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
572 | + { "vwmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
573 | + { "vwmaccsu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
574 | + { "vwmaccsu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
575 | + { "vwmaccus.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 }, | ||
576 | + { "vmv.v.v", rv_codec_v_r, rv_fmt_vd_vs1, NULL, 0, 0, 0 }, | ||
577 | + { "vmv.v.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, 0, 0, 0 }, | ||
578 | + { "vmv.v.i", rv_codec_v_i, rv_fmt_vd_imm, NULL, 0, 0, 0 }, | ||
579 | + { "vmerge.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 }, | ||
580 | + { "vmerge.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 }, | ||
581 | + { "vmerge.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 }, | ||
582 | + { "vsaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
583 | + { "vsaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
584 | + { "vsaddu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
585 | + { "vsadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
586 | + { "vsadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
587 | + { "vsadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 }, | ||
588 | + { "vssubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
589 | + { "vssubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
590 | + { "vssub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
591 | + { "vssub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
592 | + { "vaadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
593 | + { "vaadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
594 | + { "vaaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
595 | + { "vaaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
596 | + { "vasub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
597 | + { "vasub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
598 | + { "vasubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
599 | + { "vasubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
600 | + { "vsmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
601 | + { "vsmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
602 | + { "vssrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
603 | + { "vssrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
604 | + { "vssrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
605 | + { "vssra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
606 | + { "vssra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
607 | + { "vssra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
608 | + { "vnclipu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
609 | + { "vnclipu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
610 | + { "vnclipu.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
611 | + { "vnclip.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
612 | + { "vnclip.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
613 | + { "vnclip.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
614 | + { "vfadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
615 | + { "vfadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
616 | + { "vfsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
617 | + { "vfsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
618 | + { "vfrsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
619 | + { "vfwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
620 | + { "vfwadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
621 | + { "vfwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
622 | + { "vfwadd.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
623 | + { "vfwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
624 | + { "vfwsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
625 | + { "vfwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
626 | + { "vfwsub.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
627 | + { "vfmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
628 | + { "vfmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
629 | + { "vfdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
630 | + { "vfdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
631 | + { "vfrdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
632 | + { "vfwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
633 | + { "vfwmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
634 | + { "vfmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
635 | + { "vfmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
636 | + { "vfnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
637 | + { "vfnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
638 | + { "vfmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
639 | + { "vfmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
640 | + { "vfnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
641 | + { "vfnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
642 | + { "vfmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
643 | + { "vfmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
644 | + { "vfnmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
645 | + { "vfnmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
646 | + { "vfmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
647 | + { "vfmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
648 | + { "vfnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
649 | + { "vfnmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
650 | + { "vfwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
651 | + { "vfwmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
652 | + { "vfwnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
653 | + { "vfwnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
654 | + { "vfwmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
655 | + { "vfwmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
656 | + { "vfwnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 }, | ||
657 | + { "vfwnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 }, | ||
658 | + { "vfsqrt.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
659 | + { "vfrsqrt7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
660 | + { "vfrec7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
661 | + { "vfmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
662 | + { "vfmin.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
663 | + { "vfmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
664 | + { "vfmax.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
665 | + { "vfsgnj.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
666 | + { "vfsgnj.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
667 | + { "vfsgnjn.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
668 | + { "vfsgnjn.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
669 | + { "vfsgnjx.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
670 | + { "vfsgnjx.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
671 | + { "vfslide1up.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
672 | + { "vfslide1down.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
673 | + { "vmfeq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
674 | + { "vmfeq.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
675 | + { "vmfne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
676 | + { "vmfne.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
677 | + { "vmflt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
678 | + { "vmflt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
679 | + { "vmfle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
680 | + { "vmfle.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
681 | + { "vmfgt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
682 | + { "vmfge.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 }, | ||
683 | + { "vfclass.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
684 | + { "vfmerge.vfm", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vl, NULL, 0, 0, 0 }, | ||
685 | + { "vfmv.v.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, 0, 0, 0 }, | ||
686 | + { "vfcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
687 | + { "vfcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
688 | + { "vfcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
689 | + { "vfcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
690 | + { "vfcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
691 | + { "vfcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
692 | + { "vfwcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
693 | + { "vfwcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
694 | + { "vfwcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
695 | + { "vfwcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
696 | + { "vfwcvt.f.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
697 | + { "vfwcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
698 | + { "vfwcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
699 | + { "vfncvt.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
700 | + { "vfncvt.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
701 | + { "vfncvt.f.xu.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
702 | + { "vfncvt.f.x.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
703 | + { "vfncvt.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
704 | + { "vfncvt.rod.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
705 | + { "vfncvt.rtz.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
706 | + { "vfncvt.rtz.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
707 | + { "vredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
708 | + { "vredand.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
709 | + { "vredor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
710 | + { "vredxor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
711 | + { "vredminu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
712 | + { "vredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
713 | + { "vredmaxu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
714 | + { "vredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
715 | + { "vwredsumu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
716 | + { "vwredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
717 | + { "vfredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
718 | + { "vfredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
719 | + { "vfredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
720 | + { "vfredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
721 | + { "vfwredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
722 | + { "vfwredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
723 | + { "vmand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
724 | + { "vmnand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
725 | + { "vmandn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
726 | + { "vmxor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
727 | + { "vmor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
728 | + { "vmnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
729 | + { "vmorn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
730 | + { "vmxnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
731 | + { "vcpop.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, 0, 0, 0 }, | ||
732 | + { "vfirst.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, 0, 0, 0 }, | ||
733 | + { "vmsbf.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
734 | + { "vmsif.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
735 | + { "vmsof.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
736 | + { "viota.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
737 | + { "vid.v", rv_codec_v_r, rv_fmt_vd_vm, NULL, 0, 0, 0 }, | ||
738 | + { "vmv.x.s", rv_codec_v_r, rv_fmt_rd_vs2, NULL, 0, 0, 0 }, | ||
739 | + { "vmv.s.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, 0, 0, 0 }, | ||
740 | + { "vfmv.f.s", rv_codec_v_r, rv_fmt_fd_vs2, NULL, 0, 0, 0 }, | ||
741 | + { "vfmv.s.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, 0, 0, 0 }, | ||
742 | + { "vslideup.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
743 | + { "vslideup.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
744 | + { "vslide1up.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
745 | + { "vslidedown.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
746 | + { "vslidedown.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
747 | + { "vslide1down.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
748 | + { "vrgather.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
749 | + { "vrgatherei16.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | ||
750 | + { "vrgather.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | ||
751 | + { "vrgather.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | ||
752 | + { "vcompress.vm", rv_codec_v_r, rv_fmt_vd_vs2_vs1, NULL, 0, 0, 0 }, | ||
753 | + { "vmv1r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
754 | + { "vmv2r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
755 | + { "vmv4r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
756 | + { "vmv8r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 }, | ||
757 | + { "vzext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
758 | + { "vzext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
759 | + { "vzext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
760 | + { "vsext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
761 | + { "vsext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
762 | + { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 }, | ||
763 | + { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, 0, 0, 0 }, | ||
764 | + { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, 0, 0, 0 }, | ||
765 | + { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
766 | { "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 }, | ||
767 | { "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 }, | ||
768 | { "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 }, | ||
769 | -- | ||
770 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Fix lines with over 80 characters. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20230523093539.203909-8-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | disas/riscv.c | 201 +++++++++++++++++++++++++++++++++++--------------- | ||
13 | 1 file changed, 140 insertions(+), 61 deletions(-) | ||
14 | |||
15 | diff --git a/disas/riscv.c b/disas/riscv.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/disas/riscv.c | ||
18 | +++ b/disas/riscv.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static const char rv_vreg_name_sym[32][4] = { | ||
20 | /* pseudo-instruction constraints */ | ||
21 | |||
22 | static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end }; | ||
23 | -static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, rvc_end }; | ||
24 | -static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, rvc_imm_eq_zero, rvc_end }; | ||
25 | +static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, | ||
26 | + rvc_end }; | ||
27 | +static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, | ||
28 | + rvc_imm_eq_zero, rvc_end }; | ||
29 | static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end }; | ||
30 | static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end }; | ||
31 | static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end }; | ||
32 | @@ -XXX,XX +XXX,XX @@ static const rvc_constraint rvcc_bleu[] = { rvc_end }; | ||
33 | static const rvc_constraint rvcc_bgt[] = { rvc_end }; | ||
34 | static const rvc_constraint rvcc_bgtu[] = { rvc_end }; | ||
35 | static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end }; | ||
36 | -static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end }; | ||
37 | -static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end }; | ||
38 | -static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, rvc_end }; | ||
39 | -static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, rvc_end }; | ||
40 | -static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end }; | ||
41 | -static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end }; | ||
42 | -static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end }; | ||
43 | +static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, | ||
44 | + rvc_end }; | ||
45 | +static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, | ||
46 | + rvc_end }; | ||
47 | +static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, | ||
48 | + rvc_end }; | ||
49 | +static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, | ||
50 | + rvc_end }; | ||
51 | +static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, | ||
52 | + rvc_csr_eq_0xc02, rvc_end }; | ||
53 | +static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, | ||
54 | + rvc_csr_eq_0xc80, rvc_end }; | ||
55 | +static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, | ||
56 | + rvc_end }; | ||
57 | static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, | ||
58 | rvc_csr_eq_0xc82, rvc_end }; | ||
59 | -static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end }; | ||
60 | -static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end }; | ||
61 | -static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end }; | ||
62 | +static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, | ||
63 | + rvc_end }; | ||
64 | +static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, | ||
65 | + rvc_end }; | ||
66 | +static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, | ||
67 | + rvc_end }; | ||
68 | static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end }; | ||
69 | static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end }; | ||
70 | static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end }; | ||
71 | @@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = { | ||
72 | { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 }, | ||
73 | { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, | ||
74 | rv_op_addi, rv_op_addi, rvcd_imm_nz }, | ||
75 | - { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 }, | ||
76 | - { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw }, | ||
77 | + { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, | ||
78 | + rv_op_fld, 0 }, | ||
79 | + { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, | ||
80 | + rv_op_lw }, | ||
81 | { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 }, | ||
82 | - { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 }, | ||
83 | - { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw }, | ||
84 | + { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, | ||
85 | + rv_op_fsd, 0 }, | ||
86 | + { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, | ||
87 | + rv_op_sw }, | ||
88 | { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 }, | ||
89 | - { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi }, | ||
90 | + { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, | ||
91 | + rv_op_addi }, | ||
92 | { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, | ||
93 | rv_op_addi, rvcd_imm_nz }, | ||
94 | { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 }, | ||
95 | - { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi }, | ||
96 | + { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, | ||
97 | + rv_op_addi }, | ||
98 | { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, | ||
99 | rv_op_addi, rv_op_addi, rvcd_imm_nz }, | ||
100 | { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, | ||
101 | @@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = { | ||
102 | rv_op_srai, rv_op_srai, rvcd_imm_nz }, | ||
103 | { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, | ||
104 | rv_op_andi, rv_op_andi }, | ||
105 | - { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub }, | ||
106 | - { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor }, | ||
107 | - { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or }, | ||
108 | - { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, rv_op_and }, | ||
109 | - { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, rv_op_subw }, | ||
110 | - { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, rv_op_addw }, | ||
111 | - { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal }, | ||
112 | - { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq }, | ||
113 | - { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne }, | ||
114 | + { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, | ||
115 | + rv_op_sub }, | ||
116 | + { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, | ||
117 | + rv_op_xor }, | ||
118 | + { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, | ||
119 | + rv_op_or }, | ||
120 | + { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, | ||
121 | + rv_op_and }, | ||
122 | + { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, | ||
123 | + rv_op_subw }, | ||
124 | + { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, | ||
125 | + rv_op_addw }, | ||
126 | + { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, | ||
127 | + rv_op_jal }, | ||
128 | + { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, | ||
129 | + rv_op_beq }, | ||
130 | + { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, | ||
131 | + rv_op_bne }, | ||
132 | { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, | ||
133 | rv_op_slli, rv_op_slli, rvcd_imm_nz }, | ||
134 | - { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld }, | ||
135 | - { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw }, | ||
136 | - { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 }, | ||
137 | - { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr }, | ||
138 | - { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, rv_op_addi }, | ||
139 | - { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, rv_op_ebreak, rv_op_ebreak }, | ||
140 | - { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr }, | ||
141 | - { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, rv_op_add }, | ||
142 | - { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, rv_op_fsd }, | ||
143 | - { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw }, | ||
144 | - { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 }, | ||
145 | - { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld }, | ||
146 | - { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd }, | ||
147 | - { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, rv_op_addiw }, | ||
148 | - { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld }, | ||
149 | - { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd }, | ||
150 | + { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, | ||
151 | + rv_op_fld, rv_op_fld }, | ||
152 | + { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, | ||
153 | + rv_op_lw, rv_op_lw }, | ||
154 | + { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, | ||
155 | + 0 }, | ||
156 | + { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, | ||
157 | + rv_op_jalr, rv_op_jalr }, | ||
158 | + { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, | ||
159 | + rv_op_addi }, | ||
160 | + { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, | ||
161 | + rv_op_ebreak, rv_op_ebreak }, | ||
162 | + { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, | ||
163 | + rv_op_jalr, rv_op_jalr }, | ||
164 | + { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, | ||
165 | + rv_op_add }, | ||
166 | + { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, | ||
167 | + rv_op_fsd, rv_op_fsd }, | ||
168 | + { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, | ||
169 | + rv_op_sw, rv_op_sw }, | ||
170 | + { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, | ||
171 | + 0 }, | ||
172 | + { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, | ||
173 | + rv_op_ld }, | ||
174 | + { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, | ||
175 | + rv_op_sd }, | ||
176 | + { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, | ||
177 | + rv_op_addiw }, | ||
178 | + { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, | ||
179 | + rv_op_ld }, | ||
180 | + { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, | ||
181 | + rv_op_sd }, | ||
182 | { "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq }, | ||
183 | { "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq }, | ||
184 | { "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq }, | ||
185 | - { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq }, | ||
186 | + { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, | ||
187 | + rv_op_sq }, | ||
188 | { "nop", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 }, | ||
189 | { "mv", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
190 | { "not", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
191 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
192 | } | ||
193 | break; | ||
194 | case 11: | ||
195 | - switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
196 | + switch (((inst >> 24) & 0b11111000) | | ||
197 | + ((inst >> 12) & 0b00000111)) { | ||
198 | case 2: op = rv_op_amoadd_w; break; | ||
199 | case 3: op = rv_op_amoadd_d; break; | ||
200 | case 4: op = rv_op_amoadd_q; break; | ||
201 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
202 | } | ||
203 | break; | ||
204 | case 12: | ||
205 | - switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) { | ||
206 | + switch (((inst >> 22) & 0b1111111000) | | ||
207 | + ((inst >> 12) & 0b0000000111)) { | ||
208 | case 0: op = rv_op_add; break; | ||
209 | case 1: op = rv_op_sll; break; | ||
210 | case 2: op = rv_op_slt; break; | ||
211 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
212 | break; | ||
213 | case 13: op = rv_op_lui; break; | ||
214 | case 14: | ||
215 | - switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) { | ||
216 | + switch (((inst >> 22) & 0b1111111000) | | ||
217 | + ((inst >> 12) & 0b0000000111)) { | ||
218 | case 0: op = rv_op_addw; break; | ||
219 | case 1: op = rv_op_sllw; break; | ||
220 | case 5: op = rv_op_srlw; break; | ||
221 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
222 | } | ||
223 | break; | ||
224 | case 112: | ||
225 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
226 | + switch (((inst >> 17) & 0b11111000) | | ||
227 | + ((inst >> 12) & 0b00000111)) { | ||
228 | case 0: op = rv_op_fmv_x_s; break; | ||
229 | case 1: op = rv_op_fclass_s; break; | ||
230 | } | ||
231 | break; | ||
232 | case 113: | ||
233 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
234 | + switch (((inst >> 17) & 0b11111000) | | ||
235 | + ((inst >> 12) & 0b00000111)) { | ||
236 | case 0: op = rv_op_fmv_x_d; break; | ||
237 | case 1: op = rv_op_fclass_d; break; | ||
238 | } | ||
239 | break; | ||
240 | case 115: | ||
241 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
242 | + switch (((inst >> 17) & 0b11111000) | | ||
243 | + ((inst >> 12) & 0b00000111)) { | ||
244 | case 0: op = rv_op_fmv_x_q; break; | ||
245 | case 1: op = rv_op_fclass_q; break; | ||
246 | } | ||
247 | break; | ||
248 | case 120: | ||
249 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
250 | + switch (((inst >> 17) & 0b11111000) | | ||
251 | + ((inst >> 12) & 0b00000111)) { | ||
252 | case 0: op = rv_op_fmv_s_x; break; | ||
253 | } | ||
254 | break; | ||
255 | case 121: | ||
256 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
257 | + switch (((inst >> 17) & 0b11111000) | | ||
258 | + ((inst >> 12) & 0b00000111)) { | ||
259 | case 0: op = rv_op_fmv_d_x; break; | ||
260 | } | ||
261 | break; | ||
262 | case 123: | ||
263 | - switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) { | ||
264 | + switch (((inst >> 17) & 0b11111000) | | ||
265 | + ((inst >> 12) & 0b00000111)) { | ||
266 | case 0: op = rv_op_fmv_q_x; break; | ||
267 | } | ||
268 | break; | ||
269 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
270 | case 11: op = rv_op_vxor_vv; break; | ||
271 | case 12: op = rv_op_vrgather_vv; break; | ||
272 | case 14: op = rv_op_vrgatherei16_vv; break; | ||
273 | - case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vvm; break; | ||
274 | + case 16: | ||
275 | + if (((inst >> 25) & 1) == 0) { | ||
276 | + op = rv_op_vadc_vvm; | ||
277 | + } | ||
278 | + break; | ||
279 | case 17: op = rv_op_vmadc_vvm; break; | ||
280 | - case 18: if (((inst >> 25) & 1) == 0) op = rv_op_vsbc_vvm; break; | ||
281 | + case 18: | ||
282 | + if (((inst >> 25) & 1) == 0) { | ||
283 | + op = rv_op_vsbc_vvm; | ||
284 | + } | ||
285 | + break; | ||
286 | case 19: op = rv_op_vmsbc_vvm; break; | ||
287 | case 23: | ||
288 | if (((inst >> 20) & 0b111111) == 32) | ||
289 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
290 | case 2: op = rv_op_vmsof_m; break; | ||
291 | case 3: op = rv_op_vmsif_m; break; | ||
292 | case 16: op = rv_op_viota_m; break; | ||
293 | - case 17: if (((inst >> 20) & 0b11111) == 0) op = rv_op_vid_v; break; | ||
294 | + case 17: | ||
295 | + if (((inst >> 20) & 0b11111) == 0) { | ||
296 | + op = rv_op_vid_v; | ||
297 | + } | ||
298 | + break; | ||
299 | } | ||
300 | break; | ||
301 | case 23: if ((inst >> 25) & 1) op = rv_op_vcompress_vm; break; | ||
302 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
303 | case 12: op = rv_op_vrgather_vi; break; | ||
304 | case 14: op = rv_op_vslideup_vi; break; | ||
305 | case 15: op = rv_op_vslidedown_vi; break; | ||
306 | - case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vim; break; | ||
307 | + case 16: | ||
308 | + if (((inst >> 25) & 1) == 0) { | ||
309 | + op = rv_op_vadc_vim; | ||
310 | + } | ||
311 | + break; | ||
312 | case 17: op = rv_op_vmadc_vim; break; | ||
313 | case 23: | ||
314 | if (((inst >> 20) & 0b111111) == 32) | ||
315 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
316 | case 12: op = rv_op_vrgather_vx; break; | ||
317 | case 14: op = rv_op_vslideup_vx; break; | ||
318 | case 15: op = rv_op_vslidedown_vx; break; | ||
319 | - case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vxm; break; | ||
320 | + case 16: | ||
321 | + if (((inst >> 25) & 1) == 0) { | ||
322 | + op = rv_op_vadc_vxm; | ||
323 | + } | ||
324 | + break; | ||
325 | case 17: op = rv_op_vmadc_vxm; break; | ||
326 | - case 18: if (((inst >> 25) & 1) == 0) op = rv_op_vsbc_vxm; break; | ||
327 | + case 18: | ||
328 | + if (((inst >> 25) & 1) == 0) { | ||
329 | + op = rv_op_vsbc_vxm; | ||
330 | + } | ||
331 | + break; | ||
332 | case 19: op = rv_op_vmsbc_vxm; break; | ||
333 | case 23: | ||
334 | if (((inst >> 20) & 0b111111) == 32) | ||
335 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
336 | case 28: | ||
337 | switch (((inst >> 12) & 0b111)) { | ||
338 | case 0: | ||
339 | - switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) { | ||
340 | + switch (((inst >> 20) & 0b111111100000) | | ||
341 | + ((inst >> 7) & 0b000000011111)) { | ||
342 | case 0: | ||
343 | switch (((inst >> 15) & 0b1111111111)) { | ||
344 | case 0: op = rv_op_ecall; break; | ||
345 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
346 | } | ||
347 | break; | ||
348 | case 30: | ||
349 | - switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) { | ||
350 | + switch (((inst >> 22) & 0b1111111000) | | ||
351 | + ((inst >> 12) & 0b0000000111)) { | ||
352 | case 0: op = rv_op_addd; break; | ||
353 | case 1: op = rv_op_slld; break; | ||
354 | case 5: op = rv_op_srld; break; | ||
355 | -- | ||
356 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Use cur_insn_len to store the length of the current instruction to | ||
4 | prepare for PC-relative translation. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230526072124.298466-3-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/translate.c | 4 +++- | ||
14 | 1 file changed, 3 insertions(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/translate.c | ||
19 | +++ b/target/riscv/translate.c | ||
20 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
21 | DisasContextBase base; | ||
22 | /* pc_succ_insn points to the instruction following base.pc_next */ | ||
23 | target_ulong pc_succ_insn; | ||
24 | + target_ulong cur_insn_len; | ||
25 | target_ulong priv_ver; | ||
26 | RISCVMXL misa_mxl_max; | ||
27 | RISCVMXL xl; | ||
28 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | ||
29 | }; | ||
30 | |||
31 | ctx->virt_inst_excp = false; | ||
32 | + ctx->cur_insn_len = insn_len(opcode); | ||
33 | /* Check for compressed insn */ | ||
34 | - if (insn_len(opcode) == 2) { | ||
35 | + if (ctx->cur_insn_len == 2) { | ||
36 | ctx->opcode = opcode; | ||
37 | ctx->pc_succ_insn = ctx->base.pc_next + 2; | ||
38 | /* | ||
39 | -- | ||
40 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Reduce reliance on absolute value to prepare for PC-relative translation. | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20230526072124.298466-4-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/translate.c | 8 +++++--- | ||
13 | target/riscv/insn_trans/trans_rvi.c.inc | 4 ++-- | ||
14 | 2 files changed, 7 insertions(+), 5 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/translate.c | ||
19 | +++ b/target/riscv/translate.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static void exit_tb(DisasContext *ctx) | ||
21 | tcg_gen_exit_tb(NULL, 0); | ||
22 | } | ||
23 | |||
24 | -static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) | ||
25 | +static void gen_goto_tb(DisasContext *ctx, int n, target_long diff) | ||
26 | { | ||
27 | + target_ulong dest = ctx->base.pc_next + diff; | ||
28 | + | ||
29 | /* | ||
30 | * Under itrigger, instruction executes one by one like singlestep, | ||
31 | * direct block chain benefits will be small. | ||
32 | @@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
33 | } | ||
34 | |||
35 | gen_set_gpri(ctx, rd, ctx->pc_succ_insn); | ||
36 | - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */ | ||
37 | + gen_goto_tb(ctx, 0, imm); /* must use this for safety */ | ||
38 | ctx->base.is_jmp = DISAS_NORETURN; | ||
39 | } | ||
40 | |||
41 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) | ||
42 | |||
43 | switch (ctx->base.is_jmp) { | ||
44 | case DISAS_TOO_MANY: | ||
45 | - gen_goto_tb(ctx, 0, ctx->base.pc_next); | ||
46 | + gen_goto_tb(ctx, 0, 0); | ||
47 | break; | ||
48 | case DISAS_NORETURN: | ||
49 | break; | ||
50 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
53 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
54 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
55 | } else { | ||
56 | tcg_gen_brcond_tl(cond, src1, src2, l); | ||
57 | } | ||
58 | - gen_goto_tb(ctx, 1, ctx->pc_succ_insn); | ||
59 | + gen_goto_tb(ctx, 1, ctx->cur_insn_len); | ||
60 | |||
61 | gen_set_label(l); /* branch taken */ | ||
62 | |||
63 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
64 | gen_pc_plus_diff(target_pc, ctx, next_pc); | ||
65 | gen_exception_inst_addr_mis(ctx, target_pc); | ||
66 | } else { | ||
67 | - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm); | ||
68 | + gen_goto_tb(ctx, 0, a->imm); | ||
69 | } | ||
70 | ctx->base.is_jmp = DISAS_NORETURN; | ||
71 | |||
72 | -- | ||
73 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | Reduce reliance on absolute values by using true pc difference for | ||
4 | gen_pc_plus_diff() to prepare for PC-relative translation. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230526072124.298466-6-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/translate.c | 13 ++++++------- | ||
14 | target/riscv/insn_trans/trans_rvi.c.inc | 6 ++---- | ||
15 | target/riscv/insn_trans/trans_rvzce.c.inc | 2 +- | ||
16 | 3 files changed, 9 insertions(+), 12 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/translate.c | ||
21 | +++ b/target/riscv/translate.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void decode_save_opc(DisasContext *ctx) | ||
23 | } | ||
24 | |||
25 | static void gen_pc_plus_diff(TCGv target, DisasContext *ctx, | ||
26 | - target_ulong dest) | ||
27 | + target_long diff) | ||
28 | { | ||
29 | + target_ulong dest = ctx->base.pc_next + diff; | ||
30 | + | ||
31 | if (get_xl(ctx) == MXL_RV32) { | ||
32 | dest = (int32_t)dest; | ||
33 | } | ||
34 | @@ -XXX,XX +XXX,XX @@ static void gen_pc_plus_diff(TCGv target, DisasContext *ctx, | ||
35 | |||
36 | static void gen_update_pc(DisasContext *ctx, target_long diff) | ||
37 | { | ||
38 | - gen_pc_plus_diff(cpu_pc, ctx, ctx->base.pc_next + diff); | ||
39 | + gen_pc_plus_diff(cpu_pc, ctx, diff); | ||
40 | } | ||
41 | |||
42 | static void generate_exception(DisasContext *ctx, int excp) | ||
43 | @@ -XXX,XX +XXX,XX @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t) | ||
44 | |||
45 | static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) | ||
46 | { | ||
47 | - target_ulong next_pc; | ||
48 | - | ||
49 | /* check misaligned: */ | ||
50 | - next_pc = ctx->base.pc_next + imm; | ||
51 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) { | ||
52 | - if ((next_pc & 0x3) != 0) { | ||
53 | + if ((imm & 0x3) != 0) { | ||
54 | TCGv target_pc = tcg_temp_new(); | ||
55 | - gen_pc_plus_diff(target_pc, ctx, next_pc); | ||
56 | + gen_pc_plus_diff(target_pc, ctx, imm); | ||
57 | gen_exception_inst_addr_mis(ctx, target_pc); | ||
58 | return; | ||
59 | } | ||
60 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
63 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
64 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
65 | TCGLabel *l = gen_new_label(); | ||
66 | TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
67 | TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN); | ||
68 | - target_ulong next_pc; | ||
69 | |||
70 | if (get_xl(ctx) == MXL_RV128) { | ||
71 | TCGv src1h = get_gprh(ctx, a->rs1); | ||
72 | @@ -XXX,XX +XXX,XX @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
73 | |||
74 | gen_set_label(l); /* branch taken */ | ||
75 | |||
76 | - next_pc = ctx->base.pc_next + a->imm; | ||
77 | if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca && | ||
78 | - (next_pc & 0x3)) { | ||
79 | + (a->imm & 0x3)) { | ||
80 | /* misaligned */ | ||
81 | TCGv target_pc = tcg_temp_new(); | ||
82 | - gen_pc_plus_diff(target_pc, ctx, next_pc); | ||
83 | + gen_pc_plus_diff(target_pc, ctx, a->imm); | ||
84 | gen_exception_inst_addr_mis(ctx, target_pc); | ||
85 | } else { | ||
86 | gen_goto_tb(ctx, 0, a->imm); | ||
87 | diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
88 | index XXXXXXX..XXXXXXX 100644 | ||
89 | --- a/target/riscv/insn_trans/trans_rvzce.c.inc | ||
90 | +++ b/target/riscv/insn_trans/trans_rvzce.c.inc | ||
91 | @@ -XXX,XX +XXX,XX @@ static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a) | ||
92 | * Update pc to current for the non-unwinding exception | ||
93 | * that might come from cpu_ld*_code() in the helper. | ||
94 | */ | ||
95 | - tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); | ||
96 | + gen_update_pc(ctx, 0); | ||
97 | gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index)); | ||
98 | |||
99 | /* c.jt vs c.jalt depends on the index. */ | ||
100 | -- | ||
101 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
2 | 1 | ||
3 | pc_succ_insn is no longer useful after the introduce of cur_insn_len | ||
4 | and all pc related value use diff value instead of absolute value. | ||
5 | |||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230526072124.298466-8-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/translate.c | 7 +------ | ||
14 | 1 file changed, 1 insertion(+), 6 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/translate.c | ||
19 | +++ b/target/riscv/translate.c | ||
20 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
21 | |||
22 | typedef struct DisasContext { | ||
23 | DisasContextBase base; | ||
24 | - /* pc_succ_insn points to the instruction following base.pc_next */ | ||
25 | - target_ulong pc_succ_insn; | ||
26 | target_ulong cur_insn_len; | ||
27 | target_ulong pc_save; | ||
28 | target_ulong priv_ver; | ||
29 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | ||
30 | /* Check for compressed insn */ | ||
31 | if (ctx->cur_insn_len == 2) { | ||
32 | ctx->opcode = opcode; | ||
33 | - ctx->pc_succ_insn = ctx->base.pc_next + 2; | ||
34 | /* | ||
35 | * The Zca extension is added as way to refer to instructions in the C | ||
36 | * extension that do not include the floating-point loads and stores | ||
37 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | ||
38 | translator_lduw(env, &ctx->base, | ||
39 | ctx->base.pc_next + 2)); | ||
40 | ctx->opcode = opcode32; | ||
41 | - ctx->pc_succ_insn = ctx->base.pc_next + 4; | ||
42 | |||
43 | for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) { | ||
44 | if (decoders[i].guard_func(ctx) && | ||
45 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
46 | uint32_t tb_flags = ctx->base.tb->flags; | ||
47 | |||
48 | ctx->pc_save = ctx->base.pc_first; | ||
49 | - ctx->pc_succ_insn = ctx->base.pc_first; | ||
50 | ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV); | ||
51 | ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX); | ||
52 | ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS); | ||
53 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) | ||
54 | |||
55 | ctx->ol = ctx->xl; | ||
56 | decode_opc(env, ctx, opcode16); | ||
57 | - ctx->base.pc_next = ctx->pc_succ_insn; | ||
58 | + ctx->base.pc_next += ctx->cur_insn_len; | ||
59 | |||
60 | /* Only the first insn within a TB is allowed to cross a page boundary. */ | ||
61 | if (ctx->base.is_jmp == DISAS_NEXT) { | ||
62 | -- | ||
63 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | Currently, virt machine supports two pflash instances each with | ||
4 | 32MB size. However, the first pflash is always assumed to | ||
5 | contain M-mode firmware and reset vector is set to this if | ||
6 | enabled. Hence, for S-mode payloads like EDK2, only one pflash | ||
7 | instance is available for use. This means both code and NV variables | ||
8 | of EDK2 will need to use the same pflash. | ||
9 | |||
10 | The OS distros keep the EDK2 FW code as readonly. When non-volatile | ||
11 | variables also need to share the same pflash, it is not possible | ||
12 | to keep it as readonly since variables need write access. | ||
13 | |||
14 | To resolve this issue, the code and NV variables need to be separated. | ||
15 | But in that case we need an extra flash. Hence, modify the convention | ||
16 | for non-KVM guests such that, pflash0 will contain the M-mode FW | ||
17 | only when "-bios none" option is used. Otherwise, pflash0 will contain | ||
18 | the S-mode payload FW. This enables both pflash instances available | ||
19 | for EDK2 use. | ||
20 | |||
21 | When KVM is enabled, pflash0 is always assumed to contain the | ||
22 | S-mode payload firmware only. | ||
23 | |||
24 | Example usage: | ||
25 | 1) pflash0 containing M-mode FW | ||
26 | qemu-system-riscv64 -bios none -pflash <mmode_fw> -machine virt | ||
27 | or | ||
28 | qemu-system-riscv64 -bios none \ | ||
29 | -drive file=<mmode_fw>,if=pflash,format=raw,unit=0 -machine virt | ||
30 | |||
31 | 2) pflash0 containing S-mode payload like EDK2 | ||
32 | qemu-system-riscv64 -pflash <smode_fw_code> -pflash <smode_vars> -machine virt | ||
33 | or | ||
34 | qemu-system-riscv64 -bios <opensbi_fw> \ | ||
35 | -pflash <smode_fw_code> \ | ||
36 | -pflash <smode_vars> \ | ||
37 | -machine virt | ||
38 | or | ||
39 | qemu-system-riscv64 -bios <opensbi_fw> \ | ||
40 | -drive file=<smode_fw_code>,if=pflash,format=raw,unit=0,readonly=on \ | ||
41 | -drive file=<smode_fw_vars>,if=pflash,format=raw,unit=1 \ | ||
42 | -machine virt | ||
43 | |||
44 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
45 | Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de> | ||
46 | Tested-by: Andrea Bolognani <abologna@redhat.com> | ||
47 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
48 | Message-Id: <20230601045910.18646-2-sunilvl@ventanamicro.com> | ||
49 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
50 | --- | ||
51 | hw/riscv/virt.c | 53 ++++++++++++++++++++----------------------------- | ||
52 | 1 file changed, 21 insertions(+), 32 deletions(-) | ||
53 | |||
54 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/hw/riscv/virt.c | ||
57 | +++ b/hw/riscv/virt.c | ||
58 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) | ||
59 | target_ulong firmware_end_addr, kernel_start_addr; | ||
60 | const char *firmware_name = riscv_default_firmware_name(&s->soc[0]); | ||
61 | uint32_t fdt_load_addr; | ||
62 | - uint64_t kernel_entry; | ||
63 | + uint64_t kernel_entry = 0; | ||
64 | |||
65 | /* | ||
66 | * Only direct boot kernel is currently supported for KVM VM, | ||
67 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) | ||
68 | firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, | ||
69 | start_addr, NULL); | ||
70 | |||
71 | - if (drive_get(IF_PFLASH, 0, 1)) { | ||
72 | - /* | ||
73 | - * S-mode FW like EDK2 will be kept in second plash (unit 1). | ||
74 | - * When both kernel, initrd and pflash options are provided in the | ||
75 | - * command line, the kernel and initrd will be copied to the fw_cfg | ||
76 | - * table and opensbi will jump to the flash address which is the | ||
77 | - * entry point of S-mode FW. It is the job of the S-mode FW to load | ||
78 | - * the kernel and initrd using fw_cfg table. | ||
79 | - * | ||
80 | - * If only pflash is given but not -kernel, then it is the job of | ||
81 | - * of the S-mode firmware to locate and load the kernel. | ||
82 | - * In either case, the next_addr for opensbi will be the flash address. | ||
83 | - */ | ||
84 | - riscv_setup_firmware_boot(machine); | ||
85 | - kernel_entry = virt_memmap[VIRT_FLASH].base + | ||
86 | - virt_memmap[VIRT_FLASH].size / 2; | ||
87 | - } else if (machine->kernel_filename) { | ||
88 | + if (drive_get(IF_PFLASH, 0, 0)) { | ||
89 | + if (machine->firmware && !strcmp(machine->firmware, "none") && | ||
90 | + !kvm_enabled()) { | ||
91 | + /* | ||
92 | + * Pflash was supplied but bios is none and not KVM guest, | ||
93 | + * let's overwrite the address we jump to after reset to | ||
94 | + * the base of the flash. | ||
95 | + */ | ||
96 | + start_addr = virt_memmap[VIRT_FLASH].base; | ||
97 | + } else { | ||
98 | + /* | ||
99 | + * Pflash was supplied but either KVM guest or bios is not none. | ||
100 | + * In this case, base of the flash would contain S-mode payload. | ||
101 | + */ | ||
102 | + riscv_setup_firmware_boot(machine); | ||
103 | + kernel_entry = virt_memmap[VIRT_FLASH].base; | ||
104 | + } | ||
105 | + } | ||
106 | + | ||
107 | + if (machine->kernel_filename && !kernel_entry) { | ||
108 | kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0], | ||
109 | firmware_end_addr); | ||
110 | |||
111 | kernel_entry = riscv_load_kernel(machine, &s->soc[0], | ||
112 | kernel_start_addr, true, NULL); | ||
113 | - } else { | ||
114 | - /* | ||
115 | - * If dynamic firmware is used, it doesn't know where is the next mode | ||
116 | - * if kernel argument is not set. | ||
117 | - */ | ||
118 | - kernel_entry = 0; | ||
119 | - } | ||
120 | - | ||
121 | - if (drive_get(IF_PFLASH, 0, 0)) { | ||
122 | - /* | ||
123 | - * Pflash was supplied, let's overwrite the address we jump to after | ||
124 | - * reset to the base of the flash. | ||
125 | - */ | ||
126 | - start_addr = virt_memmap[VIRT_FLASH].base; | ||
127 | } | ||
128 | |||
129 | fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, | ||
130 | -- | ||
131 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Ivan Klokov <ivan.klokov@syntacore.com> | ||
2 | 1 | ||
3 | Added QEMU option 'vpu' to log vector extension registers such as gpr\fpu. | ||
4 | |||
5 | Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20230410124451.15929-2-ivan.klokov@syntacore.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | include/hw/core/cpu.h | 2 ++ | ||
11 | include/qemu/log.h | 1 + | ||
12 | accel/tcg/cpu-exec.c | 3 +++ | ||
13 | util/log.c | 2 ++ | ||
14 | 4 files changed, 8 insertions(+) | ||
15 | |||
16 | diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/hw/core/cpu.h | ||
19 | +++ b/include/hw/core/cpu.h | ||
20 | @@ -XXX,XX +XXX,XX @@ GuestPanicInformation *cpu_get_crash_info(CPUState *cpu); | ||
21 | * @CPU_DUMP_CODE: | ||
22 | * @CPU_DUMP_FPU: dump FPU register state, not just integer | ||
23 | * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state | ||
24 | + * @CPU_DUMP_VPU: dump VPU registers | ||
25 | */ | ||
26 | enum CPUDumpFlags { | ||
27 | CPU_DUMP_CODE = 0x00010000, | ||
28 | CPU_DUMP_FPU = 0x00020000, | ||
29 | CPU_DUMP_CCOP = 0x00040000, | ||
30 | + CPU_DUMP_VPU = 0x00080000, | ||
31 | }; | ||
32 | |||
33 | /** | ||
34 | diff --git a/include/qemu/log.h b/include/qemu/log.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/include/qemu/log.h | ||
37 | +++ b/include/qemu/log.h | ||
38 | @@ -XXX,XX +XXX,XX @@ bool qemu_log_separate(void); | ||
39 | /* LOG_STRACE is used for user-mode strace logging. */ | ||
40 | #define LOG_STRACE (1 << 19) | ||
41 | #define LOG_PER_THREAD (1 << 20) | ||
42 | +#define CPU_LOG_TB_VPU (1 << 21) | ||
43 | |||
44 | /* Lock/unlock output. */ | ||
45 | |||
46 | diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c | ||
47 | index XXXXXXX..XXXXXXX 100644 | ||
48 | --- a/accel/tcg/cpu-exec.c | ||
49 | +++ b/accel/tcg/cpu-exec.c | ||
50 | @@ -XXX,XX +XXX,XX @@ static void log_cpu_exec(target_ulong pc, CPUState *cpu, | ||
51 | #if defined(TARGET_I386) | ||
52 | flags |= CPU_DUMP_CCOP; | ||
53 | #endif | ||
54 | + if (qemu_loglevel_mask(CPU_LOG_TB_VPU)) { | ||
55 | + flags |= CPU_DUMP_VPU; | ||
56 | + } | ||
57 | cpu_dump_state(cpu, logfile, flags); | ||
58 | qemu_log_unlock(logfile); | ||
59 | } | ||
60 | diff --git a/util/log.c b/util/log.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/util/log.c | ||
63 | +++ b/util/log.c | ||
64 | @@ -XXX,XX +XXX,XX @@ const QEMULogItem qemu_log_items[] = { | ||
65 | "log every user-mode syscall, its input, and its result" }, | ||
66 | { LOG_PER_THREAD, "tid", | ||
67 | "open a separate log file per thread; filename must contain '%d'" }, | ||
68 | + { CPU_LOG_TB_VPU, "vpu", | ||
69 | + "include VPU registers in the 'cpu' logging" }, | ||
70 | { 0, NULL, NULL }, | ||
71 | }; | ||
72 | |||
73 | -- | ||
74 | 2.40.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Xiao Wang <xiao.w.wang@intel.com> | ||
2 | 1 | ||
3 | There's no code using MTYPE, which was a concept used in older vector | ||
4 | implementation. | ||
5 | |||
6 | Signed-off-by: Xiao Wang <xiao.w.wang@intel.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Message-Id: <20230608053517.4102648-1-xiao.w.wang@intel.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/vector_helper.c | 6 +----- | ||
13 | 1 file changed, 1 insertion(+), 5 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/vector_helper.c | ||
18 | +++ b/target/riscv/vector_helper.c | ||
19 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
20 | |||
21 | /* | ||
22 | * masked unit-stride load and store operation will be a special case of | ||
23 | - * stride, stride = NF * sizeof (MTYPE) | ||
24 | + * stride, stride = NF * sizeof (ETYPE) | ||
25 | */ | ||
26 | |||
27 | #define GEN_VEXT_LD_US(NAME, ETYPE, LOAD_FN) \ | ||
28 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d) | ||
29 | #define DO_MAX(N, M) ((N) >= (M) ? (N) : (M)) | ||
30 | #define DO_MIN(N, M) ((N) >= (M) ? (M) : (N)) | ||
31 | |||
32 | -/* Unsigned min/max */ | ||
33 | -#define DO_MAXU(N, M) DO_MAX((UMTYPE)N, (UMTYPE)M) | ||
34 | -#define DO_MINU(N, M) DO_MIN((UMTYPE)N, (UMTYPE)M) | ||
35 | - | ||
36 | /* | ||
37 | * load and store whole register instructions | ||
38 | */ | ||
39 | -- | ||
40 | 2.40.1 | diff view generated by jsdifflib |