1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4: |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit d70075373af51b6aa1d637962c962120e201fc98: | 3 | Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400) |
4 | |||
5 | Merge tag 'for_upstream' of git://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2022-01-07 17:24:24 -0800) | ||
6 | 4 | ||
7 | are available in the Git repository at: | 5 | are available in the Git repository at: |
8 | 6 | ||
9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220108 | 7 | https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911 |
10 | 8 | ||
11 | for you to fetch changes up to 48eaeb56debf91817dea00a2cd9c1f6c986eb531: | 9 | for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a: |
12 | 10 | ||
13 | target/riscv: Implement the stval/mtval illegal instruction (2022-01-08 15:46:10 +1000) | 11 | target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000) |
14 | 12 | ||
15 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
16 | Second RISC-V PR for QEMU 7.0 | 14 | First RISC-V PR for 8.2 |
17 | 15 | ||
18 | - Fix illegal instruction when PMP is disabled | 16 | * Remove 'host' CPU from TCG |
19 | - SiFive PDMA 64-bit support | 17 | * riscv_htif Fixup printing on big endian hosts |
20 | - SiFive PLIC cleanups | 18 | * Add zmmul isa string |
21 | - Mark Hypervisor extension as non experimental | 19 | * Add smepmp isa string |
22 | - Enable Hypervisor extension by default | 20 | * Fix page_check_range use in fault-only-first |
23 | - Support 32 cores on the virt machine | 21 | * Use existing lookup tables for MixColumns |
24 | - Corrections for the Vector extension | 22 | * Add RISC-V vector cryptographic instruction set support |
25 | - Experimental support for 128-bit CPUs | 23 | * Implement WARL behaviour for mcountinhibit/mcounteren |
26 | - stval and mtval support for illegal instructions | 24 | * Add Zihintntl extension ISA string to DTS |
25 | * Fix zfa fleq.d and fltq.d | ||
26 | * Fix upper/lower mtime write calculation | ||
27 | * Make rtc variable names consistent | ||
28 | * Use abi type for linux-user target_ucontext | ||
29 | * Add RISC-V KVM AIA Support | ||
30 | * Fix riscv,pmu DT node path in the virt machine | ||
31 | * Update CSR bits name for svadu extension | ||
32 | * Mark zicond non-experimental | ||
33 | * Fix satp_mode_finalize() when satp_mode.supported = 0 | ||
34 | * Fix non-KVM --enable-debug build | ||
35 | * Add new extensions to hwprobe | ||
36 | * Use accelerated helper for AES64KS1I | ||
37 | * Allocate itrigger timers only once | ||
38 | * Respect mseccfg.RLB for pmpaddrX changes | ||
39 | * Align the AIA model to v1.0 ratified spec | ||
40 | * Don't read the CSR in riscv_csrrw_do64 | ||
27 | 41 | ||
28 | ---------------------------------------------------------------- | 42 | ---------------------------------------------------------------- |
29 | Alistair Francis (11): | 43 | Akihiko Odaki (1): |
30 | hw/intc: sifive_plic: Add a reset function | 44 | target/riscv: Allocate itrigger timers only once |
31 | hw/intc: sifive_plic: Cleanup the write function | ||
32 | hw/intc: sifive_plic: Cleanup the read function | ||
33 | hw/intc: sifive_plic: Cleanup remaining functions | ||
34 | target/riscv: Mark the Hypervisor extension as non experimental | ||
35 | target/riscv: Enable the Hypervisor extension by default | ||
36 | hw/riscv: Use error_fatal for SoC realisation | ||
37 | hw/riscv: virt: Allow support for 32 cores | ||
38 | target/riscv: Set the opcode in DisasContext | ||
39 | target/riscv: Fixup setting GVA | ||
40 | target/riscv: Implement the stval/mtval illegal instruction | ||
41 | 45 | ||
42 | Bin Meng (1): | 46 | Ard Biesheuvel (2): |
43 | roms/opensbi: Upgrade from v0.9 to v1.0 | 47 | target/riscv: Use existing lookup tables for MixColumns |
48 | target/riscv: Use accelerated helper for AES64KS1I | ||
44 | 49 | ||
45 | Frank Chang (3): | 50 | Conor Dooley (1): |
46 | target/riscv: rvv-1.0: Call the correct RVF/RVD check function for widening fp insns | 51 | hw/riscv: virt: Fix riscv,pmu DT node path |
47 | target/riscv: rvv-1.0: Call the correct RVF/RVD check function for widening fp/int type-convert insns | ||
48 | target/riscv: rvv-1.0: Call the correct RVF/RVD check function for narrowing fp/int type-convert insns | ||
49 | 52 | ||
50 | Frédéric Pétrot (18): | 53 | Daniel Henrique Barboza (6): |
51 | exec/memop: Adding signedness to quad definitions | 54 | target/riscv/cpu.c: do not run 'host' CPU with TCG |
52 | exec/memop: Adding signed quad and octo defines | 55 | target/riscv/cpu.c: add zmmul isa string |
53 | qemu/int128: addition of div/rem 128-bit operations | 56 | target/riscv/cpu.c: add smepmp isa string |
54 | target/riscv: additional macros to check instruction support | 57 | target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0 |
55 | target/riscv: separation of bitwise logic and arithmetic helpers | 58 | hw/riscv/virt.c: fix non-KVM --enable-debug build |
56 | target/riscv: array for the 64 upper bits of 128-bit registers | 59 | hw/intc/riscv_aplic.c fix non-KVM --enable-debug build |
57 | target/riscv: setup everything for rv64 to support rv128 execution | ||
58 | target/riscv: moving some insns close to similar insns | ||
59 | target/riscv: accessors to registers upper part and 128-bit load/store | ||
60 | target/riscv: support for 128-bit bitwise instructions | ||
61 | target/riscv: support for 128-bit U-type instructions | ||
62 | target/riscv: support for 128-bit shift instructions | ||
63 | target/riscv: support for 128-bit arithmetic instructions | ||
64 | target/riscv: support for 128-bit M extension | ||
65 | target/riscv: adding high part of some csrs | ||
66 | target/riscv: helper functions to wrap calls to 128-bit csr insns | ||
67 | target/riscv: modification of the trans_csrxx for 128-bit support | ||
68 | target/riscv: actual functions to realize crs 128-bit insns | ||
69 | 60 | ||
70 | Jim Shu (2): | 61 | Dickon Hood (2): |
71 | hw/dma: sifive_pdma: support high 32-bit access of 64-bit register | 62 | target/riscv: Refactor translation of vector-widening instruction |
72 | hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers | 63 | target/riscv: Add Zvbb ISA extension support |
64 | |||
65 | Jason Chien (3): | ||
66 | target/riscv: Add Zihintntl extension ISA string to DTS | ||
67 | hw/intc: Fix upper/lower mtime write calculation | ||
68 | hw/intc: Make rtc variable names consistent | ||
69 | |||
70 | Kiran Ostrolenk (4): | ||
71 | target/riscv: Refactor some of the generic vector functionality | ||
72 | target/riscv: Refactor vector-vector translation macro | ||
73 | target/riscv: Refactor some of the generic vector functionality | ||
74 | target/riscv: Add Zvknh ISA extension support | ||
75 | |||
76 | LIU Zhiwei (3): | ||
77 | target/riscv: Fix page_check_range use in fault-only-first | ||
78 | target/riscv: Fix zfa fleq.d and fltq.d | ||
79 | linux-user/riscv: Use abi type for target_ucontext | ||
80 | |||
81 | Lawrence Hunter (2): | ||
82 | target/riscv: Add Zvbc ISA extension support | ||
83 | target/riscv: Add Zvksh ISA extension support | ||
84 | |||
85 | Leon Schuermann (1): | ||
86 | target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes | ||
87 | |||
88 | Max Chou (3): | ||
89 | crypto: Create sm4_subword | ||
90 | crypto: Add SM4 constant parameter CK | ||
91 | target/riscv: Add Zvksed ISA extension support | ||
92 | |||
93 | Nazar Kazakov (4): | ||
94 | target/riscv: Remove redundant "cpu_vl == 0" checks | ||
95 | target/riscv: Move vector translation checks | ||
96 | target/riscv: Add Zvkned ISA extension support | ||
97 | target/riscv: Add Zvkg ISA extension support | ||
73 | 98 | ||
74 | Nikita Shubin (1): | 99 | Nikita Shubin (1): |
75 | target/riscv/pmp: fix no pmp illegal intrs | 100 | target/riscv: don't read CSR in riscv_csrrw_do64 |
76 | 101 | ||
77 | Philipp Tomsich (1): | 102 | Rob Bradford (1): |
78 | target/riscv: Fix position of 'experimental' comment | 103 | target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren |
79 | 104 | ||
80 | include/disas/dis-asm.h | 1 + | 105 | Robbin Ehn (1): |
81 | include/exec/memop.h | 15 +- | 106 | linux-user/riscv: Add new extensions to hwprobe |
82 | include/hw/riscv/virt.h | 2 +- | ||
83 | include/qemu/int128.h | 27 + | ||
84 | include/tcg/tcg-op.h | 4 +- | ||
85 | target/arm/translate-a32.h | 4 +- | ||
86 | target/riscv/cpu.h | 24 + | ||
87 | target/riscv/cpu_bits.h | 3 + | ||
88 | target/riscv/helper.h | 9 + | ||
89 | target/riscv/insn16.decode | 27 +- | ||
90 | target/riscv/insn32.decode | 25 + | ||
91 | accel/tcg/cputlb.c | 30 +- | ||
92 | accel/tcg/user-exec.c | 8 +- | ||
93 | disas/riscv.c | 5 + | ||
94 | hw/dma/sifive_pdma.c | 181 ++++++- | ||
95 | hw/intc/sifive_plic.c | 254 +++------ | ||
96 | hw/riscv/microchip_pfsoc.c | 2 +- | ||
97 | hw/riscv/opentitan.c | 2 +- | ||
98 | hw/riscv/sifive_e.c | 2 +- | ||
99 | hw/riscv/sifive_u.c | 2 +- | ||
100 | target/alpha/translate.c | 32 +- | ||
101 | target/arm/helper-a64.c | 8 +- | ||
102 | target/arm/translate-a64.c | 8 +- | ||
103 | target/arm/translate-neon.c | 6 +- | ||
104 | target/arm/translate-sve.c | 10 +- | ||
105 | target/arm/translate-vfp.c | 8 +- | ||
106 | target/arm/translate.c | 2 +- | ||
107 | target/cris/translate.c | 2 +- | ||
108 | target/hppa/translate.c | 4 +- | ||
109 | target/i386/tcg/mem_helper.c | 2 +- | ||
110 | target/i386/tcg/translate.c | 36 +- | ||
111 | target/m68k/op_helper.c | 2 +- | ||
112 | target/mips/tcg/translate.c | 58 +- | ||
113 | target/mips/tcg/tx79_translate.c | 8 +- | ||
114 | target/ppc/translate.c | 32 +- | ||
115 | target/riscv/cpu.c | 34 +- | ||
116 | target/riscv/cpu_helper.c | 24 +- | ||
117 | target/riscv/csr.c | 194 ++++++- | ||
118 | target/riscv/gdbstub.c | 5 + | ||
119 | target/riscv/m128_helper.c | 109 ++++ | ||
120 | target/riscv/machine.c | 22 + | ||
121 | target/riscv/op_helper.c | 47 +- | ||
122 | target/riscv/translate.c | 257 +++++++-- | ||
123 | target/s390x/tcg/mem_helper.c | 8 +- | ||
124 | target/s390x/tcg/translate.c | 8 +- | ||
125 | target/sh4/translate.c | 12 +- | ||
126 | target/sparc/translate.c | 36 +- | ||
127 | target/tricore/translate.c | 4 +- | ||
128 | target/xtensa/translate.c | 4 +- | ||
129 | tcg/tcg.c | 4 +- | ||
130 | tcg/tci.c | 16 +- | ||
131 | util/int128.c | 147 +++++ | ||
132 | accel/tcg/ldst_common.c.inc | 8 +- | ||
133 | target/mips/tcg/micromips_translate.c.inc | 10 +- | ||
134 | target/ppc/translate/fixedpoint-impl.c.inc | 22 +- | ||
135 | target/ppc/translate/fp-impl.c.inc | 4 +- | ||
136 | target/ppc/translate/vsx-impl.c.inc | 42 +- | ||
137 | target/riscv/insn_trans/trans_rva.c.inc | 22 +- | ||
138 | target/riscv/insn_trans/trans_rvb.c.inc | 48 +- | ||
139 | target/riscv/insn_trans/trans_rvd.c.inc | 4 +- | ||
140 | target/riscv/insn_trans/trans_rvh.c.inc | 4 +- | ||
141 | target/riscv/insn_trans/trans_rvi.c.inc | 716 +++++++++++++++++++++---- | ||
142 | target/riscv/insn_trans/trans_rvm.c.inc | 192 ++++++- | ||
143 | target/riscv/insn_trans/trans_rvv.c.inc | 78 ++- | ||
144 | target/s390x/tcg/translate_vx.c.inc | 18 +- | ||
145 | tcg/aarch64/tcg-target.c.inc | 2 +- | ||
146 | tcg/arm/tcg-target.c.inc | 10 +- | ||
147 | tcg/i386/tcg-target.c.inc | 12 +- | ||
148 | tcg/mips/tcg-target.c.inc | 12 +- | ||
149 | tcg/ppc/tcg-target.c.inc | 16 +- | ||
150 | tcg/riscv/tcg-target.c.inc | 6 +- | ||
151 | tcg/s390x/tcg-target.c.inc | 18 +- | ||
152 | tcg/sparc/tcg-target.c.inc | 16 +- | ||
153 | pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 78680 -> 108504 bytes | ||
154 | pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | Bin 727464 -> 838904 bytes | ||
155 | pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 75096 -> 105296 bytes | ||
156 | pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | Bin 781264 -> 934696 bytes | ||
157 | roms/opensbi | 2 +- | ||
158 | target/riscv/meson.build | 1 + | ||
159 | target/s390x/tcg/insn-data.def | 28 +- | ||
160 | util/meson.build | 1 + | ||
161 | 81 files changed, 2318 insertions(+), 750 deletions(-) | ||
162 | create mode 100644 target/riscv/m128_helper.c | ||
163 | create mode 100644 util/int128.c | ||
164 | 107 | ||
108 | Thomas Huth (2): | ||
109 | hw/char/riscv_htif: Fix printing of console characters on big endian hosts | ||
110 | hw/char/riscv_htif: Fix the console syscall on big endian hosts | ||
111 | |||
112 | Tommy Wu (1): | ||
113 | target/riscv: Align the AIA model to v1.0 ratified spec | ||
114 | |||
115 | Vineet Gupta (1): | ||
116 | riscv: zicond: make non-experimental | ||
117 | |||
118 | Weiwei Li (1): | ||
119 | target/riscv: Update CSR bits name for svadu extension | ||
120 | |||
121 | Yong-Xuan Wang (5): | ||
122 | target/riscv: support the AIA device emulation with KVM enabled | ||
123 | target/riscv: check the in-kernel irqchip support | ||
124 | target/riscv: Create an KVM AIA irqchip | ||
125 | target/riscv: update APLIC and IMSIC to support KVM AIA | ||
126 | target/riscv: select KVM AIA in riscv virt machine | ||
127 | |||
128 | include/crypto/aes.h | 7 + | ||
129 | include/crypto/sm4.h | 9 + | ||
130 | target/riscv/cpu_bits.h | 8 +- | ||
131 | target/riscv/cpu_cfg.h | 9 + | ||
132 | target/riscv/debug.h | 3 +- | ||
133 | target/riscv/helper.h | 98 +++ | ||
134 | target/riscv/kvm_riscv.h | 5 + | ||
135 | target/riscv/vector_internals.h | 228 +++++++ | ||
136 | target/riscv/insn32.decode | 58 ++ | ||
137 | crypto/aes.c | 4 +- | ||
138 | crypto/sm4.c | 10 + | ||
139 | hw/char/riscv_htif.c | 12 +- | ||
140 | hw/intc/riscv_aclint.c | 11 +- | ||
141 | hw/intc/riscv_aplic.c | 52 +- | ||
142 | hw/intc/riscv_imsic.c | 25 +- | ||
143 | hw/riscv/virt.c | 374 ++++++------ | ||
144 | linux-user/riscv/signal.c | 4 +- | ||
145 | linux-user/syscall.c | 14 +- | ||
146 | target/arm/tcg/crypto_helper.c | 10 +- | ||
147 | target/riscv/cpu.c | 83 ++- | ||
148 | target/riscv/cpu_helper.c | 6 +- | ||
149 | target/riscv/crypto_helper.c | 51 +- | ||
150 | target/riscv/csr.c | 54 +- | ||
151 | target/riscv/debug.c | 15 +- | ||
152 | target/riscv/kvm.c | 201 ++++++- | ||
153 | target/riscv/pmp.c | 4 + | ||
154 | target/riscv/translate.c | 1 + | ||
155 | target/riscv/vcrypto_helper.c | 970 ++++++++++++++++++++++++++++++ | ||
156 | target/riscv/vector_helper.c | 245 +------- | ||
157 | target/riscv/vector_internals.c | 81 +++ | ||
158 | target/riscv/insn_trans/trans_rvv.c.inc | 171 +++--- | ||
159 | target/riscv/insn_trans/trans_rvvk.c.inc | 606 +++++++++++++++++++ | ||
160 | target/riscv/insn_trans/trans_rvzfa.c.inc | 4 +- | ||
161 | target/riscv/meson.build | 4 +- | ||
162 | 34 files changed, 2785 insertions(+), 652 deletions(-) | ||
163 | create mode 100644 target/riscv/vector_internals.h | ||
164 | create mode 100644 target/riscv/vcrypto_helper.c | ||
165 | create mode 100644 target/riscv/vector_internals.c | ||
166 | create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc | diff view generated by jsdifflib |
1 | From: Philipp Tomsich <philipp.tomsich@vrull.eu> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | When commit 0643c12e4b dropped the 'x-' prefix for Zb[abcs] and set | 3 | The 'host' CPU is available in a CONFIG_KVM build and it's currently |
4 | them to be enabled by default, the comment about experimental | 4 | available for all accels, but is a KVM only CPU. This means that in a |
5 | extensions was kept in place above them. This moves it down a few | 5 | RISC-V KVM capable host we can do things like this: |
6 | lines to only cover experimental extensions. | ||
7 | 6 | ||
8 | References: 0643c12e4b ("target/riscv: Enable bitmanip Zb[abcs] instructions") | 7 | $ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic |
8 | qemu-system-riscv64: H extension requires priv spec 1.12.0 | ||
9 | 9 | ||
10 | Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu> | 10 | This CPU does not have a priv spec because we don't filter its extensions |
11 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 11 | via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all |
12 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 12 | with the 'host' CPU. |
13 | |||
14 | We don't have a way to filter the 'host' CPU out of the available CPU | ||
15 | options (-cpu help) if the build includes both KVM and TCG. What we can | ||
16 | do is to error out during riscv_cpu_realize_tcg() if the user chooses | ||
17 | the 'host' CPU with accel=tcg: | ||
18 | |||
19 | $ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic | ||
20 | qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration | ||
21 | |||
22 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 23 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
14 | Message-id: 20220106134020.1628889-1-philipp.tomsich@vrull.eu | 24 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
25 | Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 26 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 27 | --- |
17 | target/riscv/cpu.c | 3 ++- | 28 | target/riscv/cpu.c | 5 +++++ |
18 | 1 file changed, 2 insertions(+), 1 deletion(-) | 29 | 1 file changed, 5 insertions(+) |
19 | 30 | ||
20 | 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 |
21 | index XXXXXXX..XXXXXXX 100644 | 32 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/cpu.c | 33 | --- a/target/riscv/cpu.c |
23 | +++ b/target/riscv/cpu.c | 34 | +++ b/target/riscv/cpu.c |
24 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 35 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp) |
25 | DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), | 36 | CPURISCVState *env = &cpu->env; |
26 | DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | 37 | Error *local_err = NULL; |
27 | 38 | ||
28 | - /* These are experimental so mark with 'x-' */ | 39 | + if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) { |
29 | DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true), | 40 | + error_setg(errp, "'host' CPU is not compatible with TCG acceleration"); |
30 | DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true), | 41 | + return; |
31 | DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true), | 42 | + } |
32 | DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true), | ||
33 | + | 43 | + |
34 | + /* These are experimental so mark with 'x-' */ | 44 | riscv_cpu_validate_misa_mxl(cpu, &local_err); |
35 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | 45 | if (local_err != NULL) { |
36 | /* ePMP 0.9.3 */ | 46 | error_propagate(errp, local_err); |
37 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | ||
38 | -- | 47 | -- |
39 | 2.31.1 | 48 | 2.41.0 |
40 | 49 | ||
41 | 50 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Thomas Huth <thuth@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | In preparation for adding support for the illegal instruction address | 3 | The character that should be printed is stored in the 64 bit "payload" |
4 | let's fixup the Hypervisor extension setting GVA logic and improve the | 4 | variable. The code currently tries to print it by taking the address |
5 | variable names. | 5 | of the variable and passing this pointer to qemu_chr_fe_write(). However, |
6 | this only works on little endian hosts where the least significant bits | ||
7 | are stored on the lowest address. To do this in a portable way, we have | ||
8 | to store the value in an uint8_t variable instead. | ||
6 | 9 | ||
10 | Fixes: 5033606780 ("RISC-V HTIF Console") | ||
11 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Reviewed-by: Bin Meng <bmeng@tinylab.org> | ||
14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
15 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
16 | Message-Id: <20230721094720.902454-2-thuth@redhat.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
10 | Message-id: 20211220064916.107241-3-alistair.francis@opensource.wdc.com | ||
11 | --- | 18 | --- |
12 | target/riscv/cpu_helper.c | 21 ++++++--------------- | 19 | hw/char/riscv_htif.c | 3 ++- |
13 | 1 file changed, 6 insertions(+), 15 deletions(-) | 20 | 1 file changed, 2 insertions(+), 1 deletion(-) |
14 | 21 | ||
15 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | 22 | diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c |
16 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu_helper.c | 24 | --- a/hw/char/riscv_htif.c |
18 | +++ b/target/riscv/cpu_helper.c | 25 | +++ b/hw/char/riscv_htif.c |
19 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | 26 | @@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written) |
20 | 27 | s->tohost = 0; /* clear to indicate we read */ | |
21 | RISCVCPU *cpu = RISCV_CPU(cs); | 28 | return; |
22 | CPURISCVState *env = &cpu->env; | 29 | } else if (cmd == HTIF_CONSOLE_CMD_PUTC) { |
23 | + bool write_gva = false; | 30 | - qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1); |
24 | uint64_t s; | 31 | + uint8_t ch = (uint8_t)payload; |
25 | 32 | + qemu_chr_fe_write(&s->chr, &ch, 1); | |
26 | /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide | 33 | resp = 0x100 | (uint8_t)payload; |
27 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | 34 | } else { |
28 | bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG); | 35 | qemu_log("HTIF device %d: unknown command\n", device); |
29 | target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK; | ||
30 | target_ulong deleg = async ? env->mideleg : env->medeleg; | ||
31 | - bool write_tval = false; | ||
32 | target_ulong tval = 0; | ||
33 | target_ulong htval = 0; | ||
34 | target_ulong mtval2 = 0; | ||
35 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
36 | case RISCV_EXCP_INST_PAGE_FAULT: | ||
37 | case RISCV_EXCP_LOAD_PAGE_FAULT: | ||
38 | case RISCV_EXCP_STORE_PAGE_FAULT: | ||
39 | - write_tval = true; | ||
40 | + write_gva = true; | ||
41 | tval = env->badaddr; | ||
42 | break; | ||
43 | default: | ||
44 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
45 | if (riscv_has_ext(env, RVH)) { | ||
46 | target_ulong hdeleg = async ? env->hideleg : env->hedeleg; | ||
47 | |||
48 | - if (env->two_stage_lookup && write_tval) { | ||
49 | - /* | ||
50 | - * If we are writing a guest virtual address to stval, set | ||
51 | - * this to 1. If we are trapping to VS we will set this to 0 | ||
52 | - * later. | ||
53 | - */ | ||
54 | - env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 1); | ||
55 | - } else { | ||
56 | - /* For other HS-mode traps, we set this to 0. */ | ||
57 | - env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0); | ||
58 | - } | ||
59 | - | ||
60 | if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1)) { | ||
61 | /* Trap to VS mode */ | ||
62 | /* | ||
63 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
64 | cause == IRQ_VS_EXT) { | ||
65 | cause = cause - 1; | ||
66 | } | ||
67 | - env->hstatus = set_field(env->hstatus, HSTATUS_GVA, 0); | ||
68 | + write_gva = false; | ||
69 | } else if (riscv_cpu_virt_enabled(env)) { | ||
70 | /* Trap into HS mode, from virt */ | ||
71 | riscv_cpu_swap_hypervisor_regs(env); | ||
72 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
73 | env->hstatus = set_field(env->hstatus, HSTATUS_SPV, | ||
74 | riscv_cpu_virt_enabled(env)); | ||
75 | |||
76 | + | ||
77 | htval = env->guest_phys_fault_addr; | ||
78 | |||
79 | riscv_cpu_set_virt_enabled(env, 0); | ||
80 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
81 | /* Trap into HS mode */ | ||
82 | env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false); | ||
83 | htval = env->guest_phys_fault_addr; | ||
84 | + write_gva = false; | ||
85 | } | ||
86 | + env->hstatus = set_field(env->hstatus, HSTATUS_GVA, write_gva); | ||
87 | } | ||
88 | |||
89 | s = env->mstatus; | ||
90 | -- | 36 | -- |
91 | 2.31.1 | 37 | 2.41.0 |
92 | 38 | ||
93 | 39 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Thomas Huth <thuth@redhat.com> | ||
1 | 2 | ||
3 | Values that have been read via cpu_physical_memory_read() from the | ||
4 | guest's memory have to be swapped in case the host endianess differs | ||
5 | from the guest. | ||
6 | |||
7 | Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall") | ||
8 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Reviewed-by: Bin Meng <bmeng@tinylab.org> | ||
11 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
12 | Message-Id: <20230721094720.902454-3-thuth@redhat.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | hw/char/riscv_htif.c | 9 +++++---- | ||
16 | 1 file changed, 5 insertions(+), 4 deletions(-) | ||
17 | |||
18 | diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/char/riscv_htif.c | ||
21 | +++ b/hw/char/riscv_htif.c | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | #include "qemu/timer.h" | ||
24 | #include "qemu/error-report.h" | ||
25 | #include "exec/address-spaces.h" | ||
26 | +#include "exec/tswap.h" | ||
27 | #include "sysemu/dma.h" | ||
28 | |||
29 | #define RISCV_DEBUG_HTIF 0 | ||
30 | @@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written) | ||
31 | } else { | ||
32 | uint64_t syscall[8]; | ||
33 | cpu_physical_memory_read(payload, syscall, sizeof(syscall)); | ||
34 | - if (syscall[0] == PK_SYS_WRITE && | ||
35 | - syscall[1] == HTIF_DEV_CONSOLE && | ||
36 | - syscall[3] == HTIF_CONSOLE_CMD_PUTC) { | ||
37 | + if (tswap64(syscall[0]) == PK_SYS_WRITE && | ||
38 | + tswap64(syscall[1]) == HTIF_DEV_CONSOLE && | ||
39 | + tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) { | ||
40 | uint8_t ch; | ||
41 | - cpu_physical_memory_read(syscall[2], &ch, 1); | ||
42 | + cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1); | ||
43 | qemu_chr_fe_write(&s->chr, &ch, 1); | ||
44 | resp = 0x100 | (uint8_t)payload; | ||
45 | } else { | ||
46 | -- | ||
47 | 2.41.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
1 | 2 | ||
3 | zmmul was promoted from experimental to ratified in commit 6d00ffad4e95. | ||
4 | Add a riscv,isa string for it. | ||
5 | |||
6 | Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties") | ||
7 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/cpu.c | 1 + | ||
14 | 1 file changed, 1 insertion(+) | ||
15 | |||
16 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/cpu.c | ||
19 | +++ b/target/riscv/cpu.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
21 | ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr), | ||
22 | ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei), | ||
23 | ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause), | ||
24 | + ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul), | ||
25 | ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs), | ||
26 | ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa), | ||
27 | ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin), | ||
28 | -- | ||
29 | 2.41.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
1 | 2 | ||
3 | The cpu->cfg.epmp extension is still experimental, but it already has a | ||
4 | 'smepmp' riscv,isa string. Add it. | ||
5 | |||
6 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
7 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/cpu.c | 1 + | ||
13 | 1 file changed, 1 insertion(+) | ||
14 | |||
15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/cpu.c | ||
18 | +++ b/target/riscv/cpu.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
20 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), | ||
21 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
22 | ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), | ||
23 | + ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp), | ||
24 | ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen), | ||
25 | ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia), | ||
26 | ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf), | ||
27 | -- | ||
28 | 2.41.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
1 | 2 | ||
3 | Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts | ||
4 | integer return value to bool type. However, it wrongly converted the use | ||
5 | of the API in riscv fault-only-first, where page_check_range < = 0, should | ||
6 | be converted to !page_check_range. | ||
7 | |||
8 | Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
10 | Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/vector_helper.c | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/vector_helper.c | ||
19 | +++ b/target/riscv/vector_helper.c | ||
20 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
21 | cpu_mmu_index(env, false)); | ||
22 | if (host) { | ||
23 | #ifdef CONFIG_USER_ONLY | ||
24 | - if (page_check_range(addr, offset, PAGE_READ)) { | ||
25 | + if (!page_check_range(addr, offset, PAGE_READ)) { | ||
26 | vl = i; | ||
27 | goto ProbeSuccess; | ||
28 | } | ||
29 | -- | ||
30 | 2.41.0 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Ard Biesheuvel <ardb@kernel.org> |
---|---|---|---|
2 | 2 | ||
3 | The AES MixColumns and InvMixColumns operations are relatively | ||
4 | expensive 4x4 matrix multiplications in GF(2^8), which is why C | ||
5 | implementations usually rely on precomputed lookup tables rather than | ||
6 | performing the calculations on demand. | ||
7 | |||
8 | Given that we already carry those tables in QEMU, we can just grab the | ||
9 | right value in the implementation of the RISC-V AES32 instructions. Note | ||
10 | that the tables in question are permuted according to the respective | ||
11 | Sbox, so we can omit the Sbox lookup as well in this case. | ||
12 | |||
13 | Cc: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Cc: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
15 | Cc: Zewen Ye <lustrew@foxmail.com> | ||
16 | Cc: Weiwei Li <liweiwei@iscas.ac.cn> | ||
17 | Cc: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
18 | Signed-off-by: Ard Biesheuvel <ardb@kernel.org> | ||
19 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
20 | Message-ID: <20230731084043.1791984-1-ardb@kernel.org> | ||
3 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
6 | Message-id: 20211220064916.107241-2-alistair.francis@opensource.wdc.com | ||
7 | --- | 22 | --- |
8 | target/riscv/translate.c | 2 ++ | 23 | include/crypto/aes.h | 7 +++++++ |
9 | 1 file changed, 2 insertions(+) | 24 | crypto/aes.c | 4 ++-- |
25 | target/riscv/crypto_helper.c | 34 ++++------------------------------ | ||
26 | 3 files changed, 13 insertions(+), 32 deletions(-) | ||
10 | 27 | ||
11 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 28 | diff --git a/include/crypto/aes.h b/include/crypto/aes.h |
12 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/riscv/translate.c | 30 | --- a/include/crypto/aes.h |
14 | +++ b/target/riscv/translate.c | 31 | +++ b/include/crypto/aes.h |
15 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | 32 | @@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out, |
16 | if (!has_ext(ctx, RVC)) { | 33 | extern const uint8_t AES_sbox[256]; |
17 | gen_exception_illegal(ctx); | 34 | extern const uint8_t AES_isbox[256]; |
35 | |||
36 | +/* | ||
37 | +AES_Te0[x] = S [x].[02, 01, 01, 03]; | ||
38 | +AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; | ||
39 | +*/ | ||
40 | + | ||
41 | +extern const uint32_t AES_Te0[256], AES_Td0[256]; | ||
42 | + | ||
43 | #endif | ||
44 | diff --git a/crypto/aes.c b/crypto/aes.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/crypto/aes.c | ||
47 | +++ b/crypto/aes.c | ||
48 | @@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e]; | ||
49 | AES_Td4[x] = Si[x].[01, 01, 01, 01]; | ||
50 | */ | ||
51 | |||
52 | -static const uint32_t AES_Te0[256] = { | ||
53 | +const uint32_t AES_Te0[256] = { | ||
54 | 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, | ||
55 | 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, | ||
56 | 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, | ||
57 | @@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = { | ||
58 | 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, | ||
59 | }; | ||
60 | |||
61 | -static const uint32_t AES_Td0[256] = { | ||
62 | +const uint32_t AES_Td0[256] = { | ||
63 | 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, | ||
64 | 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, | ||
65 | 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, | ||
66 | diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/target/riscv/crypto_helper.c | ||
69 | +++ b/target/riscv/crypto_helper.c | ||
70 | @@ -XXX,XX +XXX,XX @@ | ||
71 | #include "crypto/aes-round.h" | ||
72 | #include "crypto/sm4.h" | ||
73 | |||
74 | -#define AES_XTIME(a) \ | ||
75 | - ((a << 1) ^ ((a & 0x80) ? 0x1b : 0)) | ||
76 | - | ||
77 | -#define AES_GFMUL(a, b) (( \ | ||
78 | - (((b) & 0x1) ? (a) : 0) ^ \ | ||
79 | - (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \ | ||
80 | - (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \ | ||
81 | - (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF) | ||
82 | - | ||
83 | -static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd) | ||
84 | -{ | ||
85 | - uint32_t u; | ||
86 | - | ||
87 | - if (fwd) { | ||
88 | - u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) | | ||
89 | - (AES_GFMUL(x, 2) << 0); | ||
90 | - } else { | ||
91 | - u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) | | ||
92 | - (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0); | ||
93 | - } | ||
94 | - return u; | ||
95 | -} | ||
96 | - | ||
97 | #define sext32_xlen(x) (target_ulong)(int32_t)(x) | ||
98 | |||
99 | static inline target_ulong aes32_operation(target_ulong shamt, | ||
100 | @@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt, | ||
101 | bool enc, bool mix) | ||
102 | { | ||
103 | uint8_t si = rs2 >> shamt; | ||
104 | - uint8_t so; | ||
105 | uint32_t mixed; | ||
106 | target_ulong res; | ||
107 | |||
108 | if (enc) { | ||
109 | - so = AES_sbox[si]; | ||
110 | if (mix) { | ||
111 | - mixed = aes_mixcolumn_byte(so, true); | ||
112 | + mixed = be32_to_cpu(AES_Te0[si]); | ||
18 | } else { | 113 | } else { |
19 | + ctx->opcode = opcode; | 114 | - mixed = so; |
20 | ctx->pc_succ_insn = ctx->base.pc_next + 2; | 115 | + mixed = AES_sbox[si]; |
21 | if (!decode_insn16(ctx, opcode)) { | 116 | } |
22 | gen_exception_illegal(ctx); | 117 | } else { |
23 | @@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode) | 118 | - so = AES_isbox[si]; |
24 | opcode32 = deposit32(opcode32, 16, 16, | 119 | if (mix) { |
25 | translator_lduw(env, &ctx->base, | 120 | - mixed = aes_mixcolumn_byte(so, false); |
26 | ctx->base.pc_next + 2)); | 121 | + mixed = be32_to_cpu(AES_Td0[si]); |
27 | + ctx->opcode = opcode32; | 122 | } else { |
28 | ctx->pc_succ_insn = ctx->base.pc_next + 4; | 123 | - mixed = so; |
29 | if (!decode_insn32(ctx, opcode32)) { | 124 | + mixed = AES_isbox[si]; |
30 | gen_exception_illegal(ctx); | 125 | } |
126 | } | ||
127 | mixed = rol32(mixed, shamt); | ||
31 | -- | 128 | -- |
32 | 2.31.1 | 129 | 2.41.0 |
33 | 130 | ||
34 | 131 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | We can remove the original sifive_plic_irqs_pending() function and | 3 | Take some functions/macros out of `vector_helper` and put them in a new |
4 | instead just use the sifive_plic_claim() function (renamed to | 4 | module called `vector_internals`. This ensures they can be used by both |
5 | sifive_plic_claimed()) to determine if any interrupts are pending. | 5 | vector and vector-crypto helpers (latter implemented in proceeding |
6 | commits). | ||
6 | 7 | ||
7 | This requires move the side effects outside of sifive_plic_claimed(), | 8 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
8 | but as they are only invoked once that isn't a problem. | 9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
10 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
11 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-ID: <20230711165917.2629866-2-max.chou@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++ | ||
16 | target/riscv/vector_helper.c | 201 +------------------------------- | ||
17 | target/riscv/vector_internals.c | 81 +++++++++++++ | ||
18 | target/riscv/meson.build | 1 + | ||
19 | 4 files changed, 265 insertions(+), 200 deletions(-) | ||
20 | create mode 100644 target/riscv/vector_internals.h | ||
21 | create mode 100644 target/riscv/vector_internals.c | ||
9 | 22 | ||
10 | We have also removed all of the old #ifdef debugging logs, so let's | 23 | diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h |
11 | cleanup the last remaining debug function while we are here. | 24 | new file mode 100644 |
12 | 25 | index XXXXXXX..XXXXXXX | |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 26 | --- /dev/null |
14 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 27 | +++ b/target/riscv/vector_internals.h |
15 | Message-Id: <20220105213937.1113508-5-alistair.francis@opensource.wdc.com> | 28 | @@ -XXX,XX +XXX,XX @@ |
16 | --- | 29 | +/* |
17 | hw/intc/sifive_plic.c | 109 +++++++++--------------------------------- | 30 | + * RISC-V Vector Extension Internals |
18 | 1 file changed, 22 insertions(+), 87 deletions(-) | 31 | + * |
19 | 32 | + * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved. | |
20 | diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c | 33 | + * |
34 | + * This program is free software; you can redistribute it and/or modify it | ||
35 | + * under the terms and conditions of the GNU General Public License, | ||
36 | + * version 2 or later, as published by the Free Software Foundation. | ||
37 | + * | ||
38 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
39 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
40 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
41 | + * more details. | ||
42 | + * | ||
43 | + * You should have received a copy of the GNU General Public License along with | ||
44 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
45 | + */ | ||
46 | + | ||
47 | +#ifndef TARGET_RISCV_VECTOR_INTERNALS_H | ||
48 | +#define TARGET_RISCV_VECTOR_INTERNALS_H | ||
49 | + | ||
50 | +#include "qemu/osdep.h" | ||
51 | +#include "qemu/bitops.h" | ||
52 | +#include "cpu.h" | ||
53 | +#include "tcg/tcg-gvec-desc.h" | ||
54 | +#include "internals.h" | ||
55 | + | ||
56 | +static inline uint32_t vext_nf(uint32_t desc) | ||
57 | +{ | ||
58 | + return FIELD_EX32(simd_data(desc), VDATA, NF); | ||
59 | +} | ||
60 | + | ||
61 | +/* | ||
62 | + * Note that vector data is stored in host-endian 64-bit chunks, | ||
63 | + * so addressing units smaller than that needs a host-endian fixup. | ||
64 | + */ | ||
65 | +#if HOST_BIG_ENDIAN | ||
66 | +#define H1(x) ((x) ^ 7) | ||
67 | +#define H1_2(x) ((x) ^ 6) | ||
68 | +#define H1_4(x) ((x) ^ 4) | ||
69 | +#define H2(x) ((x) ^ 3) | ||
70 | +#define H4(x) ((x) ^ 1) | ||
71 | +#define H8(x) ((x)) | ||
72 | +#else | ||
73 | +#define H1(x) (x) | ||
74 | +#define H1_2(x) (x) | ||
75 | +#define H1_4(x) (x) | ||
76 | +#define H2(x) (x) | ||
77 | +#define H4(x) (x) | ||
78 | +#define H8(x) (x) | ||
79 | +#endif | ||
80 | + | ||
81 | +/* | ||
82 | + * Encode LMUL to lmul as following: | ||
83 | + * LMUL vlmul lmul | ||
84 | + * 1 000 0 | ||
85 | + * 2 001 1 | ||
86 | + * 4 010 2 | ||
87 | + * 8 011 3 | ||
88 | + * - 100 - | ||
89 | + * 1/8 101 -3 | ||
90 | + * 1/4 110 -2 | ||
91 | + * 1/2 111 -1 | ||
92 | + */ | ||
93 | +static inline int32_t vext_lmul(uint32_t desc) | ||
94 | +{ | ||
95 | + return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3); | ||
96 | +} | ||
97 | + | ||
98 | +static inline uint32_t vext_vm(uint32_t desc) | ||
99 | +{ | ||
100 | + return FIELD_EX32(simd_data(desc), VDATA, VM); | ||
101 | +} | ||
102 | + | ||
103 | +static inline uint32_t vext_vma(uint32_t desc) | ||
104 | +{ | ||
105 | + return FIELD_EX32(simd_data(desc), VDATA, VMA); | ||
106 | +} | ||
107 | + | ||
108 | +static inline uint32_t vext_vta(uint32_t desc) | ||
109 | +{ | ||
110 | + return FIELD_EX32(simd_data(desc), VDATA, VTA); | ||
111 | +} | ||
112 | + | ||
113 | +static inline uint32_t vext_vta_all_1s(uint32_t desc) | ||
114 | +{ | ||
115 | + return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S); | ||
116 | +} | ||
117 | + | ||
118 | +/* | ||
119 | + * Earlier designs (pre-0.9) had a varying number of bits | ||
120 | + * per mask value (MLEN). In the 0.9 design, MLEN=1. | ||
121 | + * (Section 4.5) | ||
122 | + */ | ||
123 | +static inline int vext_elem_mask(void *v0, int index) | ||
124 | +{ | ||
125 | + int idx = index / 64; | ||
126 | + int pos = index % 64; | ||
127 | + return (((uint64_t *)v0)[idx] >> pos) & 1; | ||
128 | +} | ||
129 | + | ||
130 | +/* | ||
131 | + * Get number of total elements, including prestart, body and tail elements. | ||
132 | + * Note that when LMUL < 1, the tail includes the elements past VLMAX that | ||
133 | + * are held in the same vector register. | ||
134 | + */ | ||
135 | +static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc, | ||
136 | + uint32_t esz) | ||
137 | +{ | ||
138 | + uint32_t vlenb = simd_maxsz(desc); | ||
139 | + uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW); | ||
140 | + int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 : | ||
141 | + ctzl(esz) - ctzl(sew) + vext_lmul(desc); | ||
142 | + return (vlenb << emul) / esz; | ||
143 | +} | ||
144 | + | ||
145 | +/* set agnostic elements to 1s */ | ||
146 | +void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, | ||
147 | + uint32_t tot); | ||
148 | + | ||
149 | +/* expand macro args before macro */ | ||
150 | +#define RVVCALL(macro, ...) macro(__VA_ARGS__) | ||
151 | + | ||
152 | +/* (TD, T1, T2, TX1, TX2) */ | ||
153 | +#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t | ||
154 | +#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t | ||
155 | +#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t | ||
156 | +#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t | ||
157 | + | ||
158 | +/* operation of two vector elements */ | ||
159 | +typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i); | ||
160 | + | ||
161 | +#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ | ||
162 | +static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \ | ||
163 | +{ \ | ||
164 | + TX1 s1 = *((T1 *)vs1 + HS1(i)); \ | ||
165 | + TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
166 | + *((TD *)vd + HD(i)) = OP(s2, s1); \ | ||
167 | +} | ||
168 | + | ||
169 | +void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
170 | + CPURISCVState *env, uint32_t desc, | ||
171 | + opivv2_fn *fn, uint32_t esz); | ||
172 | + | ||
173 | +/* generate the helpers for OPIVV */ | ||
174 | +#define GEN_VEXT_VV(NAME, ESZ) \ | ||
175 | +void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
176 | + void *vs2, CPURISCVState *env, \ | ||
177 | + uint32_t desc) \ | ||
178 | +{ \ | ||
179 | + do_vext_vv(vd, v0, vs1, vs2, env, desc, \ | ||
180 | + do_##NAME, ESZ); \ | ||
181 | +} | ||
182 | + | ||
183 | +typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i); | ||
184 | + | ||
185 | +/* | ||
186 | + * (T1)s1 gives the real operator type. | ||
187 | + * (TX1)(T1)s1 expands the operator type of widen or narrow operations. | ||
188 | + */ | ||
189 | +#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
190 | +static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \ | ||
191 | +{ \ | ||
192 | + TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
193 | + *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \ | ||
194 | +} | ||
195 | + | ||
196 | +void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
197 | + CPURISCVState *env, uint32_t desc, | ||
198 | + opivx2_fn fn, uint32_t esz); | ||
199 | + | ||
200 | +/* generate the helpers for OPIVX */ | ||
201 | +#define GEN_VEXT_VX(NAME, ESZ) \ | ||
202 | +void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
203 | + void *vs2, CPURISCVState *env, \ | ||
204 | + uint32_t desc) \ | ||
205 | +{ \ | ||
206 | + do_vext_vx(vd, v0, s1, vs2, env, desc, \ | ||
207 | + do_##NAME, ESZ); \ | ||
208 | +} | ||
209 | + | ||
210 | +#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */ | ||
211 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | 212 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/hw/intc/sifive_plic.c | 213 | --- a/target/riscv/vector_helper.c |
23 | +++ b/hw/intc/sifive_plic.c | 214 | +++ b/target/riscv/vector_helper.c |
24 | @@ -XXX,XX +XXX,XX @@ | 215 | @@ -XXX,XX +XXX,XX @@ |
25 | #include "migration/vmstate.h" | 216 | #include "fpu/softfloat.h" |
26 | #include "hw/irq.h" | 217 | #include "tcg/tcg-gvec-desc.h" |
27 | 218 | #include "internals.h" | |
28 | -#define RISCV_DEBUG_PLIC 0 | 219 | +#include "vector_internals.h" |
29 | - | 220 | #include <math.h> |
30 | static bool addr_between(uint32_t addr, uint32_t base, uint32_t num) | 221 | |
222 | target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1, | ||
223 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1, | ||
224 | return vl; | ||
225 | } | ||
226 | |||
227 | -/* | ||
228 | - * Note that vector data is stored in host-endian 64-bit chunks, | ||
229 | - * so addressing units smaller than that needs a host-endian fixup. | ||
230 | - */ | ||
231 | -#if HOST_BIG_ENDIAN | ||
232 | -#define H1(x) ((x) ^ 7) | ||
233 | -#define H1_2(x) ((x) ^ 6) | ||
234 | -#define H1_4(x) ((x) ^ 4) | ||
235 | -#define H2(x) ((x) ^ 3) | ||
236 | -#define H4(x) ((x) ^ 1) | ||
237 | -#define H8(x) ((x)) | ||
238 | -#else | ||
239 | -#define H1(x) (x) | ||
240 | -#define H1_2(x) (x) | ||
241 | -#define H1_4(x) (x) | ||
242 | -#define H2(x) (x) | ||
243 | -#define H4(x) (x) | ||
244 | -#define H8(x) (x) | ||
245 | -#endif | ||
246 | - | ||
247 | -static inline uint32_t vext_nf(uint32_t desc) | ||
248 | -{ | ||
249 | - return FIELD_EX32(simd_data(desc), VDATA, NF); | ||
250 | -} | ||
251 | - | ||
252 | -static inline uint32_t vext_vm(uint32_t desc) | ||
253 | -{ | ||
254 | - return FIELD_EX32(simd_data(desc), VDATA, VM); | ||
255 | -} | ||
256 | - | ||
257 | -/* | ||
258 | - * Encode LMUL to lmul as following: | ||
259 | - * LMUL vlmul lmul | ||
260 | - * 1 000 0 | ||
261 | - * 2 001 1 | ||
262 | - * 4 010 2 | ||
263 | - * 8 011 3 | ||
264 | - * - 100 - | ||
265 | - * 1/8 101 -3 | ||
266 | - * 1/4 110 -2 | ||
267 | - * 1/2 111 -1 | ||
268 | - */ | ||
269 | -static inline int32_t vext_lmul(uint32_t desc) | ||
270 | -{ | ||
271 | - return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3); | ||
272 | -} | ||
273 | - | ||
274 | -static inline uint32_t vext_vta(uint32_t desc) | ||
275 | -{ | ||
276 | - return FIELD_EX32(simd_data(desc), VDATA, VTA); | ||
277 | -} | ||
278 | - | ||
279 | -static inline uint32_t vext_vma(uint32_t desc) | ||
280 | -{ | ||
281 | - return FIELD_EX32(simd_data(desc), VDATA, VMA); | ||
282 | -} | ||
283 | - | ||
284 | -static inline uint32_t vext_vta_all_1s(uint32_t desc) | ||
285 | -{ | ||
286 | - return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S); | ||
287 | -} | ||
288 | - | ||
289 | /* | ||
290 | * Get the maximum number of elements can be operated. | ||
291 | * | ||
292 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) | ||
293 | return scale < 0 ? vlenb >> -scale : vlenb << scale; | ||
294 | } | ||
295 | |||
296 | -/* | ||
297 | - * Get number of total elements, including prestart, body and tail elements. | ||
298 | - * Note that when LMUL < 1, the tail includes the elements past VLMAX that | ||
299 | - * are held in the same vector register. | ||
300 | - */ | ||
301 | -static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc, | ||
302 | - uint32_t esz) | ||
303 | -{ | ||
304 | - uint32_t vlenb = simd_maxsz(desc); | ||
305 | - uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW); | ||
306 | - int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 : | ||
307 | - ctzl(esz) - ctzl(sew) + vext_lmul(desc); | ||
308 | - return (vlenb << emul) / esz; | ||
309 | -} | ||
310 | - | ||
311 | static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr) | ||
31 | { | 312 | { |
32 | return addr >= base && addr - base < num; | 313 | return (addr & ~env->cur_pmmask) | env->cur_pmbase; |
33 | @@ -XXX,XX +XXX,XX @@ static PLICMode char_to_mode(char c) | 314 | @@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr, |
34 | } | 315 | } |
35 | } | 316 | } |
36 | 317 | ||
37 | -static char mode_to_char(PLICMode m) | 318 | -/* set agnostic elements to 1s */ |
38 | -{ | 319 | -static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, |
39 | - switch (m) { | 320 | - uint32_t tot) |
40 | - case PLICMode_U: return 'U'; | 321 | -{ |
41 | - case PLICMode_S: return 'S'; | 322 | - if (is_agnostic == 0) { |
42 | - case PLICMode_H: return 'H'; | 323 | - /* policy undisturbed */ |
43 | - case PLICMode_M: return 'M'; | 324 | - return; |
44 | - default: return '?'; | ||
45 | - } | 325 | - } |
46 | -} | 326 | - if (tot - cnt == 0) { |
47 | - | 327 | - return; |
48 | -static void sifive_plic_print_state(SiFivePLICState *plic) | ||
49 | -{ | ||
50 | - int i; | ||
51 | - int addrid; | ||
52 | - | ||
53 | - /* pending */ | ||
54 | - qemu_log("pending : "); | ||
55 | - for (i = plic->bitfield_words - 1; i >= 0; i--) { | ||
56 | - qemu_log("%08x", plic->pending[i]); | ||
57 | - } | 328 | - } |
58 | - qemu_log("\n"); | 329 | - memset(base + cnt, -1, tot - cnt); |
59 | - | 330 | -} |
60 | - /* pending */ | 331 | - |
61 | - qemu_log("claimed : "); | 332 | static inline void vext_set_elem_mask(void *v0, int index, |
62 | - for (i = plic->bitfield_words - 1; i >= 0; i--) { | 333 | uint8_t value) |
63 | - qemu_log("%08x", plic->claimed[i]); | ||
64 | - } | ||
65 | - qemu_log("\n"); | ||
66 | - | ||
67 | - for (addrid = 0; addrid < plic->num_addrs; addrid++) { | ||
68 | - qemu_log("hart%d-%c enable: ", | ||
69 | - plic->addr_config[addrid].hartid, | ||
70 | - mode_to_char(plic->addr_config[addrid].mode)); | ||
71 | - for (i = plic->bitfield_words - 1; i >= 0; i--) { | ||
72 | - qemu_log("%08x", plic->enable[addrid * plic->bitfield_words + i]); | ||
73 | - } | ||
74 | - qemu_log("\n"); | ||
75 | - } | ||
76 | -} | ||
77 | - | ||
78 | static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value) | ||
79 | { | 334 | { |
80 | uint32_t old, new, cmp = qatomic_read(a); | 335 | @@ -XXX,XX +XXX,XX @@ static inline void vext_set_elem_mask(void *v0, int index, |
81 | @@ -XXX,XX +XXX,XX @@ static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool level) | 336 | ((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value); |
82 | atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level); | ||
83 | } | 337 | } |
84 | 338 | ||
85 | -static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid) | 339 | -/* |
86 | +static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid) | 340 | - * Earlier designs (pre-0.9) had a varying number of bits |
87 | { | 341 | - * per mask value (MLEN). In the 0.9 design, MLEN=1. |
88 | + uint32_t max_irq = 0; | 342 | - * (Section 4.5) |
89 | + uint32_t max_prio = plic->target_priority[addrid]; | 343 | - */ |
90 | int i, j; | 344 | -static inline int vext_elem_mask(void *v0, int index) |
91 | + | 345 | -{ |
92 | for (i = 0; i < plic->bitfield_words; i++) { | 346 | - int idx = index / 64; |
93 | uint32_t pending_enabled_not_claimed = | 347 | - int pos = index % 64; |
94 | - (plic->pending[i] & ~plic->claimed[i]) & | 348 | - return (((uint64_t *)v0)[idx] >> pos) & 1; |
95 | - plic->enable[addrid * plic->bitfield_words + i]; | 349 | -} |
96 | + (plic->pending[i] & ~plic->claimed[i]) & | 350 | - |
97 | + plic->enable[addrid * plic->bitfield_words + i]; | 351 | /* elements operations for load and store */ |
98 | + | 352 | typedef void vext_ldst_elem_fn(CPURISCVState *env, abi_ptr addr, |
99 | if (!pending_enabled_not_claimed) { | 353 | uint32_t idx, void *vd, uintptr_t retaddr); |
100 | continue; | 354 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b) |
101 | } | 355 | * Vector Integer Arithmetic Instructions |
102 | + | 356 | */ |
103 | for (j = 0; j < 32; j++) { | 357 | |
104 | int irq = (i << 5) + j; | 358 | -/* expand macro args before macro */ |
105 | uint32_t prio = plic->source_priority[irq]; | 359 | -#define RVVCALL(macro, ...) macro(__VA_ARGS__) |
106 | int enabled = pending_enabled_not_claimed & (1 << j); | 360 | - |
107 | - if (enabled && prio > plic->target_priority[addrid]) { | 361 | /* (TD, T1, T2, TX1, TX2) */ |
108 | - return 1; | 362 | #define OP_SSS_B int8_t, int8_t, int8_t, int8_t, int8_t |
109 | + | 363 | #define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t |
110 | + if (enabled && prio > max_prio) { | 364 | #define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t |
111 | + max_irq = irq; | 365 | #define OP_SSS_D int64_t, int64_t, int64_t, int64_t, int64_t |
112 | + max_prio = prio; | 366 | -#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t |
113 | } | 367 | -#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t |
114 | } | 368 | -#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t |
115 | } | 369 | -#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t |
116 | - return 0; | 370 | #define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t |
117 | + | 371 | #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t |
118 | + return max_irq; | 372 | #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t |
119 | } | 373 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b) |
120 | 374 | #define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t | |
121 | static void sifive_plic_update(SiFivePLICState *plic) | 375 | #define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t |
122 | @@ -XXX,XX +XXX,XX @@ static void sifive_plic_update(SiFivePLICState *plic) | 376 | |
123 | for (addrid = 0; addrid < plic->num_addrs; addrid++) { | 377 | -/* operation of two vector elements */ |
124 | uint32_t hartid = plic->addr_config[addrid].hartid; | 378 | -typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i); |
125 | PLICMode mode = plic->addr_config[addrid].mode; | 379 | - |
126 | - int level = sifive_plic_irqs_pending(plic, addrid); | 380 | -#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ |
127 | + bool level = !!sifive_plic_claimed(plic, addrid); | 381 | -static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \ |
128 | 382 | -{ \ | |
129 | switch (mode) { | 383 | - TX1 s1 = *((T1 *)vs1 + HS1(i)); \ |
130 | case PLICMode_M: | 384 | - TX2 s2 = *((T2 *)vs2 + HS2(i)); \ |
131 | @@ -XXX,XX +XXX,XX @@ static void sifive_plic_update(SiFivePLICState *plic) | 385 | - *((TD *)vd + HD(i)) = OP(s2, s1); \ |
132 | break; | 386 | -} |
133 | } | 387 | #define DO_SUB(N, M) (N - M) |
134 | } | 388 | #define DO_RSUB(N, M) (M - N) |
135 | - | 389 | |
136 | - if (RISCV_DEBUG_PLIC) { | 390 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vsub_vv_h, OP_SSS_H, H2, H2, H2, DO_SUB) |
137 | - sifive_plic_print_state(plic); | 391 | RVVCALL(OPIVV2, vsub_vv_w, OP_SSS_W, H4, H4, H4, DO_SUB) |
138 | - } | 392 | RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB) |
139 | -} | 393 | |
140 | - | 394 | -static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, |
141 | -static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid) | 395 | - CPURISCVState *env, uint32_t desc, |
142 | -{ | 396 | - opivv2_fn *fn, uint32_t esz) |
143 | - int i, j; | 397 | -{ |
144 | - uint32_t max_irq = 0; | 398 | - uint32_t vm = vext_vm(desc); |
145 | - uint32_t max_prio = plic->target_priority[addrid]; | 399 | - uint32_t vl = env->vl; |
146 | - | 400 | - uint32_t total_elems = vext_get_total_elems(env, desc, esz); |
147 | - for (i = 0; i < plic->bitfield_words; i++) { | 401 | - uint32_t vta = vext_vta(desc); |
148 | - uint32_t pending_enabled_not_claimed = | 402 | - uint32_t vma = vext_vma(desc); |
149 | - (plic->pending[i] & ~plic->claimed[i]) & | 403 | - uint32_t i; |
150 | - plic->enable[addrid * plic->bitfield_words + i]; | 404 | - |
151 | - if (!pending_enabled_not_claimed) { | 405 | - for (i = env->vstart; i < vl; i++) { |
406 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
407 | - /* set masked-off elements to 1s */ | ||
408 | - vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
152 | - continue; | 409 | - continue; |
153 | - } | 410 | - } |
154 | - for (j = 0; j < 32; j++) { | 411 | - fn(vd, vs1, vs2, i); |
155 | - int irq = (i << 5) + j; | 412 | - } |
156 | - uint32_t prio = plic->source_priority[irq]; | 413 | - env->vstart = 0; |
157 | - int enabled = pending_enabled_not_claimed & (1 << j); | 414 | - /* set tail elements to 1s */ |
158 | - if (enabled && prio > max_prio) { | 415 | - vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); |
159 | - max_irq = irq; | 416 | -} |
160 | - max_prio = prio; | 417 | - |
161 | - } | 418 | -/* generate the helpers for OPIVV */ |
419 | -#define GEN_VEXT_VV(NAME, ESZ) \ | ||
420 | -void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
421 | - void *vs2, CPURISCVState *env, \ | ||
422 | - uint32_t desc) \ | ||
423 | -{ \ | ||
424 | - do_vext_vv(vd, v0, vs1, vs2, env, desc, \ | ||
425 | - do_##NAME, ESZ); \ | ||
426 | -} | ||
427 | - | ||
428 | GEN_VEXT_VV(vadd_vv_b, 1) | ||
429 | GEN_VEXT_VV(vadd_vv_h, 2) | ||
430 | GEN_VEXT_VV(vadd_vv_w, 4) | ||
431 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VV(vsub_vv_h, 2) | ||
432 | GEN_VEXT_VV(vsub_vv_w, 4) | ||
433 | GEN_VEXT_VV(vsub_vv_d, 8) | ||
434 | |||
435 | -typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i); | ||
436 | - | ||
437 | -/* | ||
438 | - * (T1)s1 gives the real operator type. | ||
439 | - * (TX1)(T1)s1 expands the operator type of widen or narrow operations. | ||
440 | - */ | ||
441 | -#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
442 | -static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \ | ||
443 | -{ \ | ||
444 | - TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
445 | - *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \ | ||
446 | -} | ||
447 | |||
448 | RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD) | ||
449 | RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD) | ||
450 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB) | ||
451 | RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB) | ||
452 | RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB) | ||
453 | |||
454 | -static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
455 | - CPURISCVState *env, uint32_t desc, | ||
456 | - opivx2_fn fn, uint32_t esz) | ||
457 | -{ | ||
458 | - uint32_t vm = vext_vm(desc); | ||
459 | - uint32_t vl = env->vl; | ||
460 | - uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
461 | - uint32_t vta = vext_vta(desc); | ||
462 | - uint32_t vma = vext_vma(desc); | ||
463 | - uint32_t i; | ||
464 | - | ||
465 | - for (i = env->vstart; i < vl; i++) { | ||
466 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
467 | - /* set masked-off elements to 1s */ | ||
468 | - vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
469 | - continue; | ||
162 | - } | 470 | - } |
471 | - fn(vd, s1, vs2, i); | ||
163 | - } | 472 | - } |
164 | - | 473 | - env->vstart = 0; |
165 | - if (max_irq) { | 474 | - /* set tail elements to 1s */ |
166 | - sifive_plic_set_pending(plic, max_irq, false); | 475 | - vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); |
167 | - sifive_plic_set_claimed(plic, max_irq, true); | 476 | -} |
168 | - } | 477 | - |
169 | - return max_irq; | 478 | -/* generate the helpers for OPIVX */ |
170 | } | 479 | -#define GEN_VEXT_VX(NAME, ESZ) \ |
171 | 480 | -void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | |
172 | static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size) | 481 | - void *vs2, CPURISCVState *env, \ |
173 | @@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size) | 482 | - uint32_t desc) \ |
174 | if (contextid == 0) { | 483 | -{ \ |
175 | return plic->target_priority[addrid]; | 484 | - do_vext_vx(vd, v0, s1, vs2, env, desc, \ |
176 | } else if (contextid == 4) { | 485 | - do_##NAME, ESZ); \ |
177 | - uint32_t value = sifive_plic_claim(plic, addrid); | 486 | -} |
178 | + uint32_t max_irq = sifive_plic_claimed(plic, addrid); | 487 | - |
179 | + | 488 | GEN_VEXT_VX(vadd_vx_b, 1) |
180 | + if (max_irq) { | 489 | GEN_VEXT_VX(vadd_vx_h, 2) |
181 | + sifive_plic_set_pending(plic, max_irq, false); | 490 | GEN_VEXT_VX(vadd_vx_w, 4) |
182 | + sifive_plic_set_claimed(plic, max_irq, true); | 491 | diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c |
183 | + } | 492 | new file mode 100644 |
184 | 493 | index XXXXXXX..XXXXXXX | |
185 | sifive_plic_update(plic); | 494 | --- /dev/null |
186 | - return value; | 495 | +++ b/target/riscv/vector_internals.c |
187 | + return max_irq; | 496 | @@ -XXX,XX +XXX,XX @@ |
188 | } | 497 | +/* |
189 | } | 498 | + * RISC-V Vector Extension Internals |
190 | 499 | + * | |
500 | + * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved. | ||
501 | + * | ||
502 | + * This program is free software; you can redistribute it and/or modify it | ||
503 | + * under the terms and conditions of the GNU General Public License, | ||
504 | + * version 2 or later, as published by the Free Software Foundation. | ||
505 | + * | ||
506 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
507 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
508 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
509 | + * more details. | ||
510 | + * | ||
511 | + * You should have received a copy of the GNU General Public License along with | ||
512 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
513 | + */ | ||
514 | + | ||
515 | +#include "vector_internals.h" | ||
516 | + | ||
517 | +/* set agnostic elements to 1s */ | ||
518 | +void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, | ||
519 | + uint32_t tot) | ||
520 | +{ | ||
521 | + if (is_agnostic == 0) { | ||
522 | + /* policy undisturbed */ | ||
523 | + return; | ||
524 | + } | ||
525 | + if (tot - cnt == 0) { | ||
526 | + return ; | ||
527 | + } | ||
528 | + memset(base + cnt, -1, tot - cnt); | ||
529 | +} | ||
530 | + | ||
531 | +void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
532 | + CPURISCVState *env, uint32_t desc, | ||
533 | + opivv2_fn *fn, uint32_t esz) | ||
534 | +{ | ||
535 | + uint32_t vm = vext_vm(desc); | ||
536 | + uint32_t vl = env->vl; | ||
537 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
538 | + uint32_t vta = vext_vta(desc); | ||
539 | + uint32_t vma = vext_vma(desc); | ||
540 | + uint32_t i; | ||
541 | + | ||
542 | + for (i = env->vstart; i < vl; i++) { | ||
543 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
544 | + /* set masked-off elements to 1s */ | ||
545 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
546 | + continue; | ||
547 | + } | ||
548 | + fn(vd, vs1, vs2, i); | ||
549 | + } | ||
550 | + env->vstart = 0; | ||
551 | + /* set tail elements to 1s */ | ||
552 | + vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); | ||
553 | +} | ||
554 | + | ||
555 | +void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
556 | + CPURISCVState *env, uint32_t desc, | ||
557 | + opivx2_fn fn, uint32_t esz) | ||
558 | +{ | ||
559 | + uint32_t vm = vext_vm(desc); | ||
560 | + uint32_t vl = env->vl; | ||
561 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
562 | + uint32_t vta = vext_vta(desc); | ||
563 | + uint32_t vma = vext_vma(desc); | ||
564 | + uint32_t i; | ||
565 | + | ||
566 | + for (i = env->vstart; i < vl; i++) { | ||
567 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
568 | + /* set masked-off elements to 1s */ | ||
569 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
570 | + continue; | ||
571 | + } | ||
572 | + fn(vd, s1, vs2, i); | ||
573 | + } | ||
574 | + env->vstart = 0; | ||
575 | + /* set tail elements to 1s */ | ||
576 | + vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); | ||
577 | +} | ||
578 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build | ||
579 | index XXXXXXX..XXXXXXX 100644 | ||
580 | --- a/target/riscv/meson.build | ||
581 | +++ b/target/riscv/meson.build | ||
582 | @@ -XXX,XX +XXX,XX @@ riscv_ss.add(files( | ||
583 | 'gdbstub.c', | ||
584 | 'op_helper.c', | ||
585 | 'vector_helper.c', | ||
586 | + 'vector_internals.c', | ||
587 | 'bitmanip_helper.c', | ||
588 | 'translate.c', | ||
589 | 'm128_helper.c', | ||
191 | -- | 590 | -- |
192 | 2.31.1 | 591 | 2.41.0 |
193 | |||
194 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | Introduction of a gen_logic function for bitwise logic to implement | 3 | Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into |
4 | instructions in which no propagation of information occurs between bits and | 4 | function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be |
5 | use of this function on the bitwise instructions. | 5 | used in proceeding vector-crypto commits. |
6 | 6 | ||
7 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 7 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
8 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | ||
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
11 | Message-id: 20220106210108.138226-6-frederic.petrot@univ-grenoble-alpes.fr | 10 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
11 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
12 | Message-ID: <20230711165917.2629866-3-max.chou@sifive.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 14 | --- |
14 | target/riscv/translate.c | 27 +++++++++++++++++++++++++ | 15 | target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------ |
15 | target/riscv/insn_trans/trans_rvb.c.inc | 6 +++--- | 16 | 1 file changed, 32 insertions(+), 30 deletions(-) |
16 | target/riscv/insn_trans/trans_rvi.c.inc | 12 +++++------ | ||
17 | 3 files changed, 36 insertions(+), 9 deletions(-) | ||
18 | 17 | ||
19 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 18 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
20 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/translate.c | 20 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
22 | +++ b/target/riscv/translate.c | 21 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
23 | @@ -XXX,XX +XXX,XX @@ static int ex_rvc_shifti(DisasContext *ctx, int imm) | 22 | @@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx) |
24 | /* Include the auto-generated decoder for 32 bit insn */ | 23 | GEN_OPIWX_WIDEN_TRANS(vwsubu_wx) |
25 | #include "decode-insn32.c.inc" | 24 | GEN_OPIWX_WIDEN_TRANS(vwsub_wx) |
26 | 25 | ||
27 | +static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a, | 26 | +static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm, |
28 | + void (*func)(TCGv, TCGv, target_long)) | 27 | + gen_helper_gvec_4_ptr *fn, DisasContext *s) |
29 | +{ | 28 | +{ |
30 | + TCGv dest = dest_gpr(ctx, a->rd); | 29 | + uint32_t data = 0; |
31 | + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); | 30 | + TCGLabel *over = gen_new_label(); |
31 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
32 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
32 | + | 33 | + |
33 | + func(dest, src1, a->imm); | 34 | + data = FIELD_DP32(data, VDATA, VM, vm); |
34 | + | 35 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); |
35 | + gen_set_gpr(ctx, a->rd, dest); | 36 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); |
36 | + | 37 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); |
38 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
39 | + tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1), | ||
40 | + vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8, | ||
41 | + s->cfg_ptr->vlen / 8, data, fn); | ||
42 | + mark_vs_dirty(s); | ||
43 | + gen_set_label(over); | ||
37 | + return true; | 44 | + return true; |
38 | +} | 45 | +} |
39 | + | 46 | + |
40 | +static bool gen_logic(DisasContext *ctx, arg_r *a, | 47 | /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */ |
41 | + void (*func)(TCGv, TCGv, TCGv)) | 48 | /* OPIVV without GVEC IR */ |
42 | +{ | 49 | -#define GEN_OPIVV_TRANS(NAME, CHECK) \ |
43 | + TCGv dest = dest_gpr(ctx, a->rd); | 50 | -static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
44 | + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); | 51 | -{ \ |
45 | + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); | 52 | - if (CHECK(s, a)) { \ |
46 | + | 53 | - uint32_t data = 0; \ |
47 | + func(dest, src1, src2); | 54 | - static gen_helper_gvec_4_ptr * const fns[4] = { \ |
48 | + | 55 | - gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ |
49 | + gen_set_gpr(ctx, a->rd, dest); | 56 | - gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ |
50 | + | 57 | - }; \ |
51 | + return true; | 58 | - TCGLabel *over = gen_new_label(); \ |
52 | +} | 59 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ |
53 | + | 60 | - tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ |
54 | static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext, | 61 | - \ |
55 | void (*func)(TCGv, TCGv, target_long)) | 62 | - data = FIELD_DP32(data, VDATA, VM, a->vm); \ |
56 | { | 63 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ |
57 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | 64 | - data = FIELD_DP32(data, VDATA, VTA, s->vta); \ |
58 | index XXXXXXX..XXXXXXX 100644 | 65 | - data = \ |
59 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | 66 | - FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\ |
60 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | 67 | - data = FIELD_DP32(data, VDATA, VMA, s->vma); \ |
61 | @@ -XXX,XX +XXX,XX @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a) | 68 | - tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ |
62 | static bool trans_andn(DisasContext *ctx, arg_andn *a) | 69 | - vreg_ofs(s, a->rs1), \ |
63 | { | 70 | - vreg_ofs(s, a->rs2), cpu_env, \ |
64 | REQUIRE_ZBB(ctx); | 71 | - s->cfg_ptr->vlen / 8, \ |
65 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_andc_tl); | 72 | - s->cfg_ptr->vlen / 8, data, \ |
66 | + return gen_logic(ctx, a, tcg_gen_andc_tl); | 73 | - fns[s->sew]); \ |
74 | - mark_vs_dirty(s); \ | ||
75 | - gen_set_label(over); \ | ||
76 | - return true; \ | ||
77 | - } \ | ||
78 | - return false; \ | ||
79 | +#define GEN_OPIVV_TRANS(NAME, CHECK) \ | ||
80 | +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
81 | +{ \ | ||
82 | + if (CHECK(s, a)) { \ | ||
83 | + static gen_helper_gvec_4_ptr * const fns[4] = { \ | ||
84 | + gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ | ||
85 | + gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ | ||
86 | + }; \ | ||
87 | + return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\ | ||
88 | + } \ | ||
89 | + return false; \ | ||
67 | } | 90 | } |
68 | 91 | ||
69 | static bool trans_orn(DisasContext *ctx, arg_orn *a) | 92 | /* |
70 | { | ||
71 | REQUIRE_ZBB(ctx); | ||
72 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_orc_tl); | ||
73 | + return gen_logic(ctx, a, tcg_gen_orc_tl); | ||
74 | } | ||
75 | |||
76 | static bool trans_xnor(DisasContext *ctx, arg_xnor *a) | ||
77 | { | ||
78 | REQUIRE_ZBB(ctx); | ||
79 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl); | ||
80 | + return gen_logic(ctx, a, tcg_gen_eqv_tl); | ||
81 | } | ||
82 | |||
83 | static bool trans_min(DisasContext *ctx, arg_min *a) | ||
84 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
85 | index XXXXXXX..XXXXXXX 100644 | ||
86 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
87 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
88 | @@ -XXX,XX +XXX,XX @@ static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a) | ||
89 | |||
90 | static bool trans_xori(DisasContext *ctx, arg_xori *a) | ||
91 | { | ||
92 | - return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_xori_tl); | ||
93 | + return gen_logic_imm_fn(ctx, a, tcg_gen_xori_tl); | ||
94 | } | ||
95 | |||
96 | static bool trans_ori(DisasContext *ctx, arg_ori *a) | ||
97 | { | ||
98 | - return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_ori_tl); | ||
99 | + return gen_logic_imm_fn(ctx, a, tcg_gen_ori_tl); | ||
100 | } | ||
101 | |||
102 | static bool trans_andi(DisasContext *ctx, arg_andi *a) | ||
103 | { | ||
104 | - return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_andi_tl); | ||
105 | + return gen_logic_imm_fn(ctx, a, tcg_gen_andi_tl); | ||
106 | } | ||
107 | |||
108 | static bool trans_slli(DisasContext *ctx, arg_slli *a) | ||
109 | @@ -XXX,XX +XXX,XX @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a) | ||
110 | |||
111 | static bool trans_xor(DisasContext *ctx, arg_xor *a) | ||
112 | { | ||
113 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_xor_tl); | ||
114 | + return gen_logic(ctx, a, tcg_gen_xor_tl); | ||
115 | } | ||
116 | |||
117 | static bool trans_srl(DisasContext *ctx, arg_srl *a) | ||
118 | @@ -XXX,XX +XXX,XX @@ static bool trans_sra(DisasContext *ctx, arg_sra *a) | ||
119 | |||
120 | static bool trans_or(DisasContext *ctx, arg_or *a) | ||
121 | { | ||
122 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_or_tl); | ||
123 | + return gen_logic(ctx, a, tcg_gen_or_tl); | ||
124 | } | ||
125 | |||
126 | static bool trans_and(DisasContext *ctx, arg_and *a) | ||
127 | { | ||
128 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_and_tl); | ||
129 | + return gen_logic(ctx, a, tcg_gen_and_tl); | ||
130 | } | ||
131 | |||
132 | static bool trans_addiw(DisasContext *ctx, arg_addiw *a) | ||
133 | -- | 93 | -- |
134 | 2.31.1 | 94 | 2.41.0 |
135 | |||
136 | diff view generated by jsdifflib |
1 | From: Frank Chang <frank.chang@sifive.com> | 1 | From: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | Vector widening floating-point instructions should use | 3 | Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0. |
4 | require_scale_rvf() instead of require_rvf() to check whether RVF/RVD is | ||
5 | enabled. | ||
6 | 4 | ||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | 5 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
6 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-Id: <20220105022247.21131-2-frank.chang@sifive.com> | 9 | Message-ID: <20230711165917.2629866-4-max.chou@sifive.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 11 | --- |
12 | target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++++---- | 12 | target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------ |
13 | 1 file changed, 8 insertions(+), 4 deletions(-) | 13 | 1 file changed, 1 insertion(+), 30 deletions(-) |
14 | 14 | ||
15 | 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 |
16 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | 17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | 18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
19 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check) | 19 | @@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data, |
20 | static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) | 20 | TCGv_i32 desc; |
21 | |||
22 | TCGLabel *over = gen_new_label(); | ||
23 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
24 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
25 | |||
26 | dest = tcg_temp_new_ptr(); | ||
27 | @@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2, | ||
28 | TCGv_i32 desc; | ||
29 | |||
30 | TCGLabel *over = gen_new_label(); | ||
31 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
32 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
33 | |||
34 | dest = tcg_temp_new_ptr(); | ||
35 | @@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
36 | TCGv_i32 desc; | ||
37 | |||
38 | TCGLabel *over = gen_new_label(); | ||
39 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
40 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
41 | |||
42 | dest = tcg_temp_new_ptr(); | ||
43 | @@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
44 | TCGv_i32 desc; | ||
45 | |||
46 | TCGLabel *over = gen_new_label(); | ||
47 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
48 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
49 | |||
50 | dest = tcg_temp_new_ptr(); | ||
51 | @@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn, | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
56 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
57 | |||
58 | if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) { | ||
59 | @@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm, | ||
60 | uint32_t data = 0; | ||
61 | |||
62 | TCGLabel *over = gen_new_label(); | ||
63 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
64 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
65 | |||
66 | dest = tcg_temp_new_ptr(); | ||
67 | @@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
68 | uint32_t data = 0; | ||
69 | |||
70 | TCGLabel *over = gen_new_label(); | ||
71 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
72 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
73 | |||
74 | dest = tcg_temp_new_ptr(); | ||
75 | @@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a, | ||
76 | if (checkfn(s, a)) { | ||
77 | uint32_t data = 0; | ||
78 | TCGLabel *over = gen_new_label(); | ||
79 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
80 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
81 | |||
82 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
83 | @@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a, | ||
84 | if (opiwv_widen_check(s, a)) { | ||
85 | uint32_t data = 0; | ||
86 | TCGLabel *over = gen_new_label(); | ||
87 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
88 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
89 | |||
90 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
91 | @@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm, | ||
21 | { | 92 | { |
22 | return require_rvv(s) && | 93 | uint32_t data = 0; |
23 | - require_rvf(s) && | 94 | TCGLabel *over = gen_new_label(); |
24 | + require_scale_rvf(s) && | 95 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); |
25 | + (s->sew != MO_8) && | 96 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
26 | vext_check_isa_ill(s) && | 97 | |
27 | vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm); | 98 | data = FIELD_DP32(data, VDATA, VM, vm); |
28 | } | 99 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
29 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check) | 100 | gen_helper_##NAME##_w, \ |
30 | static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a) | 101 | }; \ |
31 | { | 102 | TCGLabel *over = gen_new_label(); \ |
32 | return require_rvv(s) && | 103 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ |
33 | - require_rvf(s) && | 104 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ |
34 | + require_scale_rvf(s) && | 105 | \ |
35 | + (s->sew != MO_8) && | 106 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ |
36 | vext_check_isa_ill(s) && | 107 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a) |
37 | vext_check_ds(s, a->rd, a->rs2, a->vm); | 108 | gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d, |
38 | } | 109 | }; |
39 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf) | 110 | TCGLabel *over = gen_new_label(); |
40 | static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a) | 111 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); |
41 | { | 112 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
42 | return require_rvv(s) && | 113 | |
43 | - require_rvf(s) && | 114 | tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), |
44 | + require_scale_rvf(s) && | 115 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a) |
45 | + (s->sew != MO_8) && | 116 | vext_check_ss(s, a->rd, 0, 1)) { |
46 | vext_check_isa_ill(s) && | 117 | TCGv s1; |
47 | vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm); | 118 | TCGLabel *over = gen_new_label(); |
48 | } | 119 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); |
49 | @@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv) | 120 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
50 | static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a) | 121 | |
51 | { | 122 | s1 = get_gpr(s, a->rs1, EXT_SIGN); |
52 | return require_rvv(s) && | 123 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a) |
53 | - require_rvf(s) && | 124 | gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d, |
54 | + require_scale_rvf(s) && | 125 | }; |
55 | + (s->sew != MO_8) && | 126 | TCGLabel *over = gen_new_label(); |
56 | vext_check_isa_ill(s) && | 127 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); |
57 | vext_check_dd(s, a->rd, a->rs2, a->vm); | 128 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
58 | } | 129 | |
130 | s1 = tcg_constant_i64(simm); | ||
131 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
132 | }; \ | ||
133 | TCGLabel *over = gen_new_label(); \ | ||
134 | gen_set_rm(s, RISCV_FRM_DYN); \ | ||
135 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
136 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
137 | \ | ||
138 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
139 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
140 | TCGv_i64 t1; | ||
141 | |||
142 | TCGLabel *over = gen_new_label(); | ||
143 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
144 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
145 | |||
146 | dest = tcg_temp_new_ptr(); | ||
147 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
148 | }; \ | ||
149 | TCGLabel *over = gen_new_label(); \ | ||
150 | gen_set_rm(s, RISCV_FRM_DYN); \ | ||
151 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
152 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\ | ||
153 | \ | ||
154 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
155 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
156 | }; \ | ||
157 | TCGLabel *over = gen_new_label(); \ | ||
158 | gen_set_rm(s, RISCV_FRM_DYN); \ | ||
159 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
160 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
161 | \ | ||
162 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
163 | @@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a, | ||
164 | uint32_t data = 0; | ||
165 | TCGLabel *over = gen_new_label(); | ||
166 | gen_set_rm_chkfrm(s, rm); | ||
167 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
168 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
169 | |||
170 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
171 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
172 | gen_helper_vmv_v_x_d, | ||
173 | }; | ||
174 | TCGLabel *over = gen_new_label(); | ||
175 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
176 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
177 | |||
178 | t1 = tcg_temp_new_i64(); | ||
179 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
180 | }; \ | ||
181 | TCGLabel *over = gen_new_label(); \ | ||
182 | gen_set_rm_chkfrm(s, FRM); \ | ||
183 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
184 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
185 | \ | ||
186 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
187 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
188 | }; \ | ||
189 | TCGLabel *over = gen_new_label(); \ | ||
190 | gen_set_rm(s, RISCV_FRM_DYN); \ | ||
191 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
192 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
193 | \ | ||
194 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
195 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
196 | }; \ | ||
197 | TCGLabel *over = gen_new_label(); \ | ||
198 | gen_set_rm_chkfrm(s, FRM); \ | ||
199 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
200 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
201 | \ | ||
202 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
203 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
204 | }; \ | ||
205 | TCGLabel *over = gen_new_label(); \ | ||
206 | gen_set_rm_chkfrm(s, FRM); \ | ||
207 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
208 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
209 | \ | ||
210 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
211 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \ | ||
212 | uint32_t data = 0; \ | ||
213 | gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \ | ||
214 | TCGLabel *over = gen_new_label(); \ | ||
215 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
216 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
217 | \ | ||
218 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
219 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
220 | require_vm(a->vm, a->rd)) { | ||
221 | uint32_t data = 0; | ||
222 | TCGLabel *over = gen_new_label(); | ||
223 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
224 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
225 | |||
226 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
227 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) | ||
228 | TCGv s1; | ||
229 | TCGLabel *over = gen_new_label(); | ||
230 | |||
231 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
232 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
233 | |||
234 | t1 = tcg_temp_new_i64(); | ||
235 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
236 | TCGv_i64 t1; | ||
237 | TCGLabel *over = gen_new_label(); | ||
238 | |||
239 | - /* if vl == 0 or vstart >= vl, skip vector register write back */ | ||
240 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
241 | + /* if vstart >= vl, skip vector register write back */ | ||
242 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
243 | |||
244 | /* NaN-box f[rs1] */ | ||
245 | @@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq) | ||
246 | uint32_t data = 0; | ||
247 | gen_helper_gvec_3_ptr *fn; | ||
248 | TCGLabel *over = gen_new_label(); | ||
249 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
250 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
251 | |||
252 | static gen_helper_gvec_3_ptr * const fns[6][4] = { | ||
59 | -- | 253 | -- |
60 | 2.31.1 | 254 | 2.41.0 |
61 | |||
62 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Lawrence Hunter <lawrence.hunter@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | Mult are generated inline (using a cool trick pointed out by Richard), but | 3 | This commit adds support for the Zvbc vector-crypto extension, which |
4 | for div and rem, given the complexity of the implementation of these | 4 | consists of the following instructions: |
5 | instructions, we call helpers to produce their behavior. From an | 5 | |
6 | implementation standpoint, the helpers return the low part of the results, | 6 | * vclmulh.[vx,vv] |
7 | while the high part is temporarily stored in a dedicated field of cpu_env | 7 | * vclmul.[vx,vv] |
8 | that is used to update the architectural register in the generation wrapper. | 8 | |
9 | 9 | Translation functions are defined in | |
10 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 10 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in |
11 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 11 | `target/riscv/vcrypto_helper.c`. |
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 12 | |
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
14 | Message-id: 20220106210108.138226-15-frederic.petrot@univ-grenoble-alpes.fr | 14 | Co-authored-by: Max Chou <max.chou@sifive.com> |
15 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
16 | Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
17 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
18 | [max.chou@sifive.com: Exposed x-zvbc property] | ||
19 | Message-ID: <20230711165917.2629866-5-max.chou@sifive.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 21 | --- |
17 | target/riscv/cpu.h | 3 + | 22 | target/riscv/cpu_cfg.h | 1 + |
18 | target/riscv/helper.h | 6 + | 23 | target/riscv/helper.h | 6 +++ |
19 | target/riscv/insn32.decode | 7 + | 24 | target/riscv/insn32.decode | 6 +++ |
20 | target/riscv/m128_helper.c | 109 ++++++++++++++ | 25 | target/riscv/cpu.c | 9 ++++ |
21 | target/riscv/insn_trans/trans_rvm.c.inc | 182 ++++++++++++++++++++++-- | 26 | target/riscv/translate.c | 1 + |
22 | target/riscv/meson.build | 1 + | 27 | target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++ |
23 | 6 files changed, 295 insertions(+), 13 deletions(-) | 28 | target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++ |
24 | create mode 100644 target/riscv/m128_helper.c | 29 | target/riscv/meson.build | 3 +- |
25 | 30 | 8 files changed, 146 insertions(+), 1 deletion(-) | |
26 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 31 | create mode 100644 target/riscv/vcrypto_helper.c |
27 | index XXXXXXX..XXXXXXX 100644 | 32 | create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc |
28 | --- a/target/riscv/cpu.h | 33 | |
29 | +++ b/target/riscv/cpu.h | 34 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h |
30 | @@ -XXX,XX +XXX,XX @@ struct CPURISCVState { | 35 | index XXXXXXX..XXXXXXX 100644 |
31 | uint32_t misa_ext; /* current extensions */ | 36 | --- a/target/riscv/cpu_cfg.h |
32 | uint32_t misa_ext_mask; /* max ext for this cpu */ | 37 | +++ b/target/riscv/cpu_cfg.h |
33 | 38 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | |
34 | + /* 128-bit helpers upper part return value */ | 39 | bool ext_zve32f; |
35 | + target_ulong retxh; | 40 | bool ext_zve64f; |
36 | + | 41 | bool ext_zve64d; |
37 | uint32_t features; | 42 | + bool ext_zvbc; |
38 | 43 | bool ext_zmmul; | |
39 | #ifdef CONFIG_USER_ONLY | 44 | bool ext_zvfbfmin; |
45 | bool ext_zvfbfwma; | ||
40 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 46 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h |
41 | index XXXXXXX..XXXXXXX 100644 | 47 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/target/riscv/helper.h | 48 | --- a/target/riscv/helper.h |
43 | +++ b/target/riscv/helper.h | 49 | +++ b/target/riscv/helper.h |
44 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsext_vf2_d, void, ptr, ptr, ptr, env, i32) | 50 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32) |
45 | DEF_HELPER_5(vsext_vf4_w, void, ptr, ptr, ptr, env, i32) | 51 | |
46 | DEF_HELPER_5(vsext_vf4_d, void, ptr, ptr, ptr, env, i32) | 52 | DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32) |
47 | DEF_HELPER_5(vsext_vf8_d, void, ptr, ptr, ptr, env, i32) | 53 | DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32) |
48 | + | 54 | + |
49 | +/* 128-bit integer multiplication and division */ | 55 | +/* Vector crypto functions */ |
50 | +DEF_HELPER_5(divu_i128, tl, env, tl, tl, tl, tl) | 56 | +DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32) |
51 | +DEF_HELPER_5(divs_i128, tl, env, tl, tl, tl, tl) | 57 | +DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32) |
52 | +DEF_HELPER_5(remu_i128, tl, env, tl, tl, tl, tl) | 58 | +DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32) |
53 | +DEF_HELPER_5(rems_i128, tl, env, tl, tl, tl, tl) | 59 | +DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32) |
54 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 60 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode |
55 | index XXXXXXX..XXXXXXX 100644 | 61 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/target/riscv/insn32.decode | 62 | --- a/target/riscv/insn32.decode |
57 | +++ b/target/riscv/insn32.decode | 63 | +++ b/target/riscv/insn32.decode |
58 | @@ -XXX,XX +XXX,XX @@ divuw 0000001 ..... ..... 101 ..... 0111011 @r | 64 | @@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm |
59 | remw 0000001 ..... ..... 110 ..... 0111011 @r | 65 | # *** Zvfbfwma Standard Extension *** |
60 | remuw 0000001 ..... ..... 111 ..... 0111011 @r | 66 | vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm |
61 | 67 | vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm | |
62 | +# *** RV128M Standard Extension (in addition to RV64M) *** | 68 | + |
63 | +muld 0000001 ..... ..... 000 ..... 1111011 @r | 69 | +# *** Zvbc vector crypto extension *** |
64 | +divd 0000001 ..... ..... 100 ..... 1111011 @r | 70 | +vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm |
65 | +divud 0000001 ..... ..... 101 ..... 1111011 @r | 71 | +vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm |
66 | +remd 0000001 ..... ..... 110 ..... 1111011 @r | 72 | +vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm |
67 | +remud 0000001 ..... ..... 111 ..... 1111011 @r | 73 | +vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm |
68 | + | 74 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
69 | # *** RV32A Standard Extension *** | 75 | index XXXXXXX..XXXXXXX 100644 |
70 | lr_w 00010 . . 00000 ..... 010 ..... 0101111 @atom_ld | 76 | --- a/target/riscv/cpu.c |
71 | sc_w 00011 . . ..... ..... 010 ..... 0101111 @atom_st | 77 | +++ b/target/riscv/cpu.c |
72 | diff --git a/target/riscv/m128_helper.c b/target/riscv/m128_helper.c | 78 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
79 | ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed), | ||
80 | ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh), | ||
81 | ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt), | ||
82 | + ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc), | ||
83 | ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f), | ||
84 | ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f), | ||
85 | ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d), | ||
86 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | + if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) { | ||
91 | + error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions"); | ||
92 | + return; | ||
93 | + } | ||
94 | + | ||
95 | if (cpu->cfg.ext_zk) { | ||
96 | cpu->cfg.ext_zkn = true; | ||
97 | cpu->cfg.ext_zkr = true; | ||
98 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
99 | DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false), | ||
100 | DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false), | ||
101 | |||
102 | + /* Vector cryptography extensions */ | ||
103 | + DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), | ||
104 | + | ||
105 | DEFINE_PROP_END_OF_LIST(), | ||
106 | }; | ||
107 | |||
108 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
109 | index XXXXXXX..XXXXXXX 100644 | ||
110 | --- a/target/riscv/translate.c | ||
111 | +++ b/target/riscv/translate.c | ||
112 | @@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) | ||
113 | #include "insn_trans/trans_rvzfa.c.inc" | ||
114 | #include "insn_trans/trans_rvzfh.c.inc" | ||
115 | #include "insn_trans/trans_rvk.c.inc" | ||
116 | +#include "insn_trans/trans_rvvk.c.inc" | ||
117 | #include "insn_trans/trans_privileged.c.inc" | ||
118 | #include "insn_trans/trans_svinval.c.inc" | ||
119 | #include "insn_trans/trans_rvbf16.c.inc" | ||
120 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
73 | new file mode 100644 | 121 | new file mode 100644 |
74 | index XXXXXXX..XXXXXXX | 122 | index XXXXXXX..XXXXXXX |
75 | --- /dev/null | 123 | --- /dev/null |
76 | +++ b/target/riscv/m128_helper.c | 124 | +++ b/target/riscv/vcrypto_helper.c |
77 | @@ -XXX,XX +XXX,XX @@ | 125 | @@ -XXX,XX +XXX,XX @@ |
78 | +/* | 126 | +/* |
79 | + * RISC-V Emulation Helpers for QEMU. | 127 | + * RISC-V Vector Crypto Extension Helpers for QEMU. |
80 | + * | 128 | + * |
81 | + * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu | 129 | + * Copyright (C) 2023 SiFive, Inc. |
82 | + * Copyright (c) 2017-2018 SiFive, Inc. | 130 | + * Written by Codethink Ltd and SiFive. |
83 | + * | 131 | + * |
84 | + * This program is free software; you can redistribute it and/or modify it | 132 | + * This program is free software; you can redistribute it and/or modify it |
85 | + * under the terms and conditions of the GNU General Public License, | 133 | + * under the terms and conditions of the GNU General Public License, |
86 | + * version 2 or later, as published by the Free Software Foundation. | 134 | + * version 2 or later, as published by the Free Software Foundation. |
87 | + * | 135 | + * |
... | ... | ||
93 | + * You should have received a copy of the GNU General Public License along with | 141 | + * You should have received a copy of the GNU General Public License along with |
94 | + * this program. If not, see <http://www.gnu.org/licenses/>. | 142 | + * this program. If not, see <http://www.gnu.org/licenses/>. |
95 | + */ | 143 | + */ |
96 | + | 144 | + |
97 | +#include "qemu/osdep.h" | 145 | +#include "qemu/osdep.h" |
146 | +#include "qemu/host-utils.h" | ||
147 | +#include "qemu/bitops.h" | ||
98 | +#include "cpu.h" | 148 | +#include "cpu.h" |
99 | +#include "qemu/main-loop.h" | 149 | +#include "exec/memop.h" |
100 | +#include "exec/exec-all.h" | 150 | +#include "exec/exec-all.h" |
101 | +#include "exec/helper-proto.h" | 151 | +#include "exec/helper-proto.h" |
102 | + | 152 | +#include "internals.h" |
103 | +target_ulong HELPER(divu_i128)(CPURISCVState *env, | 153 | +#include "vector_internals.h" |
104 | + target_ulong ul, target_ulong uh, | 154 | + |
105 | + target_ulong vl, target_ulong vh) | 155 | +static uint64_t clmul64(uint64_t y, uint64_t x) |
106 | +{ | 156 | +{ |
107 | + target_ulong ql, qh; | 157 | + uint64_t result = 0; |
108 | + Int128 q; | 158 | + for (int j = 63; j >= 0; j--) { |
109 | + | 159 | + if ((y >> j) & 1) { |
110 | + if (vl == 0 && vh == 0) { /* Handle special behavior on div by zero */ | 160 | + result ^= (x << j); |
111 | + ql = ~0x0; | 161 | + } |
112 | + qh = ~0x0; | 162 | + } |
113 | + } else { | 163 | + return result; |
114 | + q = int128_divu(int128_make128(ul, uh), int128_make128(vl, vh)); | 164 | +} |
115 | + ql = int128_getlo(q); | 165 | + |
116 | + qh = int128_gethi(q); | 166 | +static uint64_t clmulh64(uint64_t y, uint64_t x) |
117 | + } | 167 | +{ |
118 | + | 168 | + uint64_t result = 0; |
119 | + env->retxh = qh; | 169 | + for (int j = 63; j >= 1; j--) { |
120 | + return ql; | 170 | + if ((y >> j) & 1) { |
121 | +} | 171 | + result ^= (x >> (64 - j)); |
122 | + | 172 | + } |
123 | +target_ulong HELPER(remu_i128)(CPURISCVState *env, | 173 | + } |
124 | + target_ulong ul, target_ulong uh, | 174 | + return result; |
125 | + target_ulong vl, target_ulong vh) | 175 | +} |
126 | +{ | 176 | + |
127 | + target_ulong rl, rh; | 177 | +RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64) |
128 | + Int128 r; | 178 | +GEN_VEXT_VV(vclmul_vv, 8) |
129 | + | 179 | +RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64) |
130 | + if (vl == 0 && vh == 0) { | 180 | +GEN_VEXT_VX(vclmul_vx, 8) |
131 | + rl = ul; | 181 | +RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64) |
132 | + rh = uh; | 182 | +GEN_VEXT_VV(vclmulh_vv, 8) |
133 | + } else { | 183 | +RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64) |
134 | + r = int128_remu(int128_make128(ul, uh), int128_make128(vl, vh)); | 184 | +GEN_VEXT_VX(vclmulh_vx, 8) |
135 | + rl = int128_getlo(r); | 185 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc |
136 | + rh = int128_gethi(r); | 186 | new file mode 100644 |
137 | + } | 187 | index XXXXXXX..XXXXXXX |
138 | + | 188 | --- /dev/null |
139 | + env->retxh = rh; | 189 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc |
140 | + return rl; | ||
141 | +} | ||
142 | + | ||
143 | +target_ulong HELPER(divs_i128)(CPURISCVState *env, | ||
144 | + target_ulong ul, target_ulong uh, | ||
145 | + target_ulong vl, target_ulong vh) | ||
146 | +{ | ||
147 | + target_ulong qh, ql; | ||
148 | + Int128 q; | ||
149 | + | ||
150 | + if (vl == 0 && vh == 0) { /* Div by zero check */ | ||
151 | + ql = ~0x0; | ||
152 | + qh = ~0x0; | ||
153 | + } else if (uh == (1ULL << (TARGET_LONG_BITS - 1)) && ul == 0 && | ||
154 | + vh == ~0x0 && vl == ~0x0) { | ||
155 | + /* Signed div overflow check (-2**127 / -1) */ | ||
156 | + ql = ul; | ||
157 | + qh = uh; | ||
158 | + } else { | ||
159 | + q = int128_divs(int128_make128(ul, uh), int128_make128(vl, vh)); | ||
160 | + ql = int128_getlo(q); | ||
161 | + qh = int128_gethi(q); | ||
162 | + } | ||
163 | + | ||
164 | + env->retxh = qh; | ||
165 | + return ql; | ||
166 | +} | ||
167 | + | ||
168 | +target_ulong HELPER(rems_i128)(CPURISCVState *env, | ||
169 | + target_ulong ul, target_ulong uh, | ||
170 | + target_ulong vl, target_ulong vh) | ||
171 | +{ | ||
172 | + target_ulong rh, rl; | ||
173 | + Int128 r; | ||
174 | + | ||
175 | + if (vl == 0 && vh == 0) { | ||
176 | + rl = ul; | ||
177 | + rh = uh; | ||
178 | + } else { | ||
179 | + r = int128_rems(int128_make128(ul, uh), int128_make128(vl, vh)); | ||
180 | + rl = int128_getlo(r); | ||
181 | + rh = int128_gethi(r); | ||
182 | + } | ||
183 | + | ||
184 | + env->retxh = rh; | ||
185 | + return rl; | ||
186 | +} | ||
187 | diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc | ||
188 | index XXXXXXX..XXXXXXX 100644 | ||
189 | --- a/target/riscv/insn_trans/trans_rvm.c.inc | ||
190 | +++ b/target/riscv/insn_trans/trans_rvm.c.inc | ||
191 | @@ -XXX,XX +XXX,XX @@ | 190 | @@ -XXX,XX +XXX,XX @@ |
192 | * this program. If not, see <http://www.gnu.org/licenses/>. | 191 | +/* |
193 | */ | 192 | + * RISC-V translation routines for the vector crypto extension. |
194 | 193 | + * | |
195 | +static void gen_mulhu_i128(TCGv r2, TCGv r3, TCGv al, TCGv ah, TCGv bl, TCGv bh) | 194 | + * Copyright (C) 2023 SiFive, Inc. |
196 | +{ | 195 | + * Written by Codethink Ltd and SiFive. |
197 | + TCGv tmpl = tcg_temp_new(); | 196 | + * |
198 | + TCGv tmph = tcg_temp_new(); | 197 | + * This program is free software; you can redistribute it and/or modify it |
199 | + TCGv r0 = tcg_temp_new(); | 198 | + * under the terms and conditions of the GNU General Public License, |
200 | + TCGv r1 = tcg_temp_new(); | 199 | + * version 2 or later, as published by the Free Software Foundation. |
201 | + TCGv zero = tcg_constant_tl(0); | 200 | + * |
202 | + | 201 | + * This program is distributed in the hope it will be useful, but WITHOUT |
203 | + tcg_gen_mulu2_tl(r0, r1, al, bl); | 202 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
204 | + | 203 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
205 | + tcg_gen_mulu2_tl(tmpl, tmph, al, bh); | 204 | + * more details. |
206 | + tcg_gen_add2_tl(r1, r2, r1, zero, tmpl, tmph); | 205 | + * |
207 | + tcg_gen_mulu2_tl(tmpl, tmph, ah, bl); | 206 | + * You should have received a copy of the GNU General Public License along with |
208 | + tcg_gen_add2_tl(r1, tmph, r1, r2, tmpl, tmph); | 207 | + * this program. If not, see <http://www.gnu.org/licenses/>. |
209 | + /* Overflow detection into r3 */ | 208 | + */ |
210 | + tcg_gen_setcond_tl(TCG_COND_LTU, r3, tmph, r2); | 209 | + |
211 | + | 210 | +/* |
212 | + tcg_gen_mov_tl(r2, tmph); | 211 | + * Zvbc |
213 | + | 212 | + */ |
214 | + tcg_gen_mulu2_tl(tmpl, tmph, ah, bh); | 213 | + |
215 | + tcg_gen_add2_tl(r2, r3, r2, r3, tmpl, tmph); | 214 | +#define GEN_VV_MASKED_TRANS(NAME, CHECK) \ |
216 | + | 215 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
217 | + tcg_temp_free(tmpl); | 216 | + { \ |
218 | + tcg_temp_free(tmph); | 217 | + if (CHECK(s, a)) { \ |
219 | +} | 218 | + return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \ |
220 | + | 219 | + gen_helper_##NAME, s); \ |
221 | +static void gen_mul_i128(TCGv rl, TCGv rh, | 220 | + } \ |
222 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | 221 | + return false; \ |
223 | +{ | 222 | + } |
224 | + TCGv tmpl = tcg_temp_new(); | 223 | + |
225 | + TCGv tmph = tcg_temp_new(); | 224 | +static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a) |
226 | + TCGv tmpx = tcg_temp_new(); | 225 | +{ |
227 | + TCGv zero = tcg_constant_tl(0); | 226 | + return opivv_check(s, a) && |
228 | + | 227 | + s->cfg_ptr->ext_zvbc == true && |
229 | + tcg_gen_mulu2_tl(rl, rh, rs1l, rs2l); | 228 | + s->sew == MO_64; |
230 | + tcg_gen_mulu2_tl(tmpl, tmph, rs1l, rs2h); | 229 | +} |
231 | + tcg_gen_add2_tl(rh, tmpx, rh, zero, tmpl, tmph); | 230 | + |
232 | + tcg_gen_mulu2_tl(tmpl, tmph, rs1h, rs2l); | 231 | +GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check) |
233 | + tcg_gen_add2_tl(rh, tmph, rh, tmpx, tmpl, tmph); | 232 | +GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check) |
234 | + | 233 | + |
235 | + tcg_temp_free(tmpl); | 234 | +#define GEN_VX_MASKED_TRANS(NAME, CHECK) \ |
236 | + tcg_temp_free(tmph); | 235 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
237 | + tcg_temp_free(tmpx); | 236 | + { \ |
238 | +} | 237 | + if (CHECK(s, a)) { \ |
239 | 238 | + return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \ | |
240 | static bool trans_mul(DisasContext *ctx, arg_mul *a) | 239 | + gen_helper_##NAME, s); \ |
241 | { | 240 | + } \ |
242 | REQUIRE_EXT(ctx, RVM); | 241 | + return false; \ |
243 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL); | 242 | + } |
244 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, gen_mul_i128); | 243 | + |
245 | +} | 244 | +static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a) |
246 | + | 245 | +{ |
247 | +static void gen_mulh_i128(TCGv rl, TCGv rh, | 246 | + return opivx_check(s, a) && |
248 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | 247 | + s->cfg_ptr->ext_zvbc == true && |
249 | +{ | 248 | + s->sew == MO_64; |
250 | + TCGv t0l = tcg_temp_new(); | 249 | +} |
251 | + TCGv t0h = tcg_temp_new(); | 250 | + |
252 | + TCGv t1l = tcg_temp_new(); | 251 | +GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check) |
253 | + TCGv t1h = tcg_temp_new(); | 252 | +GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check) |
254 | + | ||
255 | + gen_mulhu_i128(rl, rh, rs1l, rs1h, rs2l, rs2h); | ||
256 | + tcg_gen_sari_tl(t0h, rs1h, 63); | ||
257 | + tcg_gen_and_tl(t0l, t0h, rs2l); | ||
258 | + tcg_gen_and_tl(t0h, t0h, rs2h); | ||
259 | + tcg_gen_sari_tl(t1h, rs2h, 63); | ||
260 | + tcg_gen_and_tl(t1l, t1h, rs1l); | ||
261 | + tcg_gen_and_tl(t1h, t1h, rs1h); | ||
262 | + tcg_gen_sub2_tl(t0l, t0h, rl, rh, t0l, t0h); | ||
263 | + tcg_gen_sub2_tl(rl, rh, t0l, t0h, t1l, t1h); | ||
264 | + | ||
265 | + tcg_temp_free(t0l); | ||
266 | + tcg_temp_free(t0h); | ||
267 | + tcg_temp_free(t1l); | ||
268 | + tcg_temp_free(t1h); | ||
269 | } | ||
270 | |||
271 | static void gen_mulh(TCGv ret, TCGv s1, TCGv s2) | ||
272 | @@ -XXX,XX +XXX,XX @@ static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2) | ||
273 | static bool trans_mulh(DisasContext *ctx, arg_mulh *a) | ||
274 | { | ||
275 | REQUIRE_EXT(ctx, RVM); | ||
276 | - return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w, NULL); | ||
277 | + return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w, | ||
278 | + gen_mulh_i128); | ||
279 | +} | ||
280 | + | ||
281 | +static void gen_mulhsu_i128(TCGv rl, TCGv rh, | ||
282 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | ||
283 | +{ | ||
284 | + | ||
285 | + TCGv t0l = tcg_temp_new(); | ||
286 | + TCGv t0h = tcg_temp_new(); | ||
287 | + | ||
288 | + gen_mulhu_i128(rl, rh, rs1l, rs1h, rs2l, rs2h); | ||
289 | + tcg_gen_sari_tl(t0h, rs1h, 63); | ||
290 | + tcg_gen_and_tl(t0l, t0h, rs2l); | ||
291 | + tcg_gen_and_tl(t0h, t0h, rs2h); | ||
292 | + tcg_gen_sub2_tl(rl, rh, rl, rh, t0l, t0h); | ||
293 | + | ||
294 | + tcg_temp_free(t0l); | ||
295 | + tcg_temp_free(t0h); | ||
296 | } | ||
297 | |||
298 | static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2) | ||
299 | @@ -XXX,XX +XXX,XX @@ static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2) | ||
300 | static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a) | ||
301 | { | ||
302 | REQUIRE_EXT(ctx, RVM); | ||
303 | - return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w, NULL); | ||
304 | + return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w, | ||
305 | + gen_mulhsu_i128); | ||
306 | } | ||
307 | |||
308 | static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2) | ||
309 | @@ -XXX,XX +XXX,XX @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a) | ||
310 | { | ||
311 | REQUIRE_EXT(ctx, RVM); | ||
312 | /* gen_mulh_w works for either sign as input. */ | ||
313 | - return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w, NULL); | ||
314 | + return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w, | ||
315 | + gen_mulhu_i128); | ||
316 | +} | ||
317 | + | ||
318 | +static void gen_div_i128(TCGv rdl, TCGv rdh, | ||
319 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | ||
320 | +{ | ||
321 | + gen_helper_divs_i128(rdl, cpu_env, rs1l, rs1h, rs2l, rs2h); | ||
322 | + tcg_gen_ld_tl(rdh, cpu_env, offsetof(CPURISCVState, retxh)); | ||
323 | } | ||
324 | |||
325 | static void gen_div(TCGv ret, TCGv source1, TCGv source2) | ||
326 | @@ -XXX,XX +XXX,XX @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2) | ||
327 | static bool trans_div(DisasContext *ctx, arg_div *a) | ||
328 | { | ||
329 | REQUIRE_EXT(ctx, RVM); | ||
330 | - return gen_arith(ctx, a, EXT_SIGN, gen_div, NULL); | ||
331 | + return gen_arith(ctx, a, EXT_SIGN, gen_div, gen_div_i128); | ||
332 | +} | ||
333 | + | ||
334 | +static void gen_divu_i128(TCGv rdl, TCGv rdh, | ||
335 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | ||
336 | +{ | ||
337 | + gen_helper_divu_i128(rdl, cpu_env, rs1l, rs1h, rs2l, rs2h); | ||
338 | + tcg_gen_ld_tl(rdh, cpu_env, offsetof(CPURISCVState, retxh)); | ||
339 | } | ||
340 | |||
341 | static void gen_divu(TCGv ret, TCGv source1, TCGv source2) | ||
342 | @@ -XXX,XX +XXX,XX @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2) | ||
343 | static bool trans_divu(DisasContext *ctx, arg_divu *a) | ||
344 | { | ||
345 | REQUIRE_EXT(ctx, RVM); | ||
346 | - return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); | ||
347 | + return gen_arith(ctx, a, EXT_ZERO, gen_divu, gen_divu_i128); | ||
348 | +} | ||
349 | + | ||
350 | +static void gen_rem_i128(TCGv rdl, TCGv rdh, | ||
351 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | ||
352 | +{ | ||
353 | + gen_helper_rems_i128(rdl, cpu_env, rs1l, rs1h, rs2l, rs2h); | ||
354 | + tcg_gen_ld_tl(rdh, cpu_env, offsetof(CPURISCVState, retxh)); | ||
355 | } | ||
356 | |||
357 | static void gen_rem(TCGv ret, TCGv source1, TCGv source2) | ||
358 | @@ -XXX,XX +XXX,XX @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2) | ||
359 | static bool trans_rem(DisasContext *ctx, arg_rem *a) | ||
360 | { | ||
361 | REQUIRE_EXT(ctx, RVM); | ||
362 | - return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); | ||
363 | + return gen_arith(ctx, a, EXT_SIGN, gen_rem, gen_rem_i128); | ||
364 | +} | ||
365 | + | ||
366 | +static void gen_remu_i128(TCGv rdl, TCGv rdh, | ||
367 | + TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h) | ||
368 | +{ | ||
369 | + gen_helper_remu_i128(rdl, cpu_env, rs1l, rs1h, rs2l, rs2h); | ||
370 | + tcg_gen_ld_tl(rdh, cpu_env, offsetof(CPURISCVState, retxh)); | ||
371 | } | ||
372 | |||
373 | static void gen_remu(TCGv ret, TCGv source1, TCGv source2) | ||
374 | @@ -XXX,XX +XXX,XX @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2) | ||
375 | static bool trans_remu(DisasContext *ctx, arg_remu *a) | ||
376 | { | ||
377 | REQUIRE_EXT(ctx, RVM); | ||
378 | - return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); | ||
379 | + return gen_arith(ctx, a, EXT_ZERO, gen_remu, gen_remu_i128); | ||
380 | } | ||
381 | |||
382 | static bool trans_mulw(DisasContext *ctx, arg_mulw *a) | ||
383 | { | ||
384 | - REQUIRE_64BIT(ctx); | ||
385 | + REQUIRE_64_OR_128BIT(ctx); | ||
386 | REQUIRE_EXT(ctx, RVM); | ||
387 | ctx->ol = MXL_RV32; | ||
388 | return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL); | ||
389 | @@ -XXX,XX +XXX,XX @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a) | ||
390 | |||
391 | static bool trans_divw(DisasContext *ctx, arg_divw *a) | ||
392 | { | ||
393 | - REQUIRE_64BIT(ctx); | ||
394 | + REQUIRE_64_OR_128BIT(ctx); | ||
395 | REQUIRE_EXT(ctx, RVM); | ||
396 | ctx->ol = MXL_RV32; | ||
397 | return gen_arith(ctx, a, EXT_SIGN, gen_div, NULL); | ||
398 | @@ -XXX,XX +XXX,XX @@ static bool trans_divw(DisasContext *ctx, arg_divw *a) | ||
399 | |||
400 | static bool trans_divuw(DisasContext *ctx, arg_divuw *a) | ||
401 | { | ||
402 | - REQUIRE_64BIT(ctx); | ||
403 | + REQUIRE_64_OR_128BIT(ctx); | ||
404 | REQUIRE_EXT(ctx, RVM); | ||
405 | ctx->ol = MXL_RV32; | ||
406 | return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); | ||
407 | @@ -XXX,XX +XXX,XX @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a) | ||
408 | |||
409 | static bool trans_remw(DisasContext *ctx, arg_remw *a) | ||
410 | { | ||
411 | - REQUIRE_64BIT(ctx); | ||
412 | + REQUIRE_64_OR_128BIT(ctx); | ||
413 | REQUIRE_EXT(ctx, RVM); | ||
414 | ctx->ol = MXL_RV32; | ||
415 | return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); | ||
416 | @@ -XXX,XX +XXX,XX @@ static bool trans_remw(DisasContext *ctx, arg_remw *a) | ||
417 | |||
418 | static bool trans_remuw(DisasContext *ctx, arg_remuw *a) | ||
419 | { | ||
420 | - REQUIRE_64BIT(ctx); | ||
421 | + REQUIRE_64_OR_128BIT(ctx); | ||
422 | REQUIRE_EXT(ctx, RVM); | ||
423 | ctx->ol = MXL_RV32; | ||
424 | return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); | ||
425 | } | ||
426 | + | ||
427 | +static bool trans_muld(DisasContext *ctx, arg_muld *a) | ||
428 | +{ | ||
429 | + REQUIRE_128BIT(ctx); | ||
430 | + REQUIRE_EXT(ctx, RVM); | ||
431 | + ctx->ol = MXL_RV64; | ||
432 | + return gen_arith(ctx, a, EXT_SIGN, tcg_gen_mul_tl, NULL); | ||
433 | +} | ||
434 | + | ||
435 | +static bool trans_divd(DisasContext *ctx, arg_divd *a) | ||
436 | +{ | ||
437 | + REQUIRE_128BIT(ctx); | ||
438 | + REQUIRE_EXT(ctx, RVM); | ||
439 | + ctx->ol = MXL_RV64; | ||
440 | + return gen_arith(ctx, a, EXT_SIGN, gen_div, NULL); | ||
441 | +} | ||
442 | + | ||
443 | +static bool trans_divud(DisasContext *ctx, arg_divud *a) | ||
444 | +{ | ||
445 | + REQUIRE_128BIT(ctx); | ||
446 | + REQUIRE_EXT(ctx, RVM); | ||
447 | + ctx->ol = MXL_RV64; | ||
448 | + return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); | ||
449 | +} | ||
450 | + | ||
451 | +static bool trans_remd(DisasContext *ctx, arg_remd *a) | ||
452 | +{ | ||
453 | + REQUIRE_128BIT(ctx); | ||
454 | + REQUIRE_EXT(ctx, RVM); | ||
455 | + ctx->ol = MXL_RV64; | ||
456 | + return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); | ||
457 | +} | ||
458 | + | ||
459 | +static bool trans_remud(DisasContext *ctx, arg_remud *a) | ||
460 | +{ | ||
461 | + REQUIRE_128BIT(ctx); | ||
462 | + REQUIRE_EXT(ctx, RVM); | ||
463 | + ctx->ol = MXL_RV64; | ||
464 | + return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); | ||
465 | +} | ||
466 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build | 253 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build |
467 | index XXXXXXX..XXXXXXX 100644 | 254 | index XXXXXXX..XXXXXXX 100644 |
468 | --- a/target/riscv/meson.build | 255 | --- a/target/riscv/meson.build |
469 | +++ b/target/riscv/meson.build | 256 | +++ b/target/riscv/meson.build |
470 | @@ -XXX,XX +XXX,XX @@ riscv_ss.add(files( | 257 | @@ -XXX,XX +XXX,XX @@ riscv_ss.add(files( |
471 | 'vector_helper.c', | ||
472 | 'bitmanip_helper.c', | ||
473 | 'translate.c', | 258 | 'translate.c', |
474 | + 'm128_helper.c' | 259 | 'm128_helper.c', |
260 | 'crypto_helper.c', | ||
261 | - 'zce_helper.c' | ||
262 | + 'zce_helper.c', | ||
263 | + 'vcrypto_helper.c' | ||
475 | )) | 264 | )) |
476 | 265 | riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) | |
477 | riscv_softmmu_ss = ss.source_set() | 266 | |
478 | -- | 267 | -- |
479 | 2.31.1 | 268 | 2.41.0 |
480 | |||
481 | diff view generated by jsdifflib |
1 | From: Frank Chang <frank.chang@sifive.com> | 1 | From: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | vfncvt.f.xu.w, vfncvt.f.x.w convert double-width integer to single-width | 3 | Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions |
4 | floating-point. Therefore, should use require_rvf() to check whether | 4 | and into the corresponding macros. This enables the functions to be |
5 | RVF/RVD is enabled. | 5 | reused in proceeding commits without check duplication. |
6 | 6 | ||
7 | vfncvt.f.f.w, vfncvt.rod.f.f.w convert double-width floating-point to | 7 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
8 | single-width integer. Therefore, should use require_scale_rvf() to check | 8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
9 | whether RVF/RVD is enabled. | 9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
10 | 10 | Signed-off-by: Max Chou <max.chou@sifive.com> | |
11 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | 11 | Message-ID: <20230711165917.2629866-6-max.chou@sifive.com> |
12 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-Id: <20220105022247.21131-4-frank.chang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 13 | --- |
16 | target/riscv/insn_trans/trans_rvv.c.inc | 32 ++++++++++++++++++------- | 14 | target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++-------------- |
17 | 1 file changed, 24 insertions(+), 8 deletions(-) | 15 | 1 file changed, 12 insertions(+), 16 deletions(-) |
18 | 16 | ||
19 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | 17 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
20 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | 19 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
22 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | 20 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
23 | @@ -XXX,XX +XXX,XX @@ GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_x_v) | 21 | @@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn, |
24 | static bool opfv_narrow_check(DisasContext *s, arg_rmr *a) | 22 | gen_helper_gvec_4_ptr *fn) |
25 | { | 23 | { |
26 | return require_rvv(s) && | 24 | TCGLabel *over = gen_new_label(); |
27 | - require_rvf(s) && | 25 | - if (!opivv_check(s, a)) { |
28 | - (s->sew != MO_64) && | 26 | - return false; |
29 | vext_check_isa_ill(s) && | 27 | - } |
30 | /* OPFV narrowing instructions ignore vs1 check */ | 28 | |
31 | vext_check_sd(s, a->rd, a->rs2, a->vm); | 29 | tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
30 | |||
31 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
32 | gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ | ||
33 | gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ | ||
34 | }; \ | ||
35 | + if (!opivv_check(s, a)) { \ | ||
36 | + return false; \ | ||
37 | + } \ | ||
38 | return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \ | ||
32 | } | 39 | } |
33 | 40 | ||
34 | -#define GEN_OPFV_NARROW_TRANS(NAME, HELPER, FRM) \ | 41 | @@ -XXX,XX +XXX,XX @@ static inline bool |
35 | +static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a) | 42 | do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn, |
36 | +{ | 43 | gen_helper_opivx *fn) |
37 | + return opfv_narrow_check(s, a) && | 44 | { |
38 | + require_rvf(s) && | 45 | - if (!opivx_check(s, a)) { |
39 | + (s->sew != MO_64); | 46 | - return false; |
40 | +} | 47 | - } |
41 | + | 48 | - |
42 | +static bool opffv_narrow_check(DisasContext *s, arg_rmr *a) | 49 | if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) { |
43 | +{ | 50 | TCGv_i64 src1 = tcg_temp_new_i64(); |
44 | + return opfv_narrow_check(s, a) && | 51 | |
45 | + require_scale_rvf(s) && | 52 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
46 | + (s->sew != MO_8); | 53 | gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ |
47 | +} | 54 | gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ |
48 | + | 55 | }; \ |
49 | +#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \ | 56 | + if (!opivx_check(s, a)) { \ |
50 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | 57 | + return false; \ |
51 | { \ | 58 | + } \ |
52 | - if (opfv_narrow_check(s, a)) { \ | 59 | return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \ |
53 | + if (CHECK(s, a)) { \ | ||
54 | if (FRM != RISCV_FRM_DYN) { \ | ||
55 | gen_set_rm(s, RISCV_FRM_DYN); \ | ||
56 | } \ | ||
57 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
58 | return false; \ | ||
59 | } | 60 | } |
60 | 61 | ||
61 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, vfncvt_f_xu_w, RISCV_FRM_DYN) | 62 | @@ -XXX,XX +XXX,XX @@ static inline bool |
62 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, vfncvt_f_x_w, RISCV_FRM_DYN) | 63 | do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn, |
63 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, vfncvt_f_f_w, RISCV_FRM_DYN) | 64 | gen_helper_opivx *fn, imm_mode_t imm_mode) |
64 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, opfxv_narrow_check, vfncvt_f_xu_w, | ||
65 | + RISCV_FRM_DYN) | ||
66 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, opfxv_narrow_check, vfncvt_f_x_w, | ||
67 | + RISCV_FRM_DYN) | ||
68 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w, | ||
69 | + RISCV_FRM_DYN) | ||
70 | /* Reuse the helper function from vfncvt.f.f.w */ | ||
71 | -GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, vfncvt_f_f_w, RISCV_FRM_ROD) | ||
72 | +GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_narrow_check, vfncvt_f_f_w, | ||
73 | + RISCV_FRM_ROD) | ||
74 | |||
75 | static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
76 | { | 65 | { |
66 | - if (!opivx_check(s, a)) { | ||
67 | - return false; | ||
68 | - } | ||
69 | - | ||
70 | if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) { | ||
71 | gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), | ||
72 | extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s)); | ||
73 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
74 | gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \ | ||
75 | gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \ | ||
76 | }; \ | ||
77 | + if (!opivx_check(s, a)) { \ | ||
78 | + return false; \ | ||
79 | + } \ | ||
80 | return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \ | ||
81 | fns[s->sew], IMM_MODE); \ | ||
82 | } | ||
83 | @@ -XXX,XX +XXX,XX @@ static inline bool | ||
84 | do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn, | ||
85 | gen_helper_opivx *fn) | ||
86 | { | ||
87 | - if (!opivx_check(s, a)) { | ||
88 | - return false; | ||
89 | - } | ||
90 | - | ||
91 | if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) { | ||
92 | TCGv_i32 src1 = tcg_temp_new_i32(); | ||
93 | |||
94 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
95 | gen_helper_##NAME##_b, gen_helper_##NAME##_h, \ | ||
96 | gen_helper_##NAME##_w, gen_helper_##NAME##_d, \ | ||
97 | }; \ | ||
98 | - \ | ||
99 | + if (!opivx_check(s, a)) { \ | ||
100 | + return false; \ | ||
101 | + } \ | ||
102 | return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \ | ||
103 | } | ||
104 | |||
77 | -- | 105 | -- |
78 | 2.31.1 | 106 | 2.41.0 |
79 | |||
80 | diff view generated by jsdifflib |
1 | From: Frank Chang <frank.chang@sifive.com> | 1 | From: Dickon Hood <dickon.hood@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | vfwcvt.xu.f.v, vfwcvt.x.f.v, vfwcvt.rtz.xu.f.v and vfwcvt.rtz.x.f.v | 3 | Zvbb (implemented in later commit) has a widening instruction, which |
4 | convert single-width floating-point to double-width integer. | 4 | requires an extra check on the enabled extensions. Refactor |
5 | Therefore, should use require_rvf() to check whether RVF/RVD is enabled. | 5 | GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing |
6 | it. | ||
6 | 7 | ||
7 | vfwcvt.f.xu.v, vfwcvt.f.x.v convert single-width integer to double-width | 8 | Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk> |
8 | floating-point, and vfwcvt.f.f.v convert double-width floating-point to | 9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
9 | single-width floating-point. Therefore, should use require_scale_rvf() to | 10 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
10 | check whether RVF/RVD is enabled. | 11 | Signed-off-by: Max Chou <max.chou@sifive.com> |
11 | 12 | Message-ID: <20230711165917.2629866-7-max.chou@sifive.com> | |
12 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Message-Id: <20220105022247.21131-3-frank.chang@sifive.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 14 | --- |
17 | target/riscv/insn_trans/trans_rvv.c.inc | 34 ++++++++++++++++++------- | 15 | target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++-------------- |
18 | 1 file changed, 25 insertions(+), 9 deletions(-) | 16 | 1 file changed, 23 insertions(+), 29 deletions(-) |
19 | 17 | ||
20 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | 18 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
21 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | 20 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
23 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | 21 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
24 | @@ -XXX,XX +XXX,XX @@ GEN_OPFV_CVT_TRANS(vfcvt_rtz_x_f_v, vfcvt_x_f_v, RISCV_FRM_RTZ) | 22 | @@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a) |
25 | static bool opfv_widen_check(DisasContext *s, arg_rmr *a) | ||
26 | { | ||
27 | return require_rvv(s) && | ||
28 | - require_scale_rvf(s) && | ||
29 | - (s->sew != MO_8) && | ||
30 | vext_check_isa_ill(s) && | ||
31 | vext_check_ds(s, a->rd, a->rs2, a->vm); | 23 | vext_check_ds(s, a->rd, a->rs2, a->vm); |
32 | } | 24 | } |
33 | 25 | ||
34 | -#define GEN_OPFV_WIDEN_TRANS(NAME, HELPER, FRM) \ | 26 | -static bool do_opivx_widen(DisasContext *s, arg_rmrr *a, |
35 | +static bool opxfv_widen_check(DisasContext *s, arg_rmr *a) | 27 | - gen_helper_opivx *fn) |
36 | +{ | 28 | -{ |
37 | + return opfv_widen_check(s, a) && | 29 | - if (opivx_widen_check(s, a)) { |
38 | + require_rvf(s); | 30 | - return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); |
39 | +} | 31 | - } |
40 | + | 32 | - return false; |
41 | +static bool opffv_widen_check(DisasContext *s, arg_rmr *a) | 33 | -} |
42 | +{ | 34 | - |
43 | + return opfv_widen_check(s, a) && | 35 | -#define GEN_OPIVX_WIDEN_TRANS(NAME) \ |
44 | + require_scale_rvf(s) && | 36 | -static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
45 | + (s->sew != MO_8); | 37 | -{ \ |
46 | +} | 38 | - static gen_helper_opivx * const fns[3] = { \ |
47 | + | 39 | - gen_helper_##NAME##_b, \ |
48 | +#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \ | 40 | - gen_helper_##NAME##_h, \ |
49 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | 41 | - gen_helper_##NAME##_w \ |
50 | { \ | 42 | - }; \ |
51 | - if (opfv_widen_check(s, a)) { \ | 43 | - return do_opivx_widen(s, a, fns[s->sew]); \ |
52 | + if (CHECK(s, a)) { \ | 44 | +#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \ |
53 | if (FRM != RISCV_FRM_DYN) { \ | 45 | +static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
54 | gen_set_rm(s, RISCV_FRM_DYN); \ | 46 | +{ \ |
55 | } \ | 47 | + if (CHECK(s, a)) { \ |
56 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | 48 | + static gen_helper_opivx * const fns[3] = { \ |
57 | return false; \ | 49 | + gen_helper_##NAME##_b, \ |
50 | + gen_helper_##NAME##_h, \ | ||
51 | + gen_helper_##NAME##_w \ | ||
52 | + }; \ | ||
53 | + return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \ | ||
54 | + } \ | ||
55 | + return false; \ | ||
58 | } | 56 | } |
59 | 57 | ||
60 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_DYN) | 58 | -GEN_OPIVX_WIDEN_TRANS(vwaddu_vx) |
61 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, vfwcvt_x_f_v, RISCV_FRM_DYN) | 59 | -GEN_OPIVX_WIDEN_TRANS(vwadd_vx) |
62 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, vfwcvt_f_f_v, RISCV_FRM_DYN) | 60 | -GEN_OPIVX_WIDEN_TRANS(vwsubu_vx) |
63 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v, | 61 | -GEN_OPIVX_WIDEN_TRANS(vwsub_vx) |
64 | + RISCV_FRM_DYN) | 62 | +GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check) |
65 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, opxfv_widen_check, vfwcvt_x_f_v, | 63 | +GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check) |
66 | + RISCV_FRM_DYN) | 64 | +GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check) |
67 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v, | 65 | +GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check) |
68 | + RISCV_FRM_DYN) | 66 | |
69 | /* Reuse the helper functions from vfwcvt.xu.f.v and vfwcvt.x.f.v */ | 67 | /* WIDEN OPIVV with WIDEN */ |
70 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_RTZ) | 68 | static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a) |
71 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, vfwcvt_x_f_v, RISCV_FRM_RTZ) | 69 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check) |
72 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v, | 70 | GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check) |
73 | + RISCV_FRM_RTZ) | 71 | GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check) |
74 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, opxfv_widen_check, vfwcvt_x_f_v, | 72 | GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check) |
75 | + RISCV_FRM_RTZ) | 73 | -GEN_OPIVX_WIDEN_TRANS(vwmul_vx) |
76 | 74 | -GEN_OPIVX_WIDEN_TRANS(vwmulu_vx) | |
77 | static bool opfxv_widen_check(DisasContext *s, arg_rmr *a) | 75 | -GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx) |
78 | { | 76 | +GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check) |
77 | +GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check) | ||
78 | +GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check) | ||
79 | |||
80 | /* Vector Single-Width Integer Multiply-Add Instructions */ | ||
81 | GEN_OPIVV_TRANS(vmacc_vv, opivv_check) | ||
82 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check) | ||
83 | GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check) | ||
84 | GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check) | ||
85 | GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check) | ||
86 | -GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx) | ||
87 | -GEN_OPIVX_WIDEN_TRANS(vwmacc_vx) | ||
88 | -GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx) | ||
89 | -GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx) | ||
90 | +GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check) | ||
91 | +GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check) | ||
92 | +GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check) | ||
93 | +GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check) | ||
94 | |||
95 | /* Vector Integer Merge and Move Instructions */ | ||
96 | static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a) | ||
79 | -- | 97 | -- |
80 | 2.31.1 | 98 | 2.41.0 |
81 | |||
82 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | lwu and ld are functionally close to the other loads, but were after the | 3 | Move some macros out of `vector_helper` and into `vector_internals`. |
4 | stores in the source file. | 4 | This ensures they can be used by both vector and vector-crypto helpers |
5 | Similarly, xor was away from or and and by two arithmetic functions, while | 5 | (latter implemented in proceeding commits). |
6 | the immediate versions were nicely put together. | ||
7 | This patch moves the aforementioned loads after lhu, and xor above or, | ||
8 | where they more logically belong. | ||
9 | 6 | ||
10 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 7 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
11 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 8 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | Signed-off-by: Max Chou <max.chou@sifive.com> |
13 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 10 | Message-ID: <20230711165917.2629866-8-max.chou@sifive.com> |
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | Message-id: 20220106210108.138226-9-frederic.petrot@univ-grenoble-alpes.fr | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
17 | --- | 12 | --- |
18 | target/riscv/insn_trans/trans_rvi.c.inc | 34 ++++++++++++------------- | 13 | target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++ |
19 | 1 file changed, 17 insertions(+), 17 deletions(-) | 14 | target/riscv/vector_helper.c | 42 ------------------------------ |
15 | 2 files changed, 46 insertions(+), 42 deletions(-) | ||
20 | 16 | ||
21 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | 17 | diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h |
22 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | 19 | --- a/target/riscv/vector_internals.h |
24 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | 20 | +++ b/target/riscv/vector_internals.h |
25 | @@ -XXX,XX +XXX,XX @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a) | 21 | @@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, |
26 | return gen_load(ctx, a, MO_TEUW); | 22 | /* expand macro args before macro */ |
27 | } | 23 | #define RVVCALL(macro, ...) macro(__VA_ARGS__) |
28 | 24 | ||
29 | +static bool trans_lwu(DisasContext *ctx, arg_lwu *a) | 25 | +/* (TD, T2, TX2) */ |
30 | +{ | 26 | +#define OP_UU_B uint8_t, uint8_t, uint8_t |
31 | + REQUIRE_64BIT(ctx); | 27 | +#define OP_UU_H uint16_t, uint16_t, uint16_t |
32 | + return gen_load(ctx, a, MO_TEUL); | 28 | +#define OP_UU_W uint32_t, uint32_t, uint32_t |
29 | +#define OP_UU_D uint64_t, uint64_t, uint64_t | ||
30 | + | ||
31 | /* (TD, T1, T2, TX1, TX2) */ | ||
32 | #define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t | ||
33 | #define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t | ||
34 | #define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t | ||
35 | #define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t | ||
36 | |||
37 | +#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \ | ||
38 | +static void do_##NAME(void *vd, void *vs2, int i) \ | ||
39 | +{ \ | ||
40 | + TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
41 | + *((TD *)vd + HD(i)) = OP(s2); \ | ||
33 | +} | 42 | +} |
34 | + | 43 | + |
35 | +static bool trans_ld(DisasContext *ctx, arg_ld *a) | 44 | +#define GEN_VEXT_V(NAME, ESZ) \ |
36 | +{ | 45 | +void HELPER(NAME)(void *vd, void *v0, void *vs2, \ |
37 | + REQUIRE_64BIT(ctx); | 46 | + CPURISCVState *env, uint32_t desc) \ |
38 | + return gen_load(ctx, a, MO_TEUQ); | 47 | +{ \ |
48 | + uint32_t vm = vext_vm(desc); \ | ||
49 | + uint32_t vl = env->vl; \ | ||
50 | + uint32_t total_elems = \ | ||
51 | + vext_get_total_elems(env, desc, ESZ); \ | ||
52 | + uint32_t vta = vext_vta(desc); \ | ||
53 | + uint32_t vma = vext_vma(desc); \ | ||
54 | + uint32_t i; \ | ||
55 | + \ | ||
56 | + for (i = env->vstart; i < vl; i++) { \ | ||
57 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
58 | + /* set masked-off elements to 1s */ \ | ||
59 | + vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
60 | + (i + 1) * ESZ); \ | ||
61 | + continue; \ | ||
62 | + } \ | ||
63 | + do_##NAME(vd, vs2, i); \ | ||
64 | + } \ | ||
65 | + env->vstart = 0; \ | ||
66 | + /* set tail elements to 1s */ \ | ||
67 | + vext_set_elems_1s(vd, vta, vl * ESZ, \ | ||
68 | + total_elems * ESZ); \ | ||
39 | +} | 69 | +} |
40 | + | 70 | + |
41 | static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) | 71 | /* operation of two vector elements */ |
42 | { | 72 | typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i); |
43 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | 73 | |
44 | @@ -XXX,XX +XXX,XX @@ static bool trans_sw(DisasContext *ctx, arg_sw *a) | 74 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ |
45 | return gen_store(ctx, a, MO_TESL); | 75 | do_##NAME, ESZ); \ |
46 | } | 76 | } |
47 | 77 | ||
48 | -static bool trans_lwu(DisasContext *ctx, arg_lwu *a) | 78 | +/* Three of the widening shortening macros: */ |
49 | -{ | 79 | +/* (TD, T1, T2, TX1, TX2) */ |
50 | - REQUIRE_64BIT(ctx); | 80 | +#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t |
51 | - return gen_load(ctx, a, MO_TEUL); | 81 | +#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t |
82 | +#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t | ||
83 | + | ||
84 | #endif /* TARGET_RISCV_VECTOR_INTERNALS_H */ | ||
85 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
86 | index XXXXXXX..XXXXXXX 100644 | ||
87 | --- a/target/riscv/vector_helper.c | ||
88 | +++ b/target/riscv/vector_helper.c | ||
89 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b) | ||
90 | #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t | ||
91 | #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t | ||
92 | #define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t | ||
93 | -#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t | ||
94 | -#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t | ||
95 | -#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t | ||
96 | #define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t | ||
97 | #define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t | ||
98 | #define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t | ||
99 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4) | ||
100 | GEN_VEXT_VF(vfwnmsac_vf_w, 8) | ||
101 | |||
102 | /* Vector Floating-Point Square-Root Instruction */ | ||
103 | -/* (TD, T2, TX2) */ | ||
104 | -#define OP_UU_H uint16_t, uint16_t, uint16_t | ||
105 | -#define OP_UU_W uint32_t, uint32_t, uint32_t | ||
106 | -#define OP_UU_D uint64_t, uint64_t, uint64_t | ||
107 | - | ||
108 | #define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \ | ||
109 | static void do_##NAME(void *vd, void *vs2, int i, \ | ||
110 | CPURISCVState *env) \ | ||
111 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32) | ||
112 | GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64) | ||
113 | |||
114 | /* Vector Floating-Point Classify Instruction */ | ||
115 | -#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \ | ||
116 | -static void do_##NAME(void *vd, void *vs2, int i) \ | ||
117 | -{ \ | ||
118 | - TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
119 | - *((TD *)vd + HD(i)) = OP(s2); \ | ||
52 | -} | 120 | -} |
53 | - | 121 | - |
54 | -static bool trans_ld(DisasContext *ctx, arg_ld *a) | 122 | -#define GEN_VEXT_V(NAME, ESZ) \ |
55 | -{ | 123 | -void HELPER(NAME)(void *vd, void *v0, void *vs2, \ |
56 | - REQUIRE_64BIT(ctx); | 124 | - CPURISCVState *env, uint32_t desc) \ |
57 | - return gen_load(ctx, a, MO_TEUQ); | 125 | -{ \ |
126 | - uint32_t vm = vext_vm(desc); \ | ||
127 | - uint32_t vl = env->vl; \ | ||
128 | - uint32_t total_elems = \ | ||
129 | - vext_get_total_elems(env, desc, ESZ); \ | ||
130 | - uint32_t vta = vext_vta(desc); \ | ||
131 | - uint32_t vma = vext_vma(desc); \ | ||
132 | - uint32_t i; \ | ||
133 | - \ | ||
134 | - for (i = env->vstart; i < vl; i++) { \ | ||
135 | - if (!vm && !vext_elem_mask(v0, i)) { \ | ||
136 | - /* set masked-off elements to 1s */ \ | ||
137 | - vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
138 | - (i + 1) * ESZ); \ | ||
139 | - continue; \ | ||
140 | - } \ | ||
141 | - do_##NAME(vd, vs2, i); \ | ||
142 | - } \ | ||
143 | - env->vstart = 0; \ | ||
144 | - /* set tail elements to 1s */ \ | ||
145 | - vext_set_elems_1s(vd, vta, vl * ESZ, \ | ||
146 | - total_elems * ESZ); \ | ||
58 | -} | 147 | -} |
59 | - | 148 | - |
60 | static bool trans_sd(DisasContext *ctx, arg_sd *a) | 149 | target_ulong fclass_h(uint64_t frs1) |
61 | { | 150 | { |
62 | REQUIRE_64BIT(ctx); | 151 | float16 f = frs1; |
63 | @@ -XXX,XX +XXX,XX @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a) | ||
64 | return gen_arith(ctx, a, EXT_SIGN, gen_sltu); | ||
65 | } | ||
66 | |||
67 | -static bool trans_xor(DisasContext *ctx, arg_xor *a) | ||
68 | -{ | ||
69 | - return gen_logic(ctx, a, tcg_gen_xor_tl); | ||
70 | -} | ||
71 | - | ||
72 | static bool trans_srl(DisasContext *ctx, arg_srl *a) | ||
73 | { | ||
74 | return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl); | ||
75 | @@ -XXX,XX +XXX,XX @@ static bool trans_sra(DisasContext *ctx, arg_sra *a) | ||
76 | return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl); | ||
77 | } | ||
78 | |||
79 | +static bool trans_xor(DisasContext *ctx, arg_xor *a) | ||
80 | +{ | ||
81 | + return gen_logic(ctx, a, tcg_gen_xor_tl); | ||
82 | +} | ||
83 | + | ||
84 | static bool trans_or(DisasContext *ctx, arg_or *a) | ||
85 | { | ||
86 | return gen_logic(ctx, a, tcg_gen_or_tl); | ||
87 | -- | 152 | -- |
88 | 2.31.1 | 153 | 2.41.0 |
89 | |||
90 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Dickon Hood <dickon.hood@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | Handling shifts for 32, 64 and 128 operation length for RV128, following the | 3 | This commit adds support for the Zvbb vector-crypto extension, which |
4 | general framework for handling various olens proposed by Richard. | 4 | consists of the following instructions: |
5 | 5 | ||
6 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | * vrol.[vv,vx] |
7 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | * vror.[vv,vx,vi] |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | * vbrev8.v |
9 | Message-id: 20220106210108.138226-13-frederic.petrot@univ-grenoble-alpes.fr | 9 | * vrev8.v |
10 | * vandn.[vv,vx] | ||
11 | * vbrev.v | ||
12 | * vclz.v | ||
13 | * vctz.v | ||
14 | * vcpop.v | ||
15 | * vwsll.[vv,vx,vi] | ||
16 | |||
17 | Translation functions are defined in | ||
18 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in | ||
19 | `target/riscv/vcrypto_helper.c`. | ||
20 | |||
21 | Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
22 | Co-authored-by: William Salmon <will.salmon@codethink.co.uk> | ||
23 | Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> | ||
24 | [max.chou@sifive.com: Fix imm mode of vror.vi] | ||
25 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
26 | Signed-off-by: William Salmon <will.salmon@codethink.co.uk> | ||
27 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> | ||
28 | Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk> | ||
29 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
30 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
31 | [max.chou@sifive.com: Exposed x-zvbb property] | ||
32 | Message-ID: <20230711165917.2629866-9-max.chou@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 33 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 34 | --- |
12 | target/riscv/insn32.decode | 10 ++ | 35 | target/riscv/cpu_cfg.h | 1 + |
13 | target/riscv/translate.c | 58 ++++-- | 36 | target/riscv/helper.h | 62 +++++++++ |
14 | target/riscv/insn_trans/trans_rvb.c.inc | 22 +-- | 37 | target/riscv/insn32.decode | 20 +++ |
15 | target/riscv/insn_trans/trans_rvi.c.inc | 224 ++++++++++++++++++++++-- | 38 | target/riscv/cpu.c | 12 ++ |
16 | 4 files changed, 270 insertions(+), 44 deletions(-) | 39 | target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++ |
40 | target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++ | ||
41 | 6 files changed, 397 insertions(+) | ||
17 | 42 | ||
43 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/cpu_cfg.h | ||
46 | +++ b/target/riscv/cpu_cfg.h | ||
47 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
48 | bool ext_zve32f; | ||
49 | bool ext_zve64f; | ||
50 | bool ext_zve64d; | ||
51 | + bool ext_zvbb; | ||
52 | bool ext_zvbc; | ||
53 | bool ext_zmmul; | ||
54 | bool ext_zvfbfmin; | ||
55 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/target/riscv/helper.h | ||
58 | +++ b/target/riscv/helper.h | ||
59 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32) | ||
60 | DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32) | ||
61 | DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32) | ||
62 | DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32) | ||
63 | + | ||
64 | +DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
65 | +DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
66 | +DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
67 | +DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
68 | + | ||
69 | +DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
70 | +DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
71 | +DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
72 | +DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
73 | + | ||
74 | +DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
75 | +DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
76 | +DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
77 | +DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
78 | + | ||
79 | +DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
80 | +DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
81 | +DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
82 | +DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
83 | + | ||
84 | +DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32) | ||
85 | +DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32) | ||
86 | +DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32) | ||
87 | +DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32) | ||
88 | +DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32) | ||
89 | +DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32) | ||
90 | +DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32) | ||
91 | +DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32) | ||
92 | +DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32) | ||
93 | +DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32) | ||
94 | +DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32) | ||
95 | +DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32) | ||
96 | + | ||
97 | +DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32) | ||
98 | +DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32) | ||
99 | +DEF_HELPER_5(vclz_v_w, void, ptr, ptr, ptr, env, i32) | ||
100 | +DEF_HELPER_5(vclz_v_d, void, ptr, ptr, ptr, env, i32) | ||
101 | +DEF_HELPER_5(vctz_v_b, void, ptr, ptr, ptr, env, i32) | ||
102 | +DEF_HELPER_5(vctz_v_h, void, ptr, ptr, ptr, env, i32) | ||
103 | +DEF_HELPER_5(vctz_v_w, void, ptr, ptr, ptr, env, i32) | ||
104 | +DEF_HELPER_5(vctz_v_d, void, ptr, ptr, ptr, env, i32) | ||
105 | +DEF_HELPER_5(vcpop_v_b, void, ptr, ptr, ptr, env, i32) | ||
106 | +DEF_HELPER_5(vcpop_v_h, void, ptr, ptr, ptr, env, i32) | ||
107 | +DEF_HELPER_5(vcpop_v_w, void, ptr, ptr, ptr, env, i32) | ||
108 | +DEF_HELPER_5(vcpop_v_d, void, ptr, ptr, ptr, env, i32) | ||
109 | + | ||
110 | +DEF_HELPER_6(vwsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
111 | +DEF_HELPER_6(vwsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
112 | +DEF_HELPER_6(vwsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
113 | +DEF_HELPER_6(vwsll_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
114 | +DEF_HELPER_6(vwsll_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
115 | +DEF_HELPER_6(vwsll_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
116 | + | ||
117 | +DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
118 | +DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
119 | +DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
120 | +DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
121 | +DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
122 | +DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
123 | +DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
124 | +DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
18 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 125 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode |
19 | index XXXXXXX..XXXXXXX 100644 | 126 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/riscv/insn32.decode | 127 | --- a/target/riscv/insn32.decode |
21 | +++ b/target/riscv/insn32.decode | 128 | +++ b/target/riscv/insn32.decode |
22 | @@ -XXX,XX +XXX,XX @@ | 129 | @@ -XXX,XX +XXX,XX @@ |
23 | %rs1 15:5 | 130 | %imm_u 12:s20 !function=ex_shift_12 |
24 | %rd 7:5 | 131 | %imm_bs 30:2 !function=ex_shift_3 |
25 | %sh5 20:5 | 132 | %imm_rnum 20:4 |
26 | +%sh6 20:6 | 133 | +%imm_z6 26:1 15:5 |
27 | 134 | ||
28 | %sh7 20:7 | 135 | # Argument sets: |
29 | %csr 20:12 | 136 | &empty |
30 | @@ -XXX,XX +XXX,XX @@ | 137 | @@ -XXX,XX +XXX,XX @@ |
31 | # Formats 64: | 138 | @r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd |
32 | @sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd | 139 | @r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd |
33 | 140 | @r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd | |
34 | +# Formats 128: | 141 | +@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd |
35 | +@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd | 142 | @r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd |
36 | + | 143 | @r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd |
37 | # *** Privileged Instructions *** | 144 | @r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1 |
38 | ecall 000000000000 00000 000 00000 1110011 | 145 | @@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm |
39 | ebreak 000000000001 00000 000 00000 1110011 | 146 | vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm |
40 | @@ -XXX,XX +XXX,XX @@ sraw 0100000 ..... ..... 101 ..... 0111011 @r | 147 | vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm |
41 | ldu ............ ..... 111 ..... 0000011 @i | 148 | vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm |
42 | lq ............ ..... 010 ..... 0001111 @i | 149 | + |
43 | sq ............ ..... 100 ..... 0100011 @s | 150 | +# *** Zvbb vector crypto extension *** |
44 | +sllid 000000 ...... ..... 001 ..... 1011011 @sh6 | 151 | +vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm |
45 | +srlid 000000 ...... ..... 101 ..... 1011011 @sh6 | 152 | +vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm |
46 | +sraid 010000 ...... ..... 101 ..... 1011011 @sh6 | 153 | +vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm |
47 | +slld 0000000 ..... ..... 001 ..... 1111011 @r | 154 | +vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm |
48 | +srld 0000000 ..... ..... 101 ..... 1111011 @r | 155 | +vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6 |
49 | +srad 0100000 ..... ..... 101 ..... 1111011 @r | 156 | +vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm |
50 | 157 | +vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm | |
51 | # *** RV32M Standard Extension *** | 158 | +vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm |
52 | mul 0000001 ..... ..... 000 ..... 0110011 @r | 159 | +vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm |
53 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 160 | +vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm |
161 | +vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm | ||
162 | +vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm | ||
163 | +vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm | ||
164 | +vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm | ||
165 | +vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm | ||
166 | +vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm | ||
167 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
54 | index XXXXXXX..XXXXXXX 100644 | 168 | index XXXXXXX..XXXXXXX 100644 |
55 | --- a/target/riscv/translate.c | 169 | --- a/target/riscv/cpu.c |
56 | +++ b/target/riscv/translate.c | 170 | +++ b/target/riscv/cpu.c |
57 | @@ -XXX,XX +XXX,XX @@ static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext, | 171 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
58 | } | 172 | ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed), |
59 | 173 | ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh), | |
60 | static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext, | 174 | ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt), |
61 | - void (*func)(TCGv, TCGv, target_long)) | 175 | + ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb), |
62 | + void (*func)(TCGv, TCGv, target_long), | 176 | ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc), |
63 | + void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long)) | 177 | ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f), |
64 | { | 178 | ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f), |
65 | TCGv dest, src1; | 179 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
66 | int max_len = get_olen(ctx); | 180 | return; |
67 | @@ -XXX,XX +XXX,XX @@ static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext, | ||
68 | dest = dest_gpr(ctx, a->rd); | ||
69 | src1 = get_gpr(ctx, a->rs1, ext); | ||
70 | |||
71 | - func(dest, src1, a->shamt); | ||
72 | + if (max_len < 128) { | ||
73 | + func(dest, src1, a->shamt); | ||
74 | + gen_set_gpr(ctx, a->rd, dest); | ||
75 | + } else { | ||
76 | + TCGv src1h = get_gprh(ctx, a->rs1); | ||
77 | + TCGv desth = dest_gprh(ctx, a->rd); | ||
78 | |||
79 | - gen_set_gpr(ctx, a->rd, dest); | ||
80 | + if (f128 == NULL) { | ||
81 | + return false; | ||
82 | + } | ||
83 | + f128(dest, desth, src1, src1h, a->shamt); | ||
84 | + gen_set_gpr128(ctx, a->rd, dest, desth); | ||
85 | + } | ||
86 | return true; | ||
87 | } | ||
88 | |||
89 | static bool gen_shift_imm_fn_per_ol(DisasContext *ctx, arg_shift *a, | ||
90 | DisasExtend ext, | ||
91 | void (*f_tl)(TCGv, TCGv, target_long), | ||
92 | - void (*f_32)(TCGv, TCGv, target_long)) | ||
93 | + void (*f_32)(TCGv, TCGv, target_long), | ||
94 | + void (*f_128)(TCGv, TCGv, TCGv, TCGv, | ||
95 | + target_long)) | ||
96 | { | ||
97 | int olen = get_olen(ctx); | ||
98 | if (olen != TARGET_LONG_BITS) { | ||
99 | if (olen == 32) { | ||
100 | f_tl = f_32; | ||
101 | - } else { | ||
102 | + } else if (olen != 128) { | ||
103 | g_assert_not_reached(); | ||
104 | } | ||
105 | } | 181 | } |
106 | - return gen_shift_imm_fn(ctx, a, ext, f_tl); | 182 | |
107 | + return gen_shift_imm_fn(ctx, a, ext, f_tl, f_128); | 183 | + /* |
108 | } | 184 | + * In principle Zve*x would also suffice here, were they supported |
109 | 185 | + * in qemu | |
110 | static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext, | 186 | + */ |
111 | @@ -XXX,XX +XXX,XX @@ static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext, | 187 | + if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) { |
112 | } | 188 | + error_setg(errp, |
113 | 189 | + "Vector crypto extensions require V or Zve* extensions"); | |
114 | static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext, | 190 | + return; |
115 | - void (*func)(TCGv, TCGv, TCGv)) | 191 | + } |
116 | + void (*func)(TCGv, TCGv, TCGv), | 192 | + |
117 | + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv)) | 193 | if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) { |
118 | { | 194 | error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions"); |
119 | - TCGv dest = dest_gpr(ctx, a->rd); | 195 | return; |
120 | - TCGv src1 = get_gpr(ctx, a->rs1, ext); | 196 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { |
121 | TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); | 197 | DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false), |
122 | TCGv ext2 = tcg_temp_new(); | 198 | |
123 | + int max_len = get_olen(ctx); | 199 | /* Vector cryptography extensions */ |
124 | 200 | + DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false), | |
125 | - tcg_gen_andi_tl(ext2, src2, get_olen(ctx) - 1); | 201 | DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), |
126 | - func(dest, src1, ext2); | 202 | |
127 | + tcg_gen_andi_tl(ext2, src2, max_len - 1); | 203 | DEFINE_PROP_END_OF_LIST(), |
128 | 204 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | |
129 | - gen_set_gpr(ctx, a->rd, dest); | ||
130 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
131 | + TCGv src1 = get_gpr(ctx, a->rs1, ext); | ||
132 | + | ||
133 | + if (max_len < 128) { | ||
134 | + func(dest, src1, ext2); | ||
135 | + gen_set_gpr(ctx, a->rd, dest); | ||
136 | + } else { | ||
137 | + TCGv src1h = get_gprh(ctx, a->rs1); | ||
138 | + TCGv desth = dest_gprh(ctx, a->rd); | ||
139 | + | ||
140 | + if (f128 == NULL) { | ||
141 | + return false; | ||
142 | + } | ||
143 | + f128(dest, desth, src1, src1h, ext2); | ||
144 | + gen_set_gpr128(ctx, a->rd, dest, desth); | ||
145 | + } | ||
146 | tcg_temp_free(ext2); | ||
147 | return true; | ||
148 | } | ||
149 | |||
150 | static bool gen_shift_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext, | ||
151 | void (*f_tl)(TCGv, TCGv, TCGv), | ||
152 | - void (*f_32)(TCGv, TCGv, TCGv)) | ||
153 | + void (*f_32)(TCGv, TCGv, TCGv), | ||
154 | + void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv)) | ||
155 | { | ||
156 | int olen = get_olen(ctx); | ||
157 | if (olen != TARGET_LONG_BITS) { | ||
158 | if (olen == 32) { | ||
159 | f_tl = f_32; | ||
160 | - } else { | ||
161 | + } else if (olen != 128) { | ||
162 | g_assert_not_reached(); | ||
163 | } | ||
164 | } | ||
165 | - return gen_shift(ctx, a, ext, f_tl); | ||
166 | + return gen_shift(ctx, a, ext, f_tl, f_128); | ||
167 | } | ||
168 | |||
169 | static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext, | ||
170 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | ||
171 | index XXXXXXX..XXXXXXX 100644 | 205 | index XXXXXXX..XXXXXXX 100644 |
172 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | 206 | --- a/target/riscv/vcrypto_helper.c |
173 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | 207 | +++ b/target/riscv/vcrypto_helper.c |
174 | @@ -XXX,XX +XXX,XX @@ static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt) | 208 | @@ -XXX,XX +XXX,XX @@ |
175 | static bool trans_bset(DisasContext *ctx, arg_bset *a) | 209 | #include "qemu/osdep.h" |
176 | { | 210 | #include "qemu/host-utils.h" |
177 | REQUIRE_ZBS(ctx); | 211 | #include "qemu/bitops.h" |
178 | - return gen_shift(ctx, a, EXT_NONE, gen_bset); | 212 | +#include "qemu/bswap.h" |
179 | + return gen_shift(ctx, a, EXT_NONE, gen_bset, NULL); | 213 | #include "cpu.h" |
180 | } | 214 | #include "exec/memop.h" |
181 | 215 | #include "exec/exec-all.h" | |
182 | static bool trans_bseti(DisasContext *ctx, arg_bseti *a) | 216 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64) |
183 | @@ -XXX,XX +XXX,XX @@ static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt) | 217 | GEN_VEXT_VV(vclmulh_vv, 8) |
184 | static bool trans_bclr(DisasContext *ctx, arg_bclr *a) | 218 | RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64) |
185 | { | 219 | GEN_VEXT_VX(vclmulh_vx, 8) |
186 | REQUIRE_ZBS(ctx); | 220 | + |
187 | - return gen_shift(ctx, a, EXT_NONE, gen_bclr); | 221 | +RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8) |
188 | + return gen_shift(ctx, a, EXT_NONE, gen_bclr, NULL); | 222 | +RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16) |
189 | } | 223 | +RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32) |
190 | 224 | +RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64) | |
191 | static bool trans_bclri(DisasContext *ctx, arg_bclri *a) | 225 | +GEN_VEXT_VV(vror_vv_b, 1) |
192 | @@ -XXX,XX +XXX,XX @@ static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt) | 226 | +GEN_VEXT_VV(vror_vv_h, 2) |
193 | static bool trans_binv(DisasContext *ctx, arg_binv *a) | 227 | +GEN_VEXT_VV(vror_vv_w, 4) |
194 | { | 228 | +GEN_VEXT_VV(vror_vv_d, 8) |
195 | REQUIRE_ZBS(ctx); | 229 | + |
196 | - return gen_shift(ctx, a, EXT_NONE, gen_binv); | 230 | +RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8) |
197 | + return gen_shift(ctx, a, EXT_NONE, gen_binv, NULL); | 231 | +RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16) |
198 | } | 232 | +RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32) |
199 | 233 | +RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64) | |
200 | static bool trans_binvi(DisasContext *ctx, arg_binvi *a) | 234 | +GEN_VEXT_VX(vror_vx_b, 1) |
201 | @@ -XXX,XX +XXX,XX @@ static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt) | 235 | +GEN_VEXT_VX(vror_vx_h, 2) |
202 | static bool trans_bext(DisasContext *ctx, arg_bext *a) | 236 | +GEN_VEXT_VX(vror_vx_w, 4) |
203 | { | 237 | +GEN_VEXT_VX(vror_vx_d, 8) |
204 | REQUIRE_ZBS(ctx); | 238 | + |
205 | - return gen_shift(ctx, a, EXT_NONE, gen_bext); | 239 | +RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8) |
206 | + return gen_shift(ctx, a, EXT_NONE, gen_bext, NULL); | 240 | +RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16) |
207 | } | 241 | +RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32) |
208 | 242 | +RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64) | |
209 | static bool trans_bexti(DisasContext *ctx, arg_bexti *a) | 243 | +GEN_VEXT_VV(vrol_vv_b, 1) |
210 | @@ -XXX,XX +XXX,XX @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2) | 244 | +GEN_VEXT_VV(vrol_vv_h, 2) |
211 | static bool trans_ror(DisasContext *ctx, arg_ror *a) | 245 | +GEN_VEXT_VV(vrol_vv_w, 4) |
212 | { | 246 | +GEN_VEXT_VV(vrol_vv_d, 8) |
213 | REQUIRE_ZBB(ctx); | 247 | + |
214 | - return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw); | 248 | +RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8) |
215 | + return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw, NULL); | 249 | +RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16) |
216 | } | 250 | +RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32) |
217 | 251 | +RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64) | |
218 | static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt) | 252 | +GEN_VEXT_VX(vrol_vx_b, 1) |
219 | @@ -XXX,XX +XXX,XX @@ static bool trans_rori(DisasContext *ctx, arg_rori *a) | 253 | +GEN_VEXT_VX(vrol_vx_h, 2) |
220 | { | 254 | +GEN_VEXT_VX(vrol_vx_w, 4) |
221 | REQUIRE_ZBB(ctx); | 255 | +GEN_VEXT_VX(vrol_vx_d, 8) |
222 | return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, | 256 | + |
223 | - tcg_gen_rotri_tl, gen_roriw); | 257 | +static uint64_t brev8(uint64_t val) |
224 | + tcg_gen_rotri_tl, gen_roriw, NULL); | 258 | +{ |
225 | } | 259 | + val = ((val & 0x5555555555555555ull) << 1) | |
226 | 260 | + ((val & 0xAAAAAAAAAAAAAAAAull) >> 1); | |
227 | static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) | 261 | + val = ((val & 0x3333333333333333ull) << 2) | |
228 | @@ -XXX,XX +XXX,XX @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) | 262 | + ((val & 0xCCCCCCCCCCCCCCCCull) >> 2); |
229 | static bool trans_rol(DisasContext *ctx, arg_rol *a) | 263 | + val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) | |
230 | { | 264 | + ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4); |
231 | REQUIRE_ZBB(ctx); | 265 | + |
232 | - return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw); | 266 | + return val; |
233 | + return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw, NULL); | 267 | +} |
234 | } | 268 | + |
235 | 269 | +RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8) | |
236 | static void gen_rev8_32(TCGv ret, TCGv src1) | 270 | +RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8) |
237 | @@ -XXX,XX +XXX,XX @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a) | 271 | +RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8) |
238 | REQUIRE_64BIT(ctx); | 272 | +RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8) |
239 | REQUIRE_ZBB(ctx); | 273 | +GEN_VEXT_V(vbrev8_v_b, 1) |
240 | ctx->ol = MXL_RV32; | 274 | +GEN_VEXT_V(vbrev8_v_h, 2) |
241 | - return gen_shift(ctx, a, EXT_NONE, gen_rorw); | 275 | +GEN_VEXT_V(vbrev8_v_w, 4) |
242 | + return gen_shift(ctx, a, EXT_NONE, gen_rorw, NULL); | 276 | +GEN_VEXT_V(vbrev8_v_d, 8) |
243 | } | 277 | + |
244 | 278 | +#define DO_IDENTITY(a) (a) | |
245 | static bool trans_roriw(DisasContext *ctx, arg_roriw *a) | 279 | +RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY) |
246 | @@ -XXX,XX +XXX,XX @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a) | 280 | +RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16) |
247 | REQUIRE_64BIT(ctx); | 281 | +RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32) |
248 | REQUIRE_ZBB(ctx); | 282 | +RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64) |
249 | ctx->ol = MXL_RV32; | 283 | +GEN_VEXT_V(vrev8_v_b, 1) |
250 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw); | 284 | +GEN_VEXT_V(vrev8_v_h, 2) |
251 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL); | 285 | +GEN_VEXT_V(vrev8_v_w, 4) |
252 | } | 286 | +GEN_VEXT_V(vrev8_v_d, 8) |
253 | 287 | + | |
254 | static bool trans_rolw(DisasContext *ctx, arg_rolw *a) | 288 | +#define DO_ANDN(a, b) ((a) & ~(b)) |
255 | @@ -XXX,XX +XXX,XX @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a) | 289 | +RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN) |
256 | REQUIRE_64BIT(ctx); | 290 | +RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN) |
257 | REQUIRE_ZBB(ctx); | 291 | +RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN) |
258 | ctx->ol = MXL_RV32; | 292 | +RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN) |
259 | - return gen_shift(ctx, a, EXT_NONE, gen_rolw); | 293 | +GEN_VEXT_VV(vandn_vv_b, 1) |
260 | + return gen_shift(ctx, a, EXT_NONE, gen_rolw, NULL); | 294 | +GEN_VEXT_VV(vandn_vv_h, 2) |
261 | } | 295 | +GEN_VEXT_VV(vandn_vv_w, 4) |
262 | 296 | +GEN_VEXT_VV(vandn_vv_d, 8) | |
263 | #define GEN_SHADD_UW(SHAMT) \ | 297 | + |
264 | @@ -XXX,XX +XXX,XX @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a) | 298 | +RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN) |
265 | { | 299 | +RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN) |
266 | REQUIRE_64BIT(ctx); | 300 | +RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN) |
267 | REQUIRE_ZBA(ctx); | 301 | +RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN) |
268 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw); | 302 | +GEN_VEXT_VX(vandn_vx_b, 1) |
269 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw, NULL); | 303 | +GEN_VEXT_VX(vandn_vx_h, 2) |
270 | } | 304 | +GEN_VEXT_VX(vandn_vx_w, 4) |
271 | 305 | +GEN_VEXT_VX(vandn_vx_d, 8) | |
272 | static bool trans_clmul(DisasContext *ctx, arg_clmul *a) | 306 | + |
273 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | 307 | +RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8) |
308 | +RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16) | ||
309 | +RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32) | ||
310 | +RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64) | ||
311 | +GEN_VEXT_V(vbrev_v_b, 1) | ||
312 | +GEN_VEXT_V(vbrev_v_h, 2) | ||
313 | +GEN_VEXT_V(vbrev_v_w, 4) | ||
314 | +GEN_VEXT_V(vbrev_v_d, 8) | ||
315 | + | ||
316 | +RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8) | ||
317 | +RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16) | ||
318 | +RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32) | ||
319 | +RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64) | ||
320 | +GEN_VEXT_V(vclz_v_b, 1) | ||
321 | +GEN_VEXT_V(vclz_v_h, 2) | ||
322 | +GEN_VEXT_V(vclz_v_w, 4) | ||
323 | +GEN_VEXT_V(vclz_v_d, 8) | ||
324 | + | ||
325 | +RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8) | ||
326 | +RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16) | ||
327 | +RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32) | ||
328 | +RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64) | ||
329 | +GEN_VEXT_V(vctz_v_b, 1) | ||
330 | +GEN_VEXT_V(vctz_v_h, 2) | ||
331 | +GEN_VEXT_V(vctz_v_w, 4) | ||
332 | +GEN_VEXT_V(vctz_v_d, 8) | ||
333 | + | ||
334 | +RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8) | ||
335 | +RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16) | ||
336 | +RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32) | ||
337 | +RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64) | ||
338 | +GEN_VEXT_V(vcpop_v_b, 1) | ||
339 | +GEN_VEXT_V(vcpop_v_h, 2) | ||
340 | +GEN_VEXT_V(vcpop_v_w, 4) | ||
341 | +GEN_VEXT_V(vcpop_v_d, 8) | ||
342 | + | ||
343 | +#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1))) | ||
344 | +RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL) | ||
345 | +RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL) | ||
346 | +RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL) | ||
347 | +GEN_VEXT_VV(vwsll_vv_b, 2) | ||
348 | +GEN_VEXT_VV(vwsll_vv_h, 4) | ||
349 | +GEN_VEXT_VV(vwsll_vv_w, 8) | ||
350 | + | ||
351 | +RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL) | ||
352 | +RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL) | ||
353 | +RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL) | ||
354 | +GEN_VEXT_VX(vwsll_vx_b, 2) | ||
355 | +GEN_VEXT_VX(vwsll_vx_h, 4) | ||
356 | +GEN_VEXT_VX(vwsll_vx_w, 8) | ||
357 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
274 | index XXXXXXX..XXXXXXX 100644 | 358 | index XXXXXXX..XXXXXXX 100644 |
275 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | 359 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc |
276 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | 360 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc |
277 | @@ -XXX,XX +XXX,XX @@ static bool trans_andi(DisasContext *ctx, arg_andi *a) | 361 | @@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a) |
278 | return gen_logic_imm_fn(ctx, a, tcg_gen_andi_tl); | 362 | |
279 | } | 363 | GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check) |
280 | 364 | GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check) | |
281 | +static void gen_slli_i128(TCGv retl, TCGv reth, | 365 | + |
282 | + TCGv src1l, TCGv src1h, | 366 | +/* |
283 | + target_long shamt) | 367 | + * Zvbb |
368 | + */ | ||
369 | + | ||
370 | +#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \ | ||
371 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
372 | + { \ | ||
373 | + if (CHECK(s, a)) { \ | ||
374 | + static gen_helper_opivx *const fns[4] = { \ | ||
375 | + gen_helper_##OPIVX##_b, \ | ||
376 | + gen_helper_##OPIVX##_h, \ | ||
377 | + gen_helper_##OPIVX##_w, \ | ||
378 | + gen_helper_##OPIVX##_d, \ | ||
379 | + }; \ | ||
380 | + return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \ | ||
381 | + IMM_MODE); \ | ||
382 | + } \ | ||
383 | + return false; \ | ||
384 | + } | ||
385 | + | ||
386 | +#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \ | ||
387 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
388 | + { \ | ||
389 | + if (CHECK(s, a)) { \ | ||
390 | + static gen_helper_gvec_4_ptr *const fns[4] = { \ | ||
391 | + gen_helper_##NAME##_b, \ | ||
392 | + gen_helper_##NAME##_h, \ | ||
393 | + gen_helper_##NAME##_w, \ | ||
394 | + gen_helper_##NAME##_d, \ | ||
395 | + }; \ | ||
396 | + return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \ | ||
397 | + } \ | ||
398 | + return false; \ | ||
399 | + } | ||
400 | + | ||
401 | +#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \ | ||
402 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
403 | + { \ | ||
404 | + if (CHECK(s, a)) { \ | ||
405 | + static gen_helper_opivx *const fns[4] = { \ | ||
406 | + gen_helper_##NAME##_b, \ | ||
407 | + gen_helper_##NAME##_h, \ | ||
408 | + gen_helper_##NAME##_w, \ | ||
409 | + gen_helper_##NAME##_d, \ | ||
410 | + }; \ | ||
411 | + return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \ | ||
412 | + fns[s->sew]); \ | ||
413 | + } \ | ||
414 | + return false; \ | ||
415 | + } | ||
416 | + | ||
417 | +static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a) | ||
284 | +{ | 418 | +{ |
285 | + if (shamt >= 64) { | 419 | + return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true; |
286 | + tcg_gen_shli_tl(reth, src1l, shamt - 64); | ||
287 | + tcg_gen_movi_tl(retl, 0); | ||
288 | + } else { | ||
289 | + tcg_gen_extract2_tl(reth, src1l, src1h, 64 - shamt); | ||
290 | + tcg_gen_shli_tl(retl, src1l, shamt); | ||
291 | + } | ||
292 | +} | 420 | +} |
293 | + | 421 | + |
294 | static bool trans_slli(DisasContext *ctx, arg_slli *a) | 422 | +static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a) |
295 | { | ||
296 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl); | ||
297 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl, gen_slli_i128); | ||
298 | } | ||
299 | |||
300 | static void gen_srliw(TCGv dst, TCGv src, target_long shamt) | ||
301 | @@ -XXX,XX +XXX,XX @@ static void gen_srliw(TCGv dst, TCGv src, target_long shamt) | ||
302 | tcg_gen_extract_tl(dst, src, shamt, 32 - shamt); | ||
303 | } | ||
304 | |||
305 | +static void gen_srli_i128(TCGv retl, TCGv reth, | ||
306 | + TCGv src1l, TCGv src1h, | ||
307 | + target_long shamt) | ||
308 | +{ | 423 | +{ |
309 | + if (shamt >= 64) { | 424 | + return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true; |
310 | + tcg_gen_shri_tl(retl, src1h, shamt - 64); | ||
311 | + tcg_gen_movi_tl(reth, 0); | ||
312 | + } else { | ||
313 | + tcg_gen_extract2_tl(retl, src1l, src1h, shamt); | ||
314 | + tcg_gen_shri_tl(reth, src1h, shamt); | ||
315 | + } | ||
316 | +} | 425 | +} |
317 | + | 426 | + |
318 | static bool trans_srli(DisasContext *ctx, arg_srli *a) | 427 | +/* vrol.v[vx] */ |
319 | { | 428 | +GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check) |
320 | return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, | 429 | +GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check) |
321 | - tcg_gen_shri_tl, gen_srliw); | 430 | + |
322 | + tcg_gen_shri_tl, gen_srliw, gen_srli_i128); | 431 | +/* vror.v[vxi] */ |
323 | } | 432 | +GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check) |
324 | 433 | +GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvbb_vx_check) | |
325 | static void gen_sraiw(TCGv dst, TCGv src, target_long shamt) | 434 | +GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri, zvbb_vx_check) |
326 | @@ -XXX,XX +XXX,XX @@ static void gen_sraiw(TCGv dst, TCGv src, target_long shamt) | 435 | + |
327 | tcg_gen_sextract_tl(dst, src, shamt, 32 - shamt); | 436 | +#define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \ |
328 | } | 437 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
329 | 438 | + { \ | |
330 | +static void gen_srai_i128(TCGv retl, TCGv reth, | 439 | + if (CHECK(s, a)) { \ |
331 | + TCGv src1l, TCGv src1h, | 440 | + static gen_helper_opivx *const fns[4] = { \ |
332 | + target_long shamt) | 441 | + gen_helper_##NAME##_b, \ |
442 | + gen_helper_##NAME##_h, \ | ||
443 | + gen_helper_##NAME##_w, \ | ||
444 | + gen_helper_##NAME##_d, \ | ||
445 | + }; \ | ||
446 | + return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \ | ||
447 | + } \ | ||
448 | + return false; \ | ||
449 | + } | ||
450 | + | ||
451 | +/* vandn.v[vx] */ | ||
452 | +GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvbb_vv_check) | ||
453 | +GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvbb_vx_check) | ||
454 | + | ||
455 | +#define GEN_OPIV_TRANS(NAME, CHECK) \ | ||
456 | + static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
457 | + { \ | ||
458 | + if (CHECK(s, a)) { \ | ||
459 | + uint32_t data = 0; \ | ||
460 | + static gen_helper_gvec_3_ptr *const fns[4] = { \ | ||
461 | + gen_helper_##NAME##_b, \ | ||
462 | + gen_helper_##NAME##_h, \ | ||
463 | + gen_helper_##NAME##_w, \ | ||
464 | + gen_helper_##NAME##_d, \ | ||
465 | + }; \ | ||
466 | + TCGLabel *over = gen_new_label(); \ | ||
467 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
468 | + \ | ||
469 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
470 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
471 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
472 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \ | ||
473 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
474 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
475 | + vreg_ofs(s, a->rs2), cpu_env, \ | ||
476 | + s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \ | ||
477 | + data, fns[s->sew]); \ | ||
478 | + mark_vs_dirty(s); \ | ||
479 | + gen_set_label(over); \ | ||
480 | + return true; \ | ||
481 | + } \ | ||
482 | + return false; \ | ||
483 | + } | ||
484 | + | ||
485 | +static bool zvbb_opiv_check(DisasContext *s, arg_rmr *a) | ||
333 | +{ | 486 | +{ |
334 | + if (shamt >= 64) { | 487 | + return s->cfg_ptr->ext_zvbb == true && |
335 | + tcg_gen_sari_tl(retl, src1h, shamt - 64); | 488 | + require_rvv(s) && |
336 | + tcg_gen_sari_tl(reth, src1h, 63); | 489 | + vext_check_isa_ill(s) && |
337 | + } else { | 490 | + vext_check_ss(s, a->rd, a->rs2, a->vm); |
338 | + tcg_gen_extract2_tl(retl, src1l, src1h, shamt); | ||
339 | + tcg_gen_sari_tl(reth, src1h, shamt); | ||
340 | + } | ||
341 | +} | 491 | +} |
342 | + | 492 | + |
343 | static bool trans_srai(DisasContext *ctx, arg_srai *a) | 493 | +GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check) |
344 | { | 494 | +GEN_OPIV_TRANS(vrev8_v, zvbb_opiv_check) |
345 | return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, | 495 | +GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check) |
346 | - tcg_gen_sari_tl, gen_sraiw); | 496 | +GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check) |
347 | + tcg_gen_sari_tl, gen_sraiw, gen_srai_i128); | 497 | +GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check) |
348 | } | 498 | +GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check) |
349 | 499 | + | |
350 | static bool trans_add(DisasContext *ctx, arg_add *a) | 500 | +static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a) |
351 | @@ -XXX,XX +XXX,XX @@ static bool trans_sub(DisasContext *ctx, arg_sub *a) | ||
352 | return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl); | ||
353 | } | ||
354 | |||
355 | +static void gen_sll_i128(TCGv destl, TCGv desth, | ||
356 | + TCGv src1l, TCGv src1h, TCGv shamt) | ||
357 | +{ | 501 | +{ |
358 | + TCGv ls = tcg_temp_new(); | 502 | + return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a); |
359 | + TCGv rs = tcg_temp_new(); | ||
360 | + TCGv hs = tcg_temp_new(); | ||
361 | + TCGv ll = tcg_temp_new(); | ||
362 | + TCGv lr = tcg_temp_new(); | ||
363 | + TCGv h0 = tcg_temp_new(); | ||
364 | + TCGv h1 = tcg_temp_new(); | ||
365 | + TCGv zero = tcg_constant_tl(0); | ||
366 | + | ||
367 | + tcg_gen_andi_tl(hs, shamt, 64); | ||
368 | + tcg_gen_andi_tl(ls, shamt, 63); | ||
369 | + tcg_gen_neg_tl(shamt, shamt); | ||
370 | + tcg_gen_andi_tl(rs, shamt, 63); | ||
371 | + | ||
372 | + tcg_gen_shl_tl(ll, src1l, ls); | ||
373 | + tcg_gen_shl_tl(h0, src1h, ls); | ||
374 | + tcg_gen_shr_tl(lr, src1l, rs); | ||
375 | + tcg_gen_movcond_tl(TCG_COND_NE, lr, shamt, zero, lr, zero); | ||
376 | + tcg_gen_or_tl(h1, h0, lr); | ||
377 | + | ||
378 | + tcg_gen_movcond_tl(TCG_COND_NE, destl, hs, zero, zero, ll); | ||
379 | + tcg_gen_movcond_tl(TCG_COND_NE, desth, hs, zero, ll, h1); | ||
380 | + | ||
381 | + tcg_temp_free(ls); | ||
382 | + tcg_temp_free(rs); | ||
383 | + tcg_temp_free(hs); | ||
384 | + tcg_temp_free(ll); | ||
385 | + tcg_temp_free(lr); | ||
386 | + tcg_temp_free(h0); | ||
387 | + tcg_temp_free(h1); | ||
388 | +} | 503 | +} |
389 | + | 504 | + |
390 | static bool trans_sll(DisasContext *ctx, arg_sll *a) | 505 | +static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a) |
391 | { | ||
392 | - return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl); | ||
393 | + return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl, gen_sll_i128); | ||
394 | } | ||
395 | |||
396 | static bool trans_slt(DisasContext *ctx, arg_slt *a) | ||
397 | @@ -XXX,XX +XXX,XX @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a) | ||
398 | return gen_arith(ctx, a, EXT_SIGN, gen_sltu); | ||
399 | } | ||
400 | |||
401 | +static void gen_srl_i128(TCGv destl, TCGv desth, | ||
402 | + TCGv src1l, TCGv src1h, TCGv shamt) | ||
403 | +{ | 506 | +{ |
404 | + TCGv ls = tcg_temp_new(); | 507 | + return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a); |
405 | + TCGv rs = tcg_temp_new(); | ||
406 | + TCGv hs = tcg_temp_new(); | ||
407 | + TCGv ll = tcg_temp_new(); | ||
408 | + TCGv lr = tcg_temp_new(); | ||
409 | + TCGv h0 = tcg_temp_new(); | ||
410 | + TCGv h1 = tcg_temp_new(); | ||
411 | + TCGv zero = tcg_constant_tl(0); | ||
412 | + | ||
413 | + tcg_gen_andi_tl(hs, shamt, 64); | ||
414 | + tcg_gen_andi_tl(rs, shamt, 63); | ||
415 | + tcg_gen_neg_tl(shamt, shamt); | ||
416 | + tcg_gen_andi_tl(ls, shamt, 63); | ||
417 | + | ||
418 | + tcg_gen_shr_tl(lr, src1l, rs); | ||
419 | + tcg_gen_shr_tl(h1, src1h, rs); | ||
420 | + tcg_gen_shl_tl(ll, src1h, ls); | ||
421 | + tcg_gen_movcond_tl(TCG_COND_NE, ll, shamt, zero, ll, zero); | ||
422 | + tcg_gen_or_tl(h0, ll, lr); | ||
423 | + | ||
424 | + tcg_gen_movcond_tl(TCG_COND_NE, destl, hs, zero, h1, h0); | ||
425 | + tcg_gen_movcond_tl(TCG_COND_NE, desth, hs, zero, zero, h1); | ||
426 | + | ||
427 | + tcg_temp_free(ls); | ||
428 | + tcg_temp_free(rs); | ||
429 | + tcg_temp_free(hs); | ||
430 | + tcg_temp_free(ll); | ||
431 | + tcg_temp_free(lr); | ||
432 | + tcg_temp_free(h0); | ||
433 | + tcg_temp_free(h1); | ||
434 | +} | 508 | +} |
435 | + | 509 | + |
436 | static bool trans_srl(DisasContext *ctx, arg_srl *a) | 510 | +/* OPIVI without GVEC IR */ |
437 | { | 511 | +#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \ |
438 | - return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl); | 512 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ |
439 | + return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl, gen_srl_i128); | 513 | + { \ |
440 | +} | 514 | + if (CHECK(s, a)) { \ |
441 | + | 515 | + static gen_helper_opivx *const fns[3] = { \ |
442 | +static void gen_sra_i128(TCGv destl, TCGv desth, | 516 | + gen_helper_##OPIVX##_b, \ |
443 | + TCGv src1l, TCGv src1h, TCGv shamt) | 517 | + gen_helper_##OPIVX##_h, \ |
444 | +{ | 518 | + gen_helper_##OPIVX##_w, \ |
445 | + TCGv ls = tcg_temp_new(); | 519 | + }; \ |
446 | + TCGv rs = tcg_temp_new(); | 520 | + return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \ |
447 | + TCGv hs = tcg_temp_new(); | 521 | + IMM_MODE); \ |
448 | + TCGv ll = tcg_temp_new(); | 522 | + } \ |
449 | + TCGv lr = tcg_temp_new(); | 523 | + return false; \ |
450 | + TCGv h0 = tcg_temp_new(); | 524 | + } |
451 | + TCGv h1 = tcg_temp_new(); | 525 | + |
452 | + TCGv zero = tcg_constant_tl(0); | 526 | +GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check) |
453 | + | 527 | +GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check) |
454 | + tcg_gen_andi_tl(hs, shamt, 64); | 528 | +GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check) |
455 | + tcg_gen_andi_tl(rs, shamt, 63); | ||
456 | + tcg_gen_neg_tl(shamt, shamt); | ||
457 | + tcg_gen_andi_tl(ls, shamt, 63); | ||
458 | + | ||
459 | + tcg_gen_shr_tl(lr, src1l, rs); | ||
460 | + tcg_gen_sar_tl(h1, src1h, rs); | ||
461 | + tcg_gen_shl_tl(ll, src1h, ls); | ||
462 | + tcg_gen_movcond_tl(TCG_COND_NE, ll, shamt, zero, ll, zero); | ||
463 | + tcg_gen_or_tl(h0, ll, lr); | ||
464 | + tcg_gen_sari_tl(lr, src1h, 63); | ||
465 | + | ||
466 | + tcg_gen_movcond_tl(TCG_COND_NE, destl, hs, zero, h1, h0); | ||
467 | + tcg_gen_movcond_tl(TCG_COND_NE, desth, hs, zero, lr, h1); | ||
468 | + | ||
469 | + tcg_temp_free(ls); | ||
470 | + tcg_temp_free(rs); | ||
471 | + tcg_temp_free(hs); | ||
472 | + tcg_temp_free(ll); | ||
473 | + tcg_temp_free(lr); | ||
474 | + tcg_temp_free(h0); | ||
475 | + tcg_temp_free(h1); | ||
476 | } | ||
477 | |||
478 | static bool trans_sra(DisasContext *ctx, arg_sra *a) | ||
479 | { | ||
480 | - return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl); | ||
481 | + return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, gen_sra_i128); | ||
482 | } | ||
483 | |||
484 | static bool trans_xor(DisasContext *ctx, arg_xor *a) | ||
485 | @@ -XXX,XX +XXX,XX @@ static bool trans_addiw(DisasContext *ctx, arg_addiw *a) | ||
486 | |||
487 | static bool trans_slliw(DisasContext *ctx, arg_slliw *a) | ||
488 | { | ||
489 | - REQUIRE_64BIT(ctx); | ||
490 | + REQUIRE_64_OR_128BIT(ctx); | ||
491 | ctx->ol = MXL_RV32; | ||
492 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl); | ||
493 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl, NULL); | ||
494 | } | ||
495 | |||
496 | static bool trans_srliw(DisasContext *ctx, arg_srliw *a) | ||
497 | { | ||
498 | - REQUIRE_64BIT(ctx); | ||
499 | + REQUIRE_64_OR_128BIT(ctx); | ||
500 | ctx->ol = MXL_RV32; | ||
501 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw); | ||
502 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw, NULL); | ||
503 | } | ||
504 | |||
505 | static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a) | ||
506 | { | ||
507 | - REQUIRE_64BIT(ctx); | ||
508 | + REQUIRE_64_OR_128BIT(ctx); | ||
509 | ctx->ol = MXL_RV32; | ||
510 | - return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw); | ||
511 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw, NULL); | ||
512 | +} | ||
513 | + | ||
514 | +static bool trans_sllid(DisasContext *ctx, arg_sllid *a) | ||
515 | +{ | ||
516 | + REQUIRE_128BIT(ctx); | ||
517 | + ctx->ol = MXL_RV64; | ||
518 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl, NULL); | ||
519 | +} | ||
520 | + | ||
521 | +static bool trans_srlid(DisasContext *ctx, arg_srlid *a) | ||
522 | +{ | ||
523 | + REQUIRE_128BIT(ctx); | ||
524 | + ctx->ol = MXL_RV64; | ||
525 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shri_tl, NULL); | ||
526 | +} | ||
527 | + | ||
528 | +static bool trans_sraid(DisasContext *ctx, arg_sraid *a) | ||
529 | +{ | ||
530 | + REQUIRE_128BIT(ctx); | ||
531 | + ctx->ol = MXL_RV64; | ||
532 | + return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_sari_tl, NULL); | ||
533 | } | ||
534 | |||
535 | static bool trans_addw(DisasContext *ctx, arg_addw *a) | ||
536 | @@ -XXX,XX +XXX,XX @@ static bool trans_subw(DisasContext *ctx, arg_subw *a) | ||
537 | |||
538 | static bool trans_sllw(DisasContext *ctx, arg_sllw *a) | ||
539 | { | ||
540 | - REQUIRE_64BIT(ctx); | ||
541 | + REQUIRE_64_OR_128BIT(ctx); | ||
542 | ctx->ol = MXL_RV32; | ||
543 | - return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl); | ||
544 | + return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl, NULL); | ||
545 | } | ||
546 | |||
547 | static bool trans_srlw(DisasContext *ctx, arg_srlw *a) | ||
548 | { | ||
549 | - REQUIRE_64BIT(ctx); | ||
550 | + REQUIRE_64_OR_128BIT(ctx); | ||
551 | ctx->ol = MXL_RV32; | ||
552 | - return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl); | ||
553 | + return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl, NULL); | ||
554 | } | ||
555 | |||
556 | static bool trans_sraw(DisasContext *ctx, arg_sraw *a) | ||
557 | { | ||
558 | - REQUIRE_64BIT(ctx); | ||
559 | + REQUIRE_64_OR_128BIT(ctx); | ||
560 | ctx->ol = MXL_RV32; | ||
561 | - return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl); | ||
562 | + return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL); | ||
563 | +} | ||
564 | + | ||
565 | +static bool trans_slld(DisasContext *ctx, arg_slld *a) | ||
566 | +{ | ||
567 | + REQUIRE_128BIT(ctx); | ||
568 | + ctx->ol = MXL_RV64; | ||
569 | + return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl, NULL); | ||
570 | } | ||
571 | |||
572 | +static bool trans_srld(DisasContext *ctx, arg_srld *a) | ||
573 | +{ | ||
574 | + REQUIRE_128BIT(ctx); | ||
575 | + ctx->ol = MXL_RV64; | ||
576 | + return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl, NULL); | ||
577 | +} | ||
578 | + | ||
579 | +static bool trans_srad(DisasContext *ctx, arg_srad *a) | ||
580 | +{ | ||
581 | + REQUIRE_128BIT(ctx); | ||
582 | + ctx->ol = MXL_RV64; | ||
583 | + return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL); | ||
584 | +} | ||
585 | + | ||
586 | + | ||
587 | static bool trans_fence(DisasContext *ctx, arg_fence *a) | ||
588 | { | ||
589 | /* FENCE is a full memory barrier. */ | ||
590 | -- | 529 | -- |
591 | 2.31.1 | 530 | 2.41.0 |
592 | |||
593 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
1 | 2 | ||
3 | This commit adds support for the Zvkned vector-crypto extension, which | ||
4 | consists of the following instructions: | ||
5 | |||
6 | * vaesef.[vv,vs] | ||
7 | * vaesdf.[vv,vs] | ||
8 | * vaesdm.[vv,vs] | ||
9 | * vaesz.vs | ||
10 | * vaesem.[vv,vs] | ||
11 | * vaeskf1.vi | ||
12 | * vaeskf2.vi | ||
13 | |||
14 | Translation functions are defined in | ||
15 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in | ||
16 | `target/riscv/vcrypto_helper.c`. | ||
17 | |||
18 | Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
19 | Co-authored-by: William Salmon <will.salmon@codethink.co.uk> | ||
20 | [max.chou@sifive.com: Replaced vstart checking by TCG op] | ||
21 | Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
22 | Signed-off-by: William Salmon <will.salmon@codethink.co.uk> | ||
23 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
24 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
25 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
26 | [max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned | ||
27 | property] | ||
28 | [max.chou@sifive.com: Fixed endian issues and replaced the vstart & vl | ||
29 | egs checking by helper function] | ||
30 | [max.chou@sifive.com: Replaced bswap32 calls in aes key expanding] | ||
31 | Message-ID: <20230711165917.2629866-10-max.chou@sifive.com> | ||
32 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
33 | --- | ||
34 | target/riscv/cpu_cfg.h | 1 + | ||
35 | target/riscv/helper.h | 14 ++ | ||
36 | target/riscv/insn32.decode | 14 ++ | ||
37 | target/riscv/cpu.c | 4 +- | ||
38 | target/riscv/vcrypto_helper.c | 202 +++++++++++++++++++++++ | ||
39 | target/riscv/insn_trans/trans_rvvk.c.inc | 147 +++++++++++++++++ | ||
40 | 6 files changed, 381 insertions(+), 1 deletion(-) | ||
41 | |||
42 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/target/riscv/cpu_cfg.h | ||
45 | +++ b/target/riscv/cpu_cfg.h | ||
46 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
47 | bool ext_zve64d; | ||
48 | bool ext_zvbb; | ||
49 | bool ext_zvbc; | ||
50 | + bool ext_zvkned; | ||
51 | bool ext_zmmul; | ||
52 | bool ext_zvfbfmin; | ||
53 | bool ext_zvfbfwma; | ||
54 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/target/riscv/helper.h | ||
57 | +++ b/target/riscv/helper.h | ||
58 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
59 | DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
60 | DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
61 | DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
62 | + | ||
63 | +DEF_HELPER_2(egs_check, void, i32, env) | ||
64 | + | ||
65 | +DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32) | ||
66 | +DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32) | ||
67 | +DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32) | ||
68 | +DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32) | ||
69 | +DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32) | ||
70 | +DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32) | ||
71 | +DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32) | ||
72 | +DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32) | ||
73 | +DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32) | ||
74 | +DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32) | ||
75 | +DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32) | ||
76 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/target/riscv/insn32.decode | ||
79 | +++ b/target/riscv/insn32.decode | ||
80 | @@ -XXX,XX +XXX,XX @@ | ||
81 | @r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd | ||
82 | @r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd | ||
83 | @r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd | ||
84 | +@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd | ||
85 | @r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd | ||
86 | @r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd | ||
87 | @r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd | ||
88 | @@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm | ||
89 | vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm | ||
90 | vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm | ||
91 | vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm | ||
92 | + | ||
93 | +# *** Zvkned vector crypto extension *** | ||
94 | +vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1 | ||
95 | +vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1 | ||
96 | +vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1 | ||
97 | +vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1 | ||
98 | +vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1 | ||
99 | +vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1 | ||
100 | +vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1 | ||
101 | +vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1 | ||
102 | +vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1 | ||
103 | +vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
104 | +vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
105 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
106 | index XXXXXXX..XXXXXXX 100644 | ||
107 | --- a/target/riscv/cpu.c | ||
108 | +++ b/target/riscv/cpu.c | ||
109 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
110 | ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma), | ||
111 | ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh), | ||
112 | ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin), | ||
113 | + ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned), | ||
114 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), | ||
115 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
116 | ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), | ||
117 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
118 | * In principle Zve*x would also suffice here, were they supported | ||
119 | * in qemu | ||
120 | */ | ||
121 | - if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) { | ||
122 | + if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) { | ||
123 | error_setg(errp, | ||
124 | "Vector crypto extensions require V or Zve* extensions"); | ||
125 | return; | ||
126 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
127 | /* Vector cryptography extensions */ | ||
128 | DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false), | ||
129 | DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), | ||
130 | + DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false), | ||
131 | |||
132 | DEFINE_PROP_END_OF_LIST(), | ||
133 | }; | ||
134 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
135 | index XXXXXXX..XXXXXXX 100644 | ||
136 | --- a/target/riscv/vcrypto_helper.c | ||
137 | +++ b/target/riscv/vcrypto_helper.c | ||
138 | @@ -XXX,XX +XXX,XX @@ | ||
139 | #include "qemu/bitops.h" | ||
140 | #include "qemu/bswap.h" | ||
141 | #include "cpu.h" | ||
142 | +#include "crypto/aes.h" | ||
143 | +#include "crypto/aes-round.h" | ||
144 | #include "exec/memop.h" | ||
145 | #include "exec/exec-all.h" | ||
146 | #include "exec/helper-proto.h" | ||
147 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL) | ||
148 | GEN_VEXT_VX(vwsll_vx_b, 2) | ||
149 | GEN_VEXT_VX(vwsll_vx_h, 4) | ||
150 | GEN_VEXT_VX(vwsll_vx_w, 8) | ||
151 | + | ||
152 | +void HELPER(egs_check)(uint32_t egs, CPURISCVState *env) | ||
153 | +{ | ||
154 | + uint32_t vl = env->vl; | ||
155 | + uint32_t vstart = env->vstart; | ||
156 | + | ||
157 | + if (vl % egs != 0 || vstart % egs != 0) { | ||
158 | + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); | ||
159 | + } | ||
160 | +} | ||
161 | + | ||
162 | +static inline void xor_round_key(AESState *round_state, AESState *round_key) | ||
163 | +{ | ||
164 | + round_state->v = round_state->v ^ round_key->v; | ||
165 | +} | ||
166 | + | ||
167 | +#define GEN_ZVKNED_HELPER_VV(NAME, ...) \ | ||
168 | + void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \ | ||
169 | + uint32_t desc) \ | ||
170 | + { \ | ||
171 | + uint32_t vl = env->vl; \ | ||
172 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); \ | ||
173 | + uint32_t vta = vext_vta(desc); \ | ||
174 | + \ | ||
175 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \ | ||
176 | + AESState round_key; \ | ||
177 | + round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \ | ||
178 | + round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \ | ||
179 | + AESState round_state; \ | ||
180 | + round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \ | ||
181 | + round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \ | ||
182 | + __VA_ARGS__; \ | ||
183 | + *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \ | ||
184 | + *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \ | ||
185 | + } \ | ||
186 | + env->vstart = 0; \ | ||
187 | + /* set tail elements to 1s */ \ | ||
188 | + vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \ | ||
189 | + } | ||
190 | + | ||
191 | +#define GEN_ZVKNED_HELPER_VS(NAME, ...) \ | ||
192 | + void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \ | ||
193 | + uint32_t desc) \ | ||
194 | + { \ | ||
195 | + uint32_t vl = env->vl; \ | ||
196 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); \ | ||
197 | + uint32_t vta = vext_vta(desc); \ | ||
198 | + \ | ||
199 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \ | ||
200 | + AESState round_key; \ | ||
201 | + round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \ | ||
202 | + round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \ | ||
203 | + AESState round_state; \ | ||
204 | + round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \ | ||
205 | + round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \ | ||
206 | + __VA_ARGS__; \ | ||
207 | + *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \ | ||
208 | + *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \ | ||
209 | + } \ | ||
210 | + env->vstart = 0; \ | ||
211 | + /* set tail elements to 1s */ \ | ||
212 | + vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \ | ||
213 | + } | ||
214 | + | ||
215 | +GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state, | ||
216 | + &round_state, | ||
217 | + &round_key, | ||
218 | + false);) | ||
219 | +GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state, | ||
220 | + &round_state, | ||
221 | + &round_key, | ||
222 | + false);) | ||
223 | +GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state, | ||
224 | + &round_state, | ||
225 | + &round_key, | ||
226 | + false);) | ||
227 | +GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state, | ||
228 | + &round_state, | ||
229 | + &round_key, | ||
230 | + false);) | ||
231 | +GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state, | ||
232 | + &round_state, | ||
233 | + &round_key, | ||
234 | + false);) | ||
235 | +GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state, | ||
236 | + &round_state, | ||
237 | + &round_key, | ||
238 | + false);) | ||
239 | +GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state, | ||
240 | + &round_state, | ||
241 | + &round_key, | ||
242 | + false);) | ||
243 | +GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state, | ||
244 | + &round_state, | ||
245 | + &round_key, | ||
246 | + false);) | ||
247 | +GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);) | ||
248 | + | ||
249 | +void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
250 | + CPURISCVState *env, uint32_t desc) | ||
251 | +{ | ||
252 | + uint32_t *vd = vd_vptr; | ||
253 | + uint32_t *vs2 = vs2_vptr; | ||
254 | + uint32_t vl = env->vl; | ||
255 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
256 | + uint32_t vta = vext_vta(desc); | ||
257 | + | ||
258 | + uimm &= 0b1111; | ||
259 | + if (uimm > 10 || uimm == 0) { | ||
260 | + uimm ^= 0b1000; | ||
261 | + } | ||
262 | + | ||
263 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
264 | + uint32_t rk[8], tmp; | ||
265 | + static const uint32_t rcon[] = { | ||
266 | + 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, | ||
267 | + 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036, | ||
268 | + }; | ||
269 | + | ||
270 | + rk[0] = vs2[i * 4 + H4(0)]; | ||
271 | + rk[1] = vs2[i * 4 + H4(1)]; | ||
272 | + rk[2] = vs2[i * 4 + H4(2)]; | ||
273 | + rk[3] = vs2[i * 4 + H4(3)]; | ||
274 | + tmp = ror32(rk[3], 8); | ||
275 | + | ||
276 | + rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) | | ||
277 | + ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) | | ||
278 | + ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) | | ||
279 | + ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0)) | ||
280 | + ^ rcon[uimm - 1]; | ||
281 | + rk[5] = rk[1] ^ rk[4]; | ||
282 | + rk[6] = rk[2] ^ rk[5]; | ||
283 | + rk[7] = rk[3] ^ rk[6]; | ||
284 | + | ||
285 | + vd[i * 4 + H4(0)] = rk[4]; | ||
286 | + vd[i * 4 + H4(1)] = rk[5]; | ||
287 | + vd[i * 4 + H4(2)] = rk[6]; | ||
288 | + vd[i * 4 + H4(3)] = rk[7]; | ||
289 | + } | ||
290 | + env->vstart = 0; | ||
291 | + /* set tail elements to 1s */ | ||
292 | + vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); | ||
293 | +} | ||
294 | + | ||
295 | +void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
296 | + CPURISCVState *env, uint32_t desc) | ||
297 | +{ | ||
298 | + uint32_t *vd = vd_vptr; | ||
299 | + uint32_t *vs2 = vs2_vptr; | ||
300 | + uint32_t vl = env->vl; | ||
301 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
302 | + uint32_t vta = vext_vta(desc); | ||
303 | + | ||
304 | + uimm &= 0b1111; | ||
305 | + if (uimm > 14 || uimm < 2) { | ||
306 | + uimm ^= 0b1000; | ||
307 | + } | ||
308 | + | ||
309 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
310 | + uint32_t rk[12], tmp; | ||
311 | + static const uint32_t rcon[] = { | ||
312 | + 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, | ||
313 | + 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036, | ||
314 | + }; | ||
315 | + | ||
316 | + rk[0] = vd[i * 4 + H4(0)]; | ||
317 | + rk[1] = vd[i * 4 + H4(1)]; | ||
318 | + rk[2] = vd[i * 4 + H4(2)]; | ||
319 | + rk[3] = vd[i * 4 + H4(3)]; | ||
320 | + rk[4] = vs2[i * 4 + H4(0)]; | ||
321 | + rk[5] = vs2[i * 4 + H4(1)]; | ||
322 | + rk[6] = vs2[i * 4 + H4(2)]; | ||
323 | + rk[7] = vs2[i * 4 + H4(3)]; | ||
324 | + | ||
325 | + if (uimm % 2 == 0) { | ||
326 | + tmp = ror32(rk[7], 8); | ||
327 | + rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) | | ||
328 | + ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) | | ||
329 | + ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) | | ||
330 | + ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0)) | ||
331 | + ^ rcon[(uimm - 1) / 2]; | ||
332 | + } else { | ||
333 | + rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) | | ||
334 | + ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) | | ||
335 | + ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) | | ||
336 | + ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0)); | ||
337 | + } | ||
338 | + rk[9] = rk[1] ^ rk[8]; | ||
339 | + rk[10] = rk[2] ^ rk[9]; | ||
340 | + rk[11] = rk[3] ^ rk[10]; | ||
341 | + | ||
342 | + vd[i * 4 + H4(0)] = rk[8]; | ||
343 | + vd[i * 4 + H4(1)] = rk[9]; | ||
344 | + vd[i * 4 + H4(2)] = rk[10]; | ||
345 | + vd[i * 4 + H4(3)] = rk[11]; | ||
346 | + } | ||
347 | + env->vstart = 0; | ||
348 | + /* set tail elements to 1s */ | ||
349 | + vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); | ||
350 | +} | ||
351 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
352 | index XXXXXXX..XXXXXXX 100644 | ||
353 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc | ||
354 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
355 | @@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a) | ||
356 | GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check) | ||
357 | GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check) | ||
358 | GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check) | ||
359 | + | ||
360 | +/* | ||
361 | + * Zvkned | ||
362 | + */ | ||
363 | + | ||
364 | +#define ZVKNED_EGS 4 | ||
365 | + | ||
366 | +#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \ | ||
367 | + static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \ | ||
368 | + { \ | ||
369 | + if (CHECK(s, a)) { \ | ||
370 | + TCGv_ptr rd_v, rs2_v; \ | ||
371 | + TCGv_i32 desc, egs; \ | ||
372 | + uint32_t data = 0; \ | ||
373 | + TCGLabel *over = gen_new_label(); \ | ||
374 | + \ | ||
375 | + if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \ | ||
376 | + /* save opcode for unwinding in case we throw an exception */ \ | ||
377 | + decode_save_opc(s); \ | ||
378 | + egs = tcg_constant_i32(EGS); \ | ||
379 | + gen_helper_egs_check(egs, cpu_env); \ | ||
380 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
381 | + } \ | ||
382 | + \ | ||
383 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
384 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
385 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
386 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \ | ||
387 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
388 | + rd_v = tcg_temp_new_ptr(); \ | ||
389 | + rs2_v = tcg_temp_new_ptr(); \ | ||
390 | + desc = tcg_constant_i32( \ | ||
391 | + simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \ | ||
392 | + tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \ | ||
393 | + tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \ | ||
394 | + gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \ | ||
395 | + mark_vs_dirty(s); \ | ||
396 | + gen_set_label(over); \ | ||
397 | + return true; \ | ||
398 | + } \ | ||
399 | + return false; \ | ||
400 | + } | ||
401 | + | ||
402 | +static bool vaes_check_vv(DisasContext *s, arg_rmr *a) | ||
403 | +{ | ||
404 | + int egw_bytes = ZVKNED_EGS << s->sew; | ||
405 | + return s->cfg_ptr->ext_zvkned == true && | ||
406 | + require_rvv(s) && | ||
407 | + vext_check_isa_ill(s) && | ||
408 | + MAXSZ(s) >= egw_bytes && | ||
409 | + require_align(a->rd, s->lmul) && | ||
410 | + require_align(a->rs2, s->lmul) && | ||
411 | + s->sew == MO_32; | ||
412 | +} | ||
413 | + | ||
414 | +static bool vaes_check_overlap(DisasContext *s, int vd, int vs2) | ||
415 | +{ | ||
416 | + int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul; | ||
417 | + return !is_overlapped(vd, op_size, vs2, 1); | ||
418 | +} | ||
419 | + | ||
420 | +static bool vaes_check_vs(DisasContext *s, arg_rmr *a) | ||
421 | +{ | ||
422 | + int egw_bytes = ZVKNED_EGS << s->sew; | ||
423 | + return vaes_check_overlap(s, a->rd, a->rs2) && | ||
424 | + MAXSZ(s) >= egw_bytes && | ||
425 | + s->cfg_ptr->ext_zvkned == true && | ||
426 | + require_rvv(s) && | ||
427 | + vext_check_isa_ill(s) && | ||
428 | + require_align(a->rd, s->lmul) && | ||
429 | + s->sew == MO_32; | ||
430 | +} | ||
431 | + | ||
432 | +GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS) | ||
433 | +GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS) | ||
434 | +GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS) | ||
435 | +GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS) | ||
436 | +GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS) | ||
437 | +GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS) | ||
438 | +GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS) | ||
439 | +GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS) | ||
440 | +GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS) | ||
441 | + | ||
442 | +#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS) \ | ||
443 | + static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \ | ||
444 | + { \ | ||
445 | + if (CHECK(s, a)) { \ | ||
446 | + TCGv_ptr rd_v, rs2_v; \ | ||
447 | + TCGv_i32 uimm_v, desc, egs; \ | ||
448 | + uint32_t data = 0; \ | ||
449 | + TCGLabel *over = gen_new_label(); \ | ||
450 | + \ | ||
451 | + if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \ | ||
452 | + /* save opcode for unwinding in case we throw an exception */ \ | ||
453 | + decode_save_opc(s); \ | ||
454 | + egs = tcg_constant_i32(EGS); \ | ||
455 | + gen_helper_egs_check(egs, cpu_env); \ | ||
456 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ | ||
457 | + } \ | ||
458 | + \ | ||
459 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
460 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
461 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
462 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \ | ||
463 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
464 | + \ | ||
465 | + rd_v = tcg_temp_new_ptr(); \ | ||
466 | + rs2_v = tcg_temp_new_ptr(); \ | ||
467 | + uimm_v = tcg_constant_i32(a->rs1); \ | ||
468 | + desc = tcg_constant_i32( \ | ||
469 | + simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \ | ||
470 | + tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \ | ||
471 | + tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \ | ||
472 | + gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc); \ | ||
473 | + mark_vs_dirty(s); \ | ||
474 | + gen_set_label(over); \ | ||
475 | + return true; \ | ||
476 | + } \ | ||
477 | + return false; \ | ||
478 | + } | ||
479 | + | ||
480 | +static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a) | ||
481 | +{ | ||
482 | + int egw_bytes = ZVKNED_EGS << s->sew; | ||
483 | + return s->cfg_ptr->ext_zvkned == true && | ||
484 | + require_rvv(s) && | ||
485 | + vext_check_isa_ill(s) && | ||
486 | + MAXSZ(s) >= egw_bytes && | ||
487 | + s->sew == MO_32 && | ||
488 | + require_align(a->rd, s->lmul) && | ||
489 | + require_align(a->rs2, s->lmul); | ||
490 | +} | ||
491 | + | ||
492 | +static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a) | ||
493 | +{ | ||
494 | + int egw_bytes = ZVKNED_EGS << s->sew; | ||
495 | + return s->cfg_ptr->ext_zvkned == true && | ||
496 | + require_rvv(s) && | ||
497 | + vext_check_isa_ill(s) && | ||
498 | + MAXSZ(s) >= egw_bytes && | ||
499 | + s->sew == MO_32 && | ||
500 | + require_align(a->rd, s->lmul) && | ||
501 | + require_align(a->rs2, s->lmul); | ||
502 | +} | ||
503 | + | ||
504 | +GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS) | ||
505 | +GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS) | ||
506 | -- | ||
507 | 2.41.0 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | Get function to retrieve the 64 top bits of a register, stored in the gprh | 3 | This commit adds support for the Zvknh vector-crypto extension, which |
4 | field of the cpu state. Set function that writes the 128-bit value at once. | 4 | consists of the following instructions: |
5 | The access to the gprh field can not be protected at compile time to make | ||
6 | sure it is accessed only in the 128-bit version of the processor because we | ||
7 | have no way to indicate that the misa_mxl_max field is const. | ||
8 | 5 | ||
9 | The 128-bit ISA adds ldu, lq and sq. We provide support for these | 6 | * vsha2ms.vv |
10 | instructions. Note that (a) we compute only 64-bit addresses to actually | 7 | * vsha2c[hl].vv |
11 | access memory, cowardly utilizing the existing address translation mechanism | ||
12 | of QEMU, and (b) we assume for now little-endian memory accesses. | ||
13 | 8 | ||
14 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 9 | Translation functions are defined in |
15 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 10 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in |
16 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | `target/riscv/vcrypto_helper.c`. |
17 | Message-id: 20220106210108.138226-10-frederic.petrot@univ-grenoble-alpes.fr | 12 | |
13 | Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
14 | Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
15 | [max.chou@sifive.com: Replaced vstart checking by TCG op] | ||
16 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
17 | Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
18 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> | ||
19 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
20 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
21 | [max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties] | ||
22 | [max.chou@sifive.com: Replaced SEW selection to happened during | ||
23 | translation] | ||
24 | Message-ID: <20230711165917.2629866-11-max.chou@sifive.com> | ||
18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
19 | --- | 26 | --- |
20 | target/riscv/insn16.decode | 27 ++++++- | 27 | target/riscv/cpu_cfg.h | 2 + |
21 | target/riscv/insn32.decode | 5 ++ | 28 | target/riscv/helper.h | 6 + |
22 | target/riscv/translate.c | 41 ++++++++++ | 29 | target/riscv/insn32.decode | 5 + |
23 | target/riscv/insn_trans/trans_rvi.c.inc | 100 ++++++++++++++++++++++-- | 30 | target/riscv/cpu.c | 13 +- |
24 | 4 files changed, 163 insertions(+), 10 deletions(-) | 31 | target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++ |
32 | target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++ | ||
33 | 6 files changed, 390 insertions(+), 3 deletions(-) | ||
25 | 34 | ||
26 | diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode | 35 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h |
27 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/target/riscv/insn16.decode | 37 | --- a/target/riscv/cpu_cfg.h |
29 | +++ b/target/riscv/insn16.decode | 38 | +++ b/target/riscv/cpu_cfg.h |
30 | @@ -XXX,XX +XXX,XX @@ | 39 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { |
31 | # Immediates: | 40 | bool ext_zvbb; |
32 | %imm_ci 12:s1 2:5 | 41 | bool ext_zvbc; |
33 | %nzuimm_ciw 7:4 11:2 5:1 6:1 !function=ex_shift_2 | 42 | bool ext_zvkned; |
34 | +%uimm_cl_q 10:1 5:2 11:2 !function=ex_shift_4 | 43 | + bool ext_zvknha; |
35 | %uimm_cl_d 5:2 10:3 !function=ex_shift_3 | 44 | + bool ext_zvknhb; |
36 | %uimm_cl_w 5:1 10:3 6:1 !function=ex_shift_2 | 45 | bool ext_zmmul; |
37 | %imm_cb 12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1 | 46 | bool ext_zvfbfmin; |
38 | %imm_cj 12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1 | 47 | bool ext_zvfbfwma; |
39 | 48 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | |
40 | %shimm_6bit 12:1 2:5 !function=ex_rvc_shifti | 49 | index XXXXXXX..XXXXXXX 100644 |
41 | +%uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4 | 50 | --- a/target/riscv/helper.h |
42 | %uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3 | 51 | +++ b/target/riscv/helper.h |
43 | %uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2 | 52 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32) |
44 | +%uimm_6bit_sq 7:4 11:2 !function=ex_shift_4 | 53 | DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32) |
45 | %uimm_6bit_sd 7:3 10:3 !function=ex_shift_3 | 54 | DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32) |
46 | %uimm_6bit_sw 7:2 9:4 !function=ex_shift_2 | 55 | DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32) |
47 | 56 | + | |
48 | @@ -XXX,XX +XXX,XX @@ | 57 | +DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32) |
49 | # Formats 16: | 58 | +DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32) |
50 | @cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd | 59 | +DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32) |
51 | @ci ... . ..... ..... .. &i imm=%imm_ci rs1=%rd %rd | 60 | +DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32) |
52 | +@cl_q ... . ..... ..... .. &i imm=%uimm_cl_q rs1=%rs1_3 rd=%rs2_3 | 61 | +DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32) |
53 | @cl_d ... ... ... .. ... .. &i imm=%uimm_cl_d rs1=%rs1_3 rd=%rs2_3 | ||
54 | @cl_w ... ... ... .. ... .. &i imm=%uimm_cl_w rs1=%rs1_3 rd=%rs2_3 | ||
55 | @cs_2 ... ... ... .. ... .. &r rs2=%rs2_3 rs1=%rs1_3 rd=%rs1_3 | ||
56 | +@cs_q ... ... ... .. ... .. &s imm=%uimm_cl_q rs1=%rs1_3 rs2=%rs2_3 | ||
57 | @cs_d ... ... ... .. ... .. &s imm=%uimm_cl_d rs1=%rs1_3 rs2=%rs2_3 | ||
58 | @cs_w ... ... ... .. ... .. &s imm=%uimm_cl_w rs1=%rs1_3 rs2=%rs2_3 | ||
59 | @cj ... ........... .. &j imm=%imm_cj | ||
60 | @cb_z ... ... ... .. ... .. &b imm=%imm_cb rs1=%rs1_3 rs2=0 | ||
61 | |||
62 | +@c_lqsp ... . ..... ..... .. &i imm=%uimm_6bit_lq rs1=2 %rd | ||
63 | @c_ldsp ... . ..... ..... .. &i imm=%uimm_6bit_ld rs1=2 %rd | ||
64 | @c_lwsp ... . ..... ..... .. &i imm=%uimm_6bit_lw rs1=2 %rd | ||
65 | +@c_sqsp ... . ..... ..... .. &s imm=%uimm_6bit_sq rs1=2 rs2=%rs2_5 | ||
66 | @c_sdsp ... . ..... ..... .. &s imm=%uimm_6bit_sd rs1=2 rs2=%rs2_5 | ||
67 | @c_swsp ... . ..... ..... .. &s imm=%uimm_6bit_sw rs1=2 rs2=%rs2_5 | ||
68 | @c_li ... . ..... ..... .. &i imm=%imm_ci rs1=0 %rd | ||
69 | @@ -XXX,XX +XXX,XX @@ | ||
70 | illegal 000 000 000 00 --- 00 | ||
71 | addi 000 ... ... .. ... 00 @c_addi4spn | ||
72 | } | ||
73 | -fld 001 ... ... .. ... 00 @cl_d | ||
74 | +{ | ||
75 | + lq 001 ... ... .. ... 00 @cl_q | ||
76 | + fld 001 ... ... .. ... 00 @cl_d | ||
77 | +} | ||
78 | lw 010 ... ... .. ... 00 @cl_w | ||
79 | -fsd 101 ... ... .. ... 00 @cs_d | ||
80 | +{ | ||
81 | + sq 101 ... ... .. ... 00 @cs_q | ||
82 | + fsd 101 ... ... .. ... 00 @cs_d | ||
83 | +} | ||
84 | sw 110 ... ... .. ... 00 @cs_w | ||
85 | |||
86 | # *** RV32C and RV64C specific Standard Extension (Quadrant 0) *** | ||
87 | @@ -XXX,XX +XXX,XX @@ addw 100 1 11 ... 01 ... 01 @cs_2 | ||
88 | |||
89 | # *** RV32/64C Standard Extension (Quadrant 2) *** | ||
90 | slli 000 . ..... ..... 10 @c_shift2 | ||
91 | -fld 001 . ..... ..... 10 @c_ldsp | ||
92 | +{ | ||
93 | + lq 001 ... ... .. ... 10 @c_lqsp | ||
94 | + fld 001 . ..... ..... 10 @c_ldsp | ||
95 | +} | ||
96 | { | ||
97 | illegal 010 - 00000 ----- 10 # c.lwsp, RES rd=0 | ||
98 | lw 010 . ..... ..... 10 @c_lwsp | ||
99 | @@ -XXX,XX +XXX,XX @@ fld 001 . ..... ..... 10 @c_ldsp | ||
100 | jalr 100 1 ..... 00000 10 @c_jalr rd=1 # C.JALR | ||
101 | add 100 1 ..... ..... 10 @cr | ||
102 | } | ||
103 | -fsd 101 ...... ..... 10 @c_sdsp | ||
104 | +{ | ||
105 | + sq 101 ... ... .. ... 10 @c_sqsp | ||
106 | + fsd 101 ...... ..... 10 @c_sdsp | ||
107 | +} | ||
108 | sw 110 . ..... ..... 10 @c_swsp | ||
109 | |||
110 | # *** RV32C and RV64C specific Standard Extension (Quadrant 2) *** | ||
111 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 62 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode |
112 | index XXXXXXX..XXXXXXX 100644 | 63 | index XXXXXXX..XXXXXXX 100644 |
113 | --- a/target/riscv/insn32.decode | 64 | --- a/target/riscv/insn32.decode |
114 | +++ b/target/riscv/insn32.decode | 65 | +++ b/target/riscv/insn32.decode |
115 | @@ -XXX,XX +XXX,XX @@ sllw 0000000 ..... ..... 001 ..... 0111011 @r | 66 | @@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1 |
116 | srlw 0000000 ..... ..... 101 ..... 0111011 @r | 67 | vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1 |
117 | sraw 0100000 ..... ..... 101 ..... 0111011 @r | 68 | vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
118 | 69 | vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1 | |
119 | +# *** RV128I Base Instruction Set (in addition to RV64I) *** | 70 | + |
120 | +ldu ............ ..... 111 ..... 0000011 @i | 71 | +# *** Zvknh vector crypto extension *** |
121 | +lq ............ ..... 010 ..... 0001111 @i | 72 | +vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
122 | +sq ............ ..... 100 ..... 0100011 @s | 73 | +vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
123 | + | 74 | +vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
124 | # *** RV32M Standard Extension *** | 75 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
125 | mul 0000001 ..... ..... 000 ..... 0110011 @r | ||
126 | mulh 0000001 ..... ..... 001 ..... 0110011 @r | ||
127 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
128 | index XXXXXXX..XXXXXXX 100644 | 76 | index XXXXXXX..XXXXXXX 100644 |
129 | --- a/target/riscv/translate.c | 77 | --- a/target/riscv/cpu.c |
130 | +++ b/target/riscv/translate.c | 78 | +++ b/target/riscv/cpu.c |
131 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | 79 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
132 | /* pc_succ_insn points to the instruction following base.pc_next */ | 80 | ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh), |
133 | target_ulong pc_succ_insn; | 81 | ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin), |
134 | target_ulong priv_ver; | 82 | ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned), |
135 | + RISCVMXL misa_mxl_max; | 83 | + ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha), |
136 | RISCVMXL xl; | 84 | + ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb), |
137 | uint32_t misa_ext; | 85 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), |
138 | uint32_t opcode; | 86 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), |
139 | @@ -XXX,XX +XXX,XX @@ static inline int get_olen(DisasContext *ctx) | 87 | ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), |
140 | return 16 << get_ol(ctx); | 88 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
89 | * In principle Zve*x would also suffice here, were they supported | ||
90 | * in qemu | ||
91 | */ | ||
92 | - if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) { | ||
93 | + if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) && | ||
94 | + !cpu->cfg.ext_zve32f) { | ||
95 | error_setg(errp, | ||
96 | "Vector crypto extensions require V or Zve* extensions"); | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | - if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) { | ||
101 | - error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions"); | ||
102 | + if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) { | ||
103 | + error_setg( | ||
104 | + errp, | ||
105 | + "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions"); | ||
106 | return; | ||
107 | } | ||
108 | |||
109 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
110 | DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false), | ||
111 | DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), | ||
112 | DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false), | ||
113 | + DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false), | ||
114 | + DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false), | ||
115 | |||
116 | DEFINE_PROP_END_OF_LIST(), | ||
117 | }; | ||
118 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
119 | index XXXXXXX..XXXXXXX 100644 | ||
120 | --- a/target/riscv/vcrypto_helper.c | ||
121 | +++ b/target/riscv/vcrypto_helper.c | ||
122 | @@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
123 | /* set tail elements to 1s */ | ||
124 | vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); | ||
141 | } | 125 | } |
142 | 126 | + | |
143 | +/* The maximum register length */ | 127 | +static inline uint32_t sig0_sha256(uint32_t x) |
144 | +#ifdef TARGET_RISCV32 | 128 | +{ |
145 | +#define get_xl_max(ctx) MXL_RV32 | 129 | + return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3); |
146 | +#else | 130 | +} |
147 | +#define get_xl_max(ctx) ((ctx)->misa_mxl_max) | 131 | + |
148 | +#endif | 132 | +static inline uint32_t sig1_sha256(uint32_t x) |
149 | + | 133 | +{ |
150 | /* | 134 | + return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10); |
151 | * RISC-V requires NaN-boxing of narrower width floating point values. | 135 | +} |
152 | * This applies when a 32-bit value is assigned to a 64-bit FP register. | 136 | + |
153 | @@ -XXX,XX +XXX,XX @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext) | 137 | +static inline uint64_t sig0_sha512(uint64_t x) |
154 | } | 138 | +{ |
155 | break; | 139 | + return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7); |
156 | case MXL_RV64: | 140 | +} |
157 | + case MXL_RV128: | 141 | + |
158 | break; | 142 | +static inline uint64_t sig1_sha512(uint64_t x) |
159 | default: | 143 | +{ |
160 | g_assert_not_reached(); | 144 | + return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6); |
161 | @@ -XXX,XX +XXX,XX @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext) | 145 | +} |
162 | return cpu_gpr[reg_num]; | 146 | + |
163 | } | 147 | +static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2) |
164 | 148 | +{ | |
165 | +static TCGv get_gprh(DisasContext *ctx, int reg_num) | 149 | + uint32_t res[4]; |
166 | +{ | 150 | + res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) + |
167 | + assert(get_xl(ctx) == MXL_RV128); | 151 | + vd[H4(0)]; |
168 | + if (reg_num == 0) { | 152 | + res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) + |
169 | + return ctx->zero; | 153 | + vd[H4(1)]; |
170 | + } | 154 | + res[2] = |
171 | + return cpu_gprh[reg_num]; | 155 | + sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)]; |
172 | +} | 156 | + res[3] = |
173 | + | 157 | + sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)]; |
174 | static TCGv dest_gpr(DisasContext *ctx, int reg_num) | 158 | + vd[H4(3)] = res[3]; |
175 | { | 159 | + vd[H4(2)] = res[2]; |
176 | if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) { | 160 | + vd[H4(1)] = res[1]; |
177 | @@ -XXX,XX +XXX,XX @@ static TCGv dest_gpr(DisasContext *ctx, int reg_num) | 161 | + vd[H4(0)] = res[0]; |
178 | return cpu_gpr[reg_num]; | 162 | +} |
179 | } | 163 | + |
180 | 164 | +static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2) | |
181 | +static TCGv dest_gprh(DisasContext *ctx, int reg_num) | 165 | +{ |
182 | +{ | 166 | + uint64_t res[4]; |
183 | + if (reg_num == 0) { | 167 | + res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0]; |
184 | + return temp_new(ctx); | 168 | + res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1]; |
185 | + } | 169 | + res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2]; |
186 | + return cpu_gprh[reg_num]; | 170 | + res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3]; |
187 | +} | 171 | + vd[3] = res[3]; |
188 | + | 172 | + vd[2] = res[2]; |
189 | static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t) | 173 | + vd[1] = res[1]; |
190 | { | 174 | + vd[0] = res[0]; |
191 | if (reg_num != 0) { | 175 | +} |
192 | @@ -XXX,XX +XXX,XX @@ static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t) | 176 | + |
193 | tcg_gen_ext32s_tl(cpu_gpr[reg_num], t); | 177 | +void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, |
194 | break; | 178 | + uint32_t desc) |
195 | case MXL_RV64: | 179 | +{ |
196 | + case MXL_RV128: | 180 | + uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW); |
197 | tcg_gen_mov_tl(cpu_gpr[reg_num], t); | 181 | + uint32_t esz = sew == MO_32 ? 4 : 8; |
198 | break; | 182 | + uint32_t total_elems; |
199 | default: | 183 | + uint32_t vta = vext_vta(desc); |
200 | g_assert_not_reached(); | 184 | + |
201 | } | 185 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { |
202 | + | 186 | + if (sew == MO_32) { |
203 | + if (get_xl_max(ctx) == MXL_RV128) { | 187 | + vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4, |
204 | + tcg_gen_sari_tl(cpu_gprh[reg_num], cpu_gpr[reg_num], 63); | 188 | + ((uint32_t *)vs2) + i * 4); |
189 | + } else { | ||
190 | + /* If not 32 then SEW should be 64 */ | ||
191 | + vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4, | ||
192 | + ((uint64_t *)vs2) + i * 4); | ||
205 | + } | 193 | + } |
206 | + } | 194 | + } |
207 | +} | 195 | + /* set tail elements to 1s */ |
208 | + | 196 | + total_elems = vext_get_total_elems(env, desc, esz); |
209 | +static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh) | 197 | + vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); |
210 | +{ | 198 | + env->vstart = 0; |
211 | + assert(get_ol(ctx) == MXL_RV128); | 199 | +} |
212 | + if (reg_num != 0) { | 200 | + |
213 | + tcg_gen_mov_tl(cpu_gpr[reg_num], rl); | 201 | +static inline uint64_t sum0_64(uint64_t x) |
214 | + tcg_gen_mov_tl(cpu_gprh[reg_num], rh); | 202 | +{ |
215 | } | 203 | + return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39); |
216 | } | 204 | +} |
217 | 205 | + | |
218 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | 206 | +static inline uint32_t sum0_32(uint32_t x) |
219 | ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3); | 207 | +{ |
220 | ctx->vstart = env->vstart; | 208 | + return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22); |
221 | ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); | 209 | +} |
222 | + ctx->misa_mxl_max = env->misa_mxl_max; | 210 | + |
223 | ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); | 211 | +static inline uint64_t sum1_64(uint64_t x) |
224 | ctx->cs = cs; | 212 | +{ |
225 | ctx->ntemp = 0; | 213 | + return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41); |
226 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | 214 | +} |
215 | + | ||
216 | +static inline uint32_t sum1_32(uint32_t x) | ||
217 | +{ | ||
218 | + return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25); | ||
219 | +} | ||
220 | + | ||
221 | +#define ch(x, y, z) ((x & y) ^ ((~x) & z)) | ||
222 | + | ||
223 | +#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
224 | + | ||
225 | +static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1) | ||
226 | +{ | ||
227 | + uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0]; | ||
228 | + uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0]; | ||
229 | + uint64_t W0 = vs1[0], W1 = vs1[1]; | ||
230 | + uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0; | ||
231 | + uint64_t T2 = sum0_64(a) + maj(a, b, c); | ||
232 | + | ||
233 | + h = g; | ||
234 | + g = f; | ||
235 | + f = e; | ||
236 | + e = d + T1; | ||
237 | + d = c; | ||
238 | + c = b; | ||
239 | + b = a; | ||
240 | + a = T1 + T2; | ||
241 | + | ||
242 | + T1 = h + sum1_64(e) + ch(e, f, g) + W1; | ||
243 | + T2 = sum0_64(a) + maj(a, b, c); | ||
244 | + h = g; | ||
245 | + g = f; | ||
246 | + f = e; | ||
247 | + e = d + T1; | ||
248 | + d = c; | ||
249 | + c = b; | ||
250 | + b = a; | ||
251 | + a = T1 + T2; | ||
252 | + | ||
253 | + vd[0] = f; | ||
254 | + vd[1] = e; | ||
255 | + vd[2] = b; | ||
256 | + vd[3] = a; | ||
257 | +} | ||
258 | + | ||
259 | +static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1) | ||
260 | +{ | ||
261 | + uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)]; | ||
262 | + uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)]; | ||
263 | + uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)]; | ||
264 | + uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0; | ||
265 | + uint32_t T2 = sum0_32(a) + maj(a, b, c); | ||
266 | + | ||
267 | + h = g; | ||
268 | + g = f; | ||
269 | + f = e; | ||
270 | + e = d + T1; | ||
271 | + d = c; | ||
272 | + c = b; | ||
273 | + b = a; | ||
274 | + a = T1 + T2; | ||
275 | + | ||
276 | + T1 = h + sum1_32(e) + ch(e, f, g) + W1; | ||
277 | + T2 = sum0_32(a) + maj(a, b, c); | ||
278 | + h = g; | ||
279 | + g = f; | ||
280 | + f = e; | ||
281 | + e = d + T1; | ||
282 | + d = c; | ||
283 | + c = b; | ||
284 | + b = a; | ||
285 | + a = T1 + T2; | ||
286 | + | ||
287 | + vd[H4(0)] = f; | ||
288 | + vd[H4(1)] = e; | ||
289 | + vd[H4(2)] = b; | ||
290 | + vd[H4(3)] = a; | ||
291 | +} | ||
292 | + | ||
293 | +void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
294 | + uint32_t desc) | ||
295 | +{ | ||
296 | + const uint32_t esz = 4; | ||
297 | + uint32_t total_elems; | ||
298 | + uint32_t vta = vext_vta(desc); | ||
299 | + | ||
300 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
301 | + vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i, | ||
302 | + ((uint32_t *)vs1) + 4 * i + 2); | ||
303 | + } | ||
304 | + | ||
305 | + /* set tail elements to 1s */ | ||
306 | + total_elems = vext_get_total_elems(env, desc, esz); | ||
307 | + vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); | ||
308 | + env->vstart = 0; | ||
309 | +} | ||
310 | + | ||
311 | +void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
312 | + uint32_t desc) | ||
313 | +{ | ||
314 | + const uint32_t esz = 8; | ||
315 | + uint32_t total_elems; | ||
316 | + uint32_t vta = vext_vta(desc); | ||
317 | + | ||
318 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
319 | + vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i, | ||
320 | + ((uint64_t *)vs1) + 4 * i + 2); | ||
321 | + } | ||
322 | + | ||
323 | + /* set tail elements to 1s */ | ||
324 | + total_elems = vext_get_total_elems(env, desc, esz); | ||
325 | + vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); | ||
326 | + env->vstart = 0; | ||
327 | +} | ||
328 | + | ||
329 | +void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
330 | + uint32_t desc) | ||
331 | +{ | ||
332 | + const uint32_t esz = 4; | ||
333 | + uint32_t total_elems; | ||
334 | + uint32_t vta = vext_vta(desc); | ||
335 | + | ||
336 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
337 | + vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i, | ||
338 | + (((uint32_t *)vs1) + 4 * i)); | ||
339 | + } | ||
340 | + | ||
341 | + /* set tail elements to 1s */ | ||
342 | + total_elems = vext_get_total_elems(env, desc, esz); | ||
343 | + vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); | ||
344 | + env->vstart = 0; | ||
345 | +} | ||
346 | + | ||
347 | +void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
348 | + uint32_t desc) | ||
349 | +{ | ||
350 | + uint32_t esz = 8; | ||
351 | + uint32_t total_elems; | ||
352 | + uint32_t vta = vext_vta(desc); | ||
353 | + | ||
354 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
355 | + vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i, | ||
356 | + (((uint64_t *)vs1) + 4 * i)); | ||
357 | + } | ||
358 | + | ||
359 | + /* set tail elements to 1s */ | ||
360 | + total_elems = vext_get_total_elems(env, desc, esz); | ||
361 | + vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); | ||
362 | + env->vstart = 0; | ||
363 | +} | ||
364 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
227 | index XXXXXXX..XXXXXXX 100644 | 365 | index XXXXXXX..XXXXXXX 100644 |
228 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | 366 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc |
229 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | 367 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc |
230 | @@ -XXX,XX +XXX,XX @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) | 368 | @@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a) |
231 | return gen_branch(ctx, a, TCG_COND_GEU); | 369 | |
232 | } | 370 | GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS) |
233 | 371 | GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS) | |
234 | -static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) | 372 | + |
235 | +static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop) | 373 | +/* |
236 | { | 374 | + * Zvknh |
237 | TCGv dest = dest_gpr(ctx, a->rd); | 375 | + */ |
238 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | 376 | + |
239 | @@ -XXX,XX +XXX,XX @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) | 377 | +#define ZVKNH_EGS 4 |
240 | return true; | 378 | + |
241 | } | 379 | +#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \ |
242 | 380 | + static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | |
243 | +/* Compute only 64-bit addresses to use the address translation mechanism */ | 381 | + { \ |
244 | +static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop) | 382 | + if (CHECK(s, a)) { \ |
245 | +{ | 383 | + uint32_t data = 0; \ |
246 | + TCGv src1l = get_gpr(ctx, a->rs1, EXT_NONE); | 384 | + TCGLabel *over = gen_new_label(); \ |
247 | + TCGv destl = dest_gpr(ctx, a->rd); | 385 | + TCGv_i32 egs; \ |
248 | + TCGv desth = dest_gprh(ctx, a->rd); | 386 | + \ |
249 | + TCGv addrl = tcg_temp_new(); | 387 | + if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \ |
250 | + | 388 | + /* save opcode for unwinding in case we throw an exception */ \ |
251 | + tcg_gen_addi_tl(addrl, src1l, a->imm); | 389 | + decode_save_opc(s); \ |
252 | + | 390 | + egs = tcg_constant_i32(EGS); \ |
253 | + if ((memop & MO_SIZE) <= MO_64) { | 391 | + gen_helper_egs_check(egs, cpu_env); \ |
254 | + tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, memop); | 392 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \ |
255 | + if (memop & MO_SIGN) { | 393 | + } \ |
256 | + tcg_gen_sari_tl(desth, destl, 63); | 394 | + \ |
257 | + } else { | 395 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ |
258 | + tcg_gen_movi_tl(desth, 0); | 396 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ |
397 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
398 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \ | ||
399 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
400 | + \ | ||
401 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \ | ||
402 | + vreg_ofs(s, a->rs2), cpu_env, \ | ||
403 | + s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \ | ||
404 | + data, gen_helper_##NAME); \ | ||
405 | + \ | ||
406 | + mark_vs_dirty(s); \ | ||
407 | + gen_set_label(over); \ | ||
408 | + return true; \ | ||
409 | + } \ | ||
410 | + return false; \ | ||
411 | + } | ||
412 | + | ||
413 | +static bool vsha_check_sew(DisasContext *s) | ||
414 | +{ | ||
415 | + return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) || | ||
416 | + (s->cfg_ptr->ext_zvknhb == true && | ||
417 | + (s->sew == MO_32 || s->sew == MO_64)); | ||
418 | +} | ||
419 | + | ||
420 | +static bool vsha_check(DisasContext *s, arg_rmrr *a) | ||
421 | +{ | ||
422 | + int egw_bytes = ZVKNH_EGS << s->sew; | ||
423 | + int mult = 1 << MAX(s->lmul, 0); | ||
424 | + return opivv_check(s, a) && | ||
425 | + vsha_check_sew(s) && | ||
426 | + MAXSZ(s) >= egw_bytes && | ||
427 | + !is_overlapped(a->rd, mult, a->rs1, mult) && | ||
428 | + !is_overlapped(a->rd, mult, a->rs2, mult) && | ||
429 | + s->lmul >= 0; | ||
430 | +} | ||
431 | + | ||
432 | +GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS) | ||
433 | + | ||
434 | +static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a) | ||
435 | +{ | ||
436 | + if (vsha_check(s, a)) { | ||
437 | + uint32_t data = 0; | ||
438 | + TCGLabel *over = gen_new_label(); | ||
439 | + TCGv_i32 egs; | ||
440 | + | ||
441 | + if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { | ||
442 | + /* save opcode for unwinding in case we throw an exception */ | ||
443 | + decode_save_opc(s); | ||
444 | + egs = tcg_constant_i32(ZVKNH_EGS); | ||
445 | + gen_helper_egs_check(egs, cpu_env); | ||
446 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
259 | + } | 447 | + } |
260 | + } else { | 448 | + |
261 | + /* assume little-endian memory access for now */ | 449 | + data = FIELD_DP32(data, VDATA, VM, a->vm); |
262 | + tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ); | 450 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); |
263 | + tcg_gen_addi_tl(addrl, addrl, 8); | 451 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); |
264 | + tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ); | 452 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); |
265 | + } | 453 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); |
266 | + | 454 | + |
267 | + gen_set_gpr128(ctx, a->rd, destl, desth); | 455 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), |
268 | + | 456 | + vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8, |
269 | + tcg_temp_free(addrl); | 457 | + s->cfg_ptr->vlen / 8, data, |
270 | + return true; | 458 | + s->sew == MO_32 ? |
271 | +} | 459 | + gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv); |
272 | + | 460 | + |
273 | +static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) | 461 | + mark_vs_dirty(s); |
274 | +{ | 462 | + gen_set_label(over); |
275 | + if (get_xl(ctx) == MXL_RV128) { | 463 | + return true; |
276 | + return gen_load_i128(ctx, a, memop); | 464 | + } |
277 | + } else { | 465 | + return false; |
278 | + return gen_load_tl(ctx, a, memop); | 466 | +} |
279 | + } | 467 | + |
280 | +} | 468 | +static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a) |
281 | + | 469 | +{ |
282 | static bool trans_lb(DisasContext *ctx, arg_lb *a) | 470 | + if (vsha_check(s, a)) { |
283 | { | 471 | + uint32_t data = 0; |
284 | return gen_load(ctx, a, MO_SB); | 472 | + TCGLabel *over = gen_new_label(); |
285 | @@ -XXX,XX +XXX,XX @@ static bool trans_lw(DisasContext *ctx, arg_lw *a) | 473 | + TCGv_i32 egs; |
286 | return gen_load(ctx, a, MO_TESL); | 474 | + |
287 | } | 475 | + if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { |
288 | 476 | + /* save opcode for unwinding in case we throw an exception */ | |
289 | +static bool trans_ld(DisasContext *ctx, arg_ld *a) | 477 | + decode_save_opc(s); |
290 | +{ | 478 | + egs = tcg_constant_i32(ZVKNH_EGS); |
291 | + REQUIRE_64_OR_128BIT(ctx); | 479 | + gen_helper_egs_check(egs, cpu_env); |
292 | + return gen_load(ctx, a, MO_TESQ); | 480 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); |
293 | +} | 481 | + } |
294 | + | 482 | + |
295 | +static bool trans_lq(DisasContext *ctx, arg_lq *a) | 483 | + data = FIELD_DP32(data, VDATA, VM, a->vm); |
296 | +{ | 484 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); |
297 | + REQUIRE_128BIT(ctx); | 485 | + data = FIELD_DP32(data, VDATA, VTA, s->vta); |
298 | + return gen_load(ctx, a, MO_TEUO); | 486 | + data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); |
299 | +} | 487 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); |
300 | + | 488 | + |
301 | static bool trans_lbu(DisasContext *ctx, arg_lbu *a) | 489 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), |
302 | { | 490 | + vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8, |
303 | return gen_load(ctx, a, MO_UB); | 491 | + s->cfg_ptr->vlen / 8, data, |
304 | @@ -XXX,XX +XXX,XX @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a) | 492 | + s->sew == MO_32 ? |
305 | 493 | + gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv); | |
306 | static bool trans_lwu(DisasContext *ctx, arg_lwu *a) | 494 | + |
307 | { | 495 | + mark_vs_dirty(s); |
308 | - REQUIRE_64BIT(ctx); | 496 | + gen_set_label(over); |
309 | + REQUIRE_64_OR_128BIT(ctx); | 497 | + return true; |
310 | return gen_load(ctx, a, MO_TEUL); | 498 | + } |
311 | } | 499 | + return false; |
312 | 500 | +} | |
313 | -static bool trans_ld(DisasContext *ctx, arg_ld *a) | ||
314 | +static bool trans_ldu(DisasContext *ctx, arg_ldu *a) | ||
315 | { | ||
316 | - REQUIRE_64BIT(ctx); | ||
317 | + REQUIRE_128BIT(ctx); | ||
318 | return gen_load(ctx, a, MO_TEUQ); | ||
319 | } | ||
320 | |||
321 | -static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) | ||
322 | +static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop) | ||
323 | { | ||
324 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | ||
325 | TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); | ||
326 | @@ -XXX,XX +XXX,XX @@ static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) | ||
327 | return true; | ||
328 | } | ||
329 | |||
330 | +static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop) | ||
331 | +{ | ||
332 | + TCGv src1l = get_gpr(ctx, a->rs1, EXT_NONE); | ||
333 | + TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE); | ||
334 | + TCGv src2h = get_gprh(ctx, a->rs2); | ||
335 | + TCGv addrl = tcg_temp_new(); | ||
336 | + | ||
337 | + tcg_gen_addi_tl(addrl, src1l, a->imm); | ||
338 | + | ||
339 | + if ((memop & MO_SIZE) <= MO_64) { | ||
340 | + tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop); | ||
341 | + } else { | ||
342 | + /* little-endian memory access assumed for now */ | ||
343 | + tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ); | ||
344 | + tcg_gen_addi_tl(addrl, addrl, 8); | ||
345 | + tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ); | ||
346 | + } | ||
347 | + | ||
348 | + tcg_temp_free(addrl); | ||
349 | + return true; | ||
350 | +} | ||
351 | + | ||
352 | +static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) | ||
353 | +{ | ||
354 | + if (get_xl(ctx) == MXL_RV128) { | ||
355 | + return gen_store_i128(ctx, a, memop); | ||
356 | + } else { | ||
357 | + return gen_store_tl(ctx, a, memop); | ||
358 | + } | ||
359 | +} | ||
360 | + | ||
361 | static bool trans_sb(DisasContext *ctx, arg_sb *a) | ||
362 | { | ||
363 | return gen_store(ctx, a, MO_SB); | ||
364 | @@ -XXX,XX +XXX,XX @@ static bool trans_sw(DisasContext *ctx, arg_sw *a) | ||
365 | |||
366 | static bool trans_sd(DisasContext *ctx, arg_sd *a) | ||
367 | { | ||
368 | - REQUIRE_64BIT(ctx); | ||
369 | + REQUIRE_64_OR_128BIT(ctx); | ||
370 | return gen_store(ctx, a, MO_TEUQ); | ||
371 | } | ||
372 | |||
373 | +static bool trans_sq(DisasContext *ctx, arg_sq *a) | ||
374 | +{ | ||
375 | + REQUIRE_128BIT(ctx); | ||
376 | + return gen_store(ctx, a, MO_TEUO); | ||
377 | +} | ||
378 | + | ||
379 | static bool trans_addi(DisasContext *ctx, arg_addi *a) | ||
380 | { | ||
381 | return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl); | ||
382 | -- | 501 | -- |
383 | 2.31.1 | 502 | 2.41.0 |
384 | |||
385 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | |
2 | |||
3 | This commit adds support for the Zvksh vector-crypto extension, which | ||
4 | consists of the following instructions: | ||
5 | |||
6 | * vsm3me.vv | ||
7 | * vsm3c.vi | ||
8 | |||
9 | Translation functions are defined in | ||
10 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in | ||
11 | `target/riscv/vcrypto_helper.c`. | ||
12 | |||
13 | Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> | ||
14 | [max.chou@sifive.com: Replaced vstart checking by TCG op] | ||
15 | Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk> | ||
16 | Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
17 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
18 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
19 | [max.chou@sifive.com: Exposed x-zvksh property] | ||
20 | Message-ID: <20230711165917.2629866-12-max.chou@sifive.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | --- | ||
23 | target/riscv/cpu_cfg.h | 1 + | ||
24 | target/riscv/helper.h | 3 + | ||
25 | target/riscv/insn32.decode | 4 + | ||
26 | target/riscv/cpu.c | 6 +- | ||
27 | target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++ | ||
28 | target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++ | ||
29 | 6 files changed, 177 insertions(+), 2 deletions(-) | ||
30 | |||
31 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/cpu_cfg.h | ||
34 | +++ b/target/riscv/cpu_cfg.h | ||
35 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
36 | bool ext_zvkned; | ||
37 | bool ext_zvknha; | ||
38 | bool ext_zvknhb; | ||
39 | + bool ext_zvksh; | ||
40 | bool ext_zmmul; | ||
41 | bool ext_zvfbfmin; | ||
42 | bool ext_zvfbfwma; | ||
43 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/helper.h | ||
46 | +++ b/target/riscv/helper.h | ||
47 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32) | ||
48 | DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32) | ||
49 | DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32) | ||
50 | DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32) | ||
51 | + | ||
52 | +DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32) | ||
53 | +DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32) | ||
54 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/target/riscv/insn32.decode | ||
57 | +++ b/target/riscv/insn32.decode | ||
58 | @@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
59 | vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
60 | vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
61 | vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
62 | + | ||
63 | +# *** Zvksh vector crypto extension *** | ||
64 | +vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
65 | +vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
66 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/target/riscv/cpu.c | ||
69 | +++ b/target/riscv/cpu.c | ||
70 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
71 | ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned), | ||
72 | ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha), | ||
73 | ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb), | ||
74 | + ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh), | ||
75 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), | ||
76 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
77 | ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), | ||
78 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
79 | * In principle Zve*x would also suffice here, were they supported | ||
80 | * in qemu | ||
81 | */ | ||
82 | - if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) && | ||
83 | - !cpu->cfg.ext_zve32f) { | ||
84 | + if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || | ||
85 | + cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) { | ||
86 | error_setg(errp, | ||
87 | "Vector crypto extensions require V or Zve* extensions"); | ||
88 | return; | ||
89 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
90 | DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false), | ||
91 | DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false), | ||
92 | DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false), | ||
93 | + DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false), | ||
94 | |||
95 | DEFINE_PROP_END_OF_LIST(), | ||
96 | }; | ||
97 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
98 | index XXXXXXX..XXXXXXX 100644 | ||
99 | --- a/target/riscv/vcrypto_helper.c | ||
100 | +++ b/target/riscv/vcrypto_helper.c | ||
101 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env, | ||
102 | vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz); | ||
103 | env->vstart = 0; | ||
104 | } | ||
105 | + | ||
106 | +static inline uint32_t p1(uint32_t x) | ||
107 | +{ | ||
108 | + return x ^ rol32(x, 15) ^ rol32(x, 23); | ||
109 | +} | ||
110 | + | ||
111 | +static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3, | ||
112 | + uint32_t m13, uint32_t m6) | ||
113 | +{ | ||
114 | + return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6; | ||
115 | +} | ||
116 | + | ||
117 | +void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr, | ||
118 | + CPURISCVState *env, uint32_t desc) | ||
119 | +{ | ||
120 | + uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW)); | ||
121 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
122 | + uint32_t vta = vext_vta(desc); | ||
123 | + uint32_t *vd = vd_vptr; | ||
124 | + uint32_t *vs1 = vs1_vptr; | ||
125 | + uint32_t *vs2 = vs2_vptr; | ||
126 | + | ||
127 | + for (int i = env->vstart / 8; i < env->vl / 8; i++) { | ||
128 | + uint32_t w[24]; | ||
129 | + for (int j = 0; j < 8; j++) { | ||
130 | + w[j] = bswap32(vs1[H4((i * 8) + j)]); | ||
131 | + w[j + 8] = bswap32(vs2[H4((i * 8) + j)]); | ||
132 | + } | ||
133 | + for (int j = 0; j < 8; j++) { | ||
134 | + w[j + 16] = | ||
135 | + zvksh_w(w[j], w[j + 7], w[j + 13], w[j + 3], w[j + 10]); | ||
136 | + } | ||
137 | + for (int j = 0; j < 8; j++) { | ||
138 | + vd[(i * 8) + j] = bswap32(w[H4(j + 16)]); | ||
139 | + } | ||
140 | + } | ||
141 | + vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz); | ||
142 | + env->vstart = 0; | ||
143 | +} | ||
144 | + | ||
145 | +static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z) | ||
146 | +{ | ||
147 | + return x ^ y ^ z; | ||
148 | +} | ||
149 | + | ||
150 | +static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z) | ||
151 | +{ | ||
152 | + return (x & y) | (x & z) | (y & z); | ||
153 | +} | ||
154 | + | ||
155 | +static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j) | ||
156 | +{ | ||
157 | + return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z); | ||
158 | +} | ||
159 | + | ||
160 | +static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z) | ||
161 | +{ | ||
162 | + return x ^ y ^ z; | ||
163 | +} | ||
164 | + | ||
165 | +static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z) | ||
166 | +{ | ||
167 | + return (x & y) | (~x & z); | ||
168 | +} | ||
169 | + | ||
170 | +static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j) | ||
171 | +{ | ||
172 | + return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z); | ||
173 | +} | ||
174 | + | ||
175 | +static inline uint32_t t_j(uint32_t j) | ||
176 | +{ | ||
177 | + return (j <= 15) ? 0x79cc4519 : 0x7a879d8a; | ||
178 | +} | ||
179 | + | ||
180 | +static inline uint32_t p_0(uint32_t x) | ||
181 | +{ | ||
182 | + return x ^ rol32(x, 9) ^ rol32(x, 17); | ||
183 | +} | ||
184 | + | ||
185 | +static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm) | ||
186 | +{ | ||
187 | + uint32_t x0, x1; | ||
188 | + uint32_t j; | ||
189 | + uint32_t ss1, ss2, tt1, tt2; | ||
190 | + x0 = vs2[0] ^ vs2[4]; | ||
191 | + x1 = vs2[1] ^ vs2[5]; | ||
192 | + j = 2 * uimm; | ||
193 | + ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7); | ||
194 | + ss2 = ss1 ^ rol32(vs1[0], 12); | ||
195 | + tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0; | ||
196 | + tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0]; | ||
197 | + vs1[3] = vs1[2]; | ||
198 | + vd[3] = rol32(vs1[1], 9); | ||
199 | + vs1[1] = vs1[0]; | ||
200 | + vd[1] = tt1; | ||
201 | + vs1[7] = vs1[6]; | ||
202 | + vd[7] = rol32(vs1[5], 19); | ||
203 | + vs1[5] = vs1[4]; | ||
204 | + vd[5] = p_0(tt2); | ||
205 | + j = 2 * uimm + 1; | ||
206 | + ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7); | ||
207 | + ss2 = ss1 ^ rol32(vd[1], 12); | ||
208 | + tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1; | ||
209 | + tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1]; | ||
210 | + vd[2] = rol32(vs1[1], 9); | ||
211 | + vd[0] = tt1; | ||
212 | + vd[6] = rol32(vs1[5], 19); | ||
213 | + vd[4] = p_0(tt2); | ||
214 | +} | ||
215 | + | ||
216 | +void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, | ||
217 | + CPURISCVState *env, uint32_t desc) | ||
218 | +{ | ||
219 | + uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW)); | ||
220 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
221 | + uint32_t vta = vext_vta(desc); | ||
222 | + uint32_t *vd = vd_vptr; | ||
223 | + uint32_t *vs2 = vs2_vptr; | ||
224 | + uint32_t v1[8], v2[8], v3[8]; | ||
225 | + | ||
226 | + for (int i = env->vstart / 8; i < env->vl / 8; i++) { | ||
227 | + for (int k = 0; k < 8; k++) { | ||
228 | + v2[k] = bswap32(vd[H4(i * 8 + k)]); | ||
229 | + v3[k] = bswap32(vs2[H4(i * 8 + k)]); | ||
230 | + } | ||
231 | + sm3c(v1, v2, v3, uimm); | ||
232 | + for (int k = 0; k < 8; k++) { | ||
233 | + vd[i * 8 + k] = bswap32(v1[H4(k)]); | ||
234 | + } | ||
235 | + } | ||
236 | + vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz); | ||
237 | + env->vstart = 0; | ||
238 | +} | ||
239 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
240 | index XXXXXXX..XXXXXXX 100644 | ||
241 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc | ||
242 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
243 | @@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a) | ||
244 | } | ||
245 | return false; | ||
246 | } | ||
247 | + | ||
248 | +/* | ||
249 | + * Zvksh | ||
250 | + */ | ||
251 | + | ||
252 | +#define ZVKSH_EGS 8 | ||
253 | + | ||
254 | +static inline bool vsm3_check(DisasContext *s, arg_rmrr *a) | ||
255 | +{ | ||
256 | + int egw_bytes = ZVKSH_EGS << s->sew; | ||
257 | + int mult = 1 << MAX(s->lmul, 0); | ||
258 | + return s->cfg_ptr->ext_zvksh == true && | ||
259 | + require_rvv(s) && | ||
260 | + vext_check_isa_ill(s) && | ||
261 | + !is_overlapped(a->rd, mult, a->rs2, mult) && | ||
262 | + MAXSZ(s) >= egw_bytes && | ||
263 | + s->sew == MO_32; | ||
264 | +} | ||
265 | + | ||
266 | +static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a) | ||
267 | +{ | ||
268 | + return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
269 | +} | ||
270 | + | ||
271 | +static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a) | ||
272 | +{ | ||
273 | + return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
274 | +} | ||
275 | + | ||
276 | +GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS) | ||
277 | +GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS) | ||
278 | -- | ||
279 | 2.41.0 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Nazar Kazakov <nazar.kazakov@codethink.co.uk> |
---|---|---|---|
2 | 2 | ||
3 | The upper 64-bit of the 128-bit registers have now a place inside | 3 | This commit adds support for the Zvkg vector-crypto extension, which |
4 | the cpu state structure, and are created as globals for future use. | 4 | consists of the following instructions: |
5 | 5 | ||
6 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | * vgmul.vv |
7 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | * vghsh.vv |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | |
9 | Message-id: 20220106210108.138226-7-frederic.petrot@univ-grenoble-alpes.fr | 9 | Translation functions are defined in |
10 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in | ||
11 | `target/riscv/vcrypto_helper.c`. | ||
12 | |||
13 | Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
14 | [max.chou@sifive.com: Replaced vstart checking by TCG op] | ||
15 | Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk> | ||
16 | Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk> | ||
17 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
18 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
19 | [max.chou@sifive.com: Exposed x-zvkg property] | ||
20 | [max.chou@sifive.com: Replaced uint by int for cross win32 build] | ||
21 | Message-ID: <20230711165917.2629866-13-max.chou@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 23 | --- |
12 | target/riscv/cpu.h | 2 ++ | 24 | target/riscv/cpu_cfg.h | 1 + |
13 | target/riscv/cpu.c | 9 +++++++++ | 25 | target/riscv/helper.h | 3 + |
14 | target/riscv/machine.c | 20 ++++++++++++++++++++ | 26 | target/riscv/insn32.decode | 4 ++ |
15 | target/riscv/translate.c | 5 ++++- | 27 | target/riscv/cpu.c | 6 +- |
16 | 4 files changed, 35 insertions(+), 1 deletion(-) | 28 | target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++ |
17 | 29 | target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++ | |
18 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 30 | 6 files changed, 114 insertions(+), 2 deletions(-) |
19 | index XXXXXXX..XXXXXXX 100644 | 31 | |
20 | --- a/target/riscv/cpu.h | 32 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h |
21 | +++ b/target/riscv/cpu.h | 33 | index XXXXXXX..XXXXXXX 100644 |
22 | @@ -XXX,XX +XXX,XX @@ FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1) | 34 | --- a/target/riscv/cpu_cfg.h |
23 | 35 | +++ b/target/riscv/cpu_cfg.h | |
24 | struct CPURISCVState { | 36 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { |
25 | target_ulong gpr[32]; | 37 | bool ext_zve64d; |
26 | + target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */ | 38 | bool ext_zvbb; |
27 | uint64_t fpr[32]; /* assume both F and D extensions */ | 39 | bool ext_zvbc; |
28 | 40 | + bool ext_zvkg; | |
29 | /* vector coprocessor state. */ | 41 | bool ext_zvkned; |
30 | @@ -XXX,XX +XXX,XX @@ static inline bool riscv_feature(CPURISCVState *env, int feature) | 42 | bool ext_zvknha; |
31 | #include "cpu_user.h" | 43 | bool ext_zvknhb; |
32 | 44 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | |
33 | extern const char * const riscv_int_regnames[]; | 45 | index XXXXXXX..XXXXXXX 100644 |
34 | +extern const char * const riscv_int_regnamesh[]; | 46 | --- a/target/riscv/helper.h |
35 | extern const char * const riscv_fpr_regnames[]; | 47 | +++ b/target/riscv/helper.h |
36 | 48 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32) | |
37 | const char *riscv_cpu_get_trap_name(target_ulong cause, bool async); | 49 | |
50 | DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32) | ||
51 | DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32) | ||
52 | + | ||
53 | +DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32) | ||
54 | +DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32) | ||
55 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/target/riscv/insn32.decode | ||
58 | +++ b/target/riscv/insn32.decode | ||
59 | @@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
60 | # *** Zvksh vector crypto extension *** | ||
61 | vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
62 | vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
63 | + | ||
64 | +# *** Zvkg vector crypto extension *** | ||
65 | +vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
66 | +vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1 | ||
38 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 67 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
39 | index XXXXXXX..XXXXXXX 100644 | 68 | index XXXXXXX..XXXXXXX 100644 |
40 | --- a/target/riscv/cpu.c | 69 | --- a/target/riscv/cpu.c |
41 | +++ b/target/riscv/cpu.c | 70 | +++ b/target/riscv/cpu.c |
42 | @@ -XXX,XX +XXX,XX @@ const char * const riscv_int_regnames[] = { | 71 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
43 | "x28/t3", "x29/t4", "x30/t5", "x31/t6" | 72 | ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma), |
44 | }; | 73 | ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh), |
45 | 74 | ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin), | |
46 | +const char * const riscv_int_regnamesh[] = { | 75 | + ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg), |
47 | + "x0h/zeroh", "x1h/rah", "x2h/sph", "x3h/gph", "x4h/tph", "x5h/t0h", | 76 | ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned), |
48 | + "x6h/t1h", "x7h/t2h", "x8h/s0h", "x9h/s1h", "x10h/a0h", "x11h/a1h", | 77 | ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha), |
49 | + "x12h/a2h", "x13h/a3h", "x14h/a4h", "x15h/a5h", "x16h/a6h", "x17h/a7h", | 78 | ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb), |
50 | + "x18h/s2h", "x19h/s3h", "x20h/s4h", "x21h/s5h", "x22h/s6h", "x23h/s7h", | 79 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
51 | + "x24h/s8h", "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h", | 80 | * In principle Zve*x would also suffice here, were they supported |
52 | + "x30h/t5h", "x31h/t6h" | 81 | * in qemu |
53 | +}; | 82 | */ |
54 | + | 83 | - if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || |
55 | const char * const riscv_fpr_regnames[] = { | 84 | - cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) { |
56 | "f0/ft0", "f1/ft1", "f2/ft2", "f3/ft3", "f4/ft4", "f5/ft5", | 85 | + if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned || |
57 | "f6/ft6", "f7/ft7", "f8/fs0", "f9/fs1", "f10/fa0", "f11/fa1", | 86 | + cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) { |
58 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | 87 | error_setg(errp, |
59 | index XXXXXXX..XXXXXXX 100644 | 88 | "Vector crypto extensions require V or Zve* extensions"); |
60 | --- a/target/riscv/machine.c | 89 | return; |
61 | +++ b/target/riscv/machine.c | 90 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { |
62 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pointermasking = { | 91 | /* Vector cryptography extensions */ |
63 | } | 92 | DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false), |
64 | }; | 93 | DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), |
65 | 94 | + DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false), | |
66 | +static bool rv128_needed(void *opaque) | 95 | DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false), |
67 | +{ | 96 | DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false), |
68 | + RISCVCPU *cpu = opaque; | 97 | DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false), |
69 | + CPURISCVState *env = &cpu->env; | 98 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c |
70 | + | 99 | index XXXXXXX..XXXXXXX 100644 |
71 | + return env->misa_mxl_max == MXL_RV128; | 100 | --- a/target/riscv/vcrypto_helper.c |
72 | +} | 101 | +++ b/target/riscv/vcrypto_helper.c |
73 | + | 102 | @@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm, |
74 | +static const VMStateDescription vmstate_rv128 = { | 103 | vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz); |
75 | + .name = "cpu/rv128", | 104 | env->vstart = 0; |
76 | + .version_id = 1, | 105 | } |
77 | + .minimum_version_id = 1, | 106 | + |
78 | + .needed = rv128_needed, | 107 | +void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr, |
79 | + .fields = (VMStateField[]) { | 108 | + CPURISCVState *env, uint32_t desc) |
80 | + VMSTATE_UINTTL_ARRAY(env.gprh, RISCVCPU, 32), | 109 | +{ |
81 | + VMSTATE_END_OF_LIST() | 110 | + uint64_t *vd = vd_vptr; |
111 | + uint64_t *vs1 = vs1_vptr; | ||
112 | + uint64_t *vs2 = vs2_vptr; | ||
113 | + uint32_t vta = vext_vta(desc); | ||
114 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); | ||
115 | + | ||
116 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { | ||
117 | + uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]}; | ||
118 | + uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])}; | ||
119 | + uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]}; | ||
120 | + uint64_t Z[2] = {0, 0}; | ||
121 | + | ||
122 | + uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])}; | ||
123 | + | ||
124 | + for (int j = 0; j < 128; j++) { | ||
125 | + if ((S[j / 64] >> (j % 64)) & 1) { | ||
126 | + Z[0] ^= H[0]; | ||
127 | + Z[1] ^= H[1]; | ||
128 | + } | ||
129 | + bool reduce = ((H[1] >> 63) & 1); | ||
130 | + H[1] = H[1] << 1 | H[0] >> 63; | ||
131 | + H[0] = H[0] << 1; | ||
132 | + if (reduce) { | ||
133 | + H[0] ^= 0x87; | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + vd[i * 2 + 0] = brev8(Z[0]); | ||
138 | + vd[i * 2 + 1] = brev8(Z[1]); | ||
82 | + } | 139 | + } |
83 | +}; | 140 | + /* set tail elements to 1s */ |
84 | + | 141 | + vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4); |
85 | const VMStateDescription vmstate_riscv_cpu = { | 142 | + env->vstart = 0; |
86 | .name = "cpu", | 143 | +} |
87 | .version_id = 3, | 144 | + |
88 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { | 145 | +void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env, |
89 | &vmstate_hyper, | 146 | + uint32_t desc) |
90 | &vmstate_vector, | 147 | +{ |
91 | &vmstate_pointermasking, | 148 | + uint64_t *vd = vd_vptr; |
92 | + &vmstate_rv128, | 149 | + uint64_t *vs2 = vs2_vptr; |
93 | NULL | 150 | + uint32_t vta = vext_vta(desc); |
94 | } | 151 | + uint32_t total_elems = vext_get_total_elems(env, desc, 4); |
95 | }; | 152 | + |
96 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 153 | + for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { |
97 | index XXXXXXX..XXXXXXX 100644 | 154 | + uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])}; |
98 | --- a/target/riscv/translate.c | 155 | + uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])}; |
99 | +++ b/target/riscv/translate.c | 156 | + uint64_t Z[2] = {0, 0}; |
100 | @@ -XXX,XX +XXX,XX @@ | 157 | + |
101 | #include "internals.h" | 158 | + for (int j = 0; j < 128; j++) { |
102 | 159 | + if ((Y[j / 64] >> (j % 64)) & 1) { | |
103 | /* global register indices */ | 160 | + Z[0] ^= H[0]; |
104 | -static TCGv cpu_gpr[32], cpu_pc, cpu_vl, cpu_vstart; | 161 | + Z[1] ^= H[1]; |
105 | +static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart; | 162 | + } |
106 | static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ | 163 | + bool reduce = ((H[1] >> 63) & 1); |
107 | static TCGv load_res; | 164 | + H[1] = H[1] << 1 | H[0] >> 63; |
108 | static TCGv load_val; | 165 | + H[0] = H[0] << 1; |
109 | @@ -XXX,XX +XXX,XX @@ void riscv_translate_init(void) | 166 | + if (reduce) { |
110 | * unless you specifically block reads/writes to reg 0. | 167 | + H[0] ^= 0x87; |
111 | */ | 168 | + } |
112 | cpu_gpr[0] = NULL; | 169 | + } |
113 | + cpu_gprh[0] = NULL; | 170 | + |
114 | 171 | + vd[i * 2 + 0] = brev8(Z[0]); | |
115 | for (i = 1; i < 32; i++) { | 172 | + vd[i * 2 + 1] = brev8(Z[1]); |
116 | cpu_gpr[i] = tcg_global_mem_new(cpu_env, | 173 | + } |
117 | offsetof(CPURISCVState, gpr[i]), riscv_int_regnames[i]); | 174 | + /* set tail elements to 1s */ |
118 | + cpu_gprh[i] = tcg_global_mem_new(cpu_env, | 175 | + vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4); |
119 | + offsetof(CPURISCVState, gprh[i]), riscv_int_regnamesh[i]); | 176 | + env->vstart = 0; |
120 | } | 177 | +} |
121 | 178 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | |
122 | for (i = 0; i < 32; i++) { | 179 | index XXXXXXX..XXXXXXX 100644 |
180 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc | ||
181 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
182 | @@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a) | ||
183 | |||
184 | GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS) | ||
185 | GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS) | ||
186 | + | ||
187 | +/* | ||
188 | + * Zvkg | ||
189 | + */ | ||
190 | + | ||
191 | +#define ZVKG_EGS 4 | ||
192 | + | ||
193 | +static bool vgmul_check(DisasContext *s, arg_rmr *a) | ||
194 | +{ | ||
195 | + int egw_bytes = ZVKG_EGS << s->sew; | ||
196 | + return s->cfg_ptr->ext_zvkg == true && | ||
197 | + vext_check_isa_ill(s) && | ||
198 | + require_rvv(s) && | ||
199 | + MAXSZ(s) >= egw_bytes && | ||
200 | + vext_check_ss(s, a->rd, a->rs2, a->vm) && | ||
201 | + s->sew == MO_32; | ||
202 | +} | ||
203 | + | ||
204 | +GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS) | ||
205 | + | ||
206 | +static bool vghsh_check(DisasContext *s, arg_rmrr *a) | ||
207 | +{ | ||
208 | + int egw_bytes = ZVKG_EGS << s->sew; | ||
209 | + return s->cfg_ptr->ext_zvkg == true && | ||
210 | + opivv_check(s, a) && | ||
211 | + MAXSZ(s) >= egw_bytes && | ||
212 | + s->sew == MO_32; | ||
213 | +} | ||
214 | + | ||
215 | +GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS) | ||
123 | -- | 216 | -- |
124 | 2.31.1 | 217 | 2.41.0 |
125 | |||
126 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Allows sharing of sm4_subword between different targets. | ||
4 | |||
5 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
6 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
9 | Message-ID: <20230711165917.2629866-14-max.chou@sifive.com> | ||
3 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
4 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
5 | Message-Id: <20220105213937.1113508-3-alistair.francis@opensource.wdc.com> | ||
6 | --- | 11 | --- |
7 | hw/intc/sifive_plic.c | 76 +++++++++++++++---------------------------- | 12 | include/crypto/sm4.h | 8 ++++++++ |
8 | 1 file changed, 27 insertions(+), 49 deletions(-) | 13 | target/arm/tcg/crypto_helper.c | 10 ++-------- |
14 | 2 files changed, 10 insertions(+), 8 deletions(-) | ||
9 | 15 | ||
10 | diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c | 16 | diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h |
11 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/hw/intc/sifive_plic.c | 18 | --- a/include/crypto/sm4.h |
13 | +++ b/hw/intc/sifive_plic.c | 19 | +++ b/include/crypto/sm4.h |
14 | @@ -XXX,XX +XXX,XX @@ | 20 | @@ -XXX,XX +XXX,XX @@ |
15 | 21 | ||
16 | #define RISCV_DEBUG_PLIC 0 | 22 | extern const uint8_t sm4_sbox[256]; |
17 | 23 | ||
18 | +static bool addr_between(uint32_t addr, uint32_t base, uint32_t num) | 24 | +static inline uint32_t sm4_subword(uint32_t word) |
19 | +{ | 25 | +{ |
20 | + return addr >= base && addr - base < num; | 26 | + return sm4_sbox[word & 0xff] | |
27 | + sm4_sbox[(word >> 8) & 0xff] << 8 | | ||
28 | + sm4_sbox[(word >> 16) & 0xff] << 16 | | ||
29 | + sm4_sbox[(word >> 24) & 0xff] << 24; | ||
21 | +} | 30 | +} |
22 | + | 31 | + |
23 | static PLICMode char_to_mode(char c) | 32 | #endif |
24 | { | 33 | diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c |
25 | switch (c) { | 34 | index XXXXXXX..XXXXXXX 100644 |
26 | @@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value, | 35 | --- a/target/arm/tcg/crypto_helper.c |
27 | { | 36 | +++ b/target/arm/tcg/crypto_helper.c |
28 | SiFivePLICState *plic = opaque; | 37 | @@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm) |
29 | 38 | CR_ST_WORD(d, (i + 3) % 4) ^ | |
30 | - /* writes must be 4 byte words */ | 39 | CR_ST_WORD(n, i); |
31 | - if ((addr & 0x3) != 0) { | 40 | |
32 | - goto err; | 41 | - t = sm4_sbox[t & 0xff] | |
33 | - } | 42 | - sm4_sbox[(t >> 8) & 0xff] << 8 | |
34 | - | 43 | - sm4_sbox[(t >> 16) & 0xff] << 16 | |
35 | - if (addr >= plic->priority_base && /* 4 bytes per source */ | 44 | - sm4_sbox[(t >> 24) & 0xff] << 24; |
36 | - addr < plic->priority_base + (plic->num_sources << 2)) | 45 | + t = sm4_subword(t); |
37 | - { | 46 | |
38 | + if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) { | 47 | CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^ |
39 | uint32_t irq = ((addr - plic->priority_base) >> 2) + 1; | 48 | rol32(t, 24); |
40 | + | 49 | @@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm) |
41 | plic->source_priority[irq] = value & 7; | 50 | CR_ST_WORD(d, (i + 3) % 4) ^ |
42 | - if (RISCV_DEBUG_PLIC) { | 51 | CR_ST_WORD(m, i); |
43 | - qemu_log("plic: write priority: irq=%d priority=%d\n", | 52 | |
44 | - irq, plic->source_priority[irq]); | 53 | - t = sm4_sbox[t & 0xff] | |
45 | - } | 54 | - sm4_sbox[(t >> 8) & 0xff] << 8 | |
46 | sifive_plic_update(plic); | 55 | - sm4_sbox[(t >> 16) & 0xff] << 16 | |
47 | - return; | 56 | - sm4_sbox[(t >> 24) & 0xff] << 24; |
48 | - } else if (addr >= plic->pending_base && /* 1 bit per source */ | 57 | + t = sm4_subword(t); |
49 | - addr < plic->pending_base + (plic->num_sources >> 3)) | 58 | |
50 | - { | 59 | CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23); |
51 | + } else if (addr_between(addr, plic->pending_base, | ||
52 | + plic->num_sources >> 3)) { | ||
53 | qemu_log_mask(LOG_GUEST_ERROR, | ||
54 | "%s: invalid pending write: 0x%" HWADDR_PRIx "", | ||
55 | __func__, addr); | ||
56 | - return; | ||
57 | - } else if (addr >= plic->enable_base && /* 1 bit per source */ | ||
58 | - addr < plic->enable_base + plic->num_addrs * plic->enable_stride) | ||
59 | - { | ||
60 | + } else if (addr_between(addr, plic->enable_base, | ||
61 | + plic->num_addrs * plic->enable_stride)) { | ||
62 | uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride; | ||
63 | uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2; | ||
64 | + | ||
65 | if (wordid < plic->bitfield_words) { | ||
66 | plic->enable[addrid * plic->bitfield_words + wordid] = value; | ||
67 | - if (RISCV_DEBUG_PLIC) { | ||
68 | - qemu_log("plic: write enable: hart%d-%c word=%d value=%x\n", | ||
69 | - plic->addr_config[addrid].hartid, | ||
70 | - mode_to_char(plic->addr_config[addrid].mode), wordid, | ||
71 | - plic->enable[addrid * plic->bitfield_words + wordid]); | ||
72 | - } | ||
73 | - return; | ||
74 | + } else { | ||
75 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
76 | + "%s: Invalid enable write 0x%" HWADDR_PRIx "\n", | ||
77 | + __func__, addr); | ||
78 | } | ||
79 | - } else if (addr >= plic->context_base && /* 4 bytes per reg */ | ||
80 | - addr < plic->context_base + plic->num_addrs * plic->context_stride) | ||
81 | - { | ||
82 | + } else if (addr_between(addr, plic->context_base, | ||
83 | + plic->num_addrs * plic->context_stride)) { | ||
84 | uint32_t addrid = (addr - plic->context_base) / plic->context_stride; | ||
85 | uint32_t contextid = (addr & (plic->context_stride - 1)); | ||
86 | + | ||
87 | if (contextid == 0) { | ||
88 | - if (RISCV_DEBUG_PLIC) { | ||
89 | - qemu_log("plic: write priority: hart%d-%c priority=%x\n", | ||
90 | - plic->addr_config[addrid].hartid, | ||
91 | - mode_to_char(plic->addr_config[addrid].mode), | ||
92 | - plic->target_priority[addrid]); | ||
93 | - } | ||
94 | if (value <= plic->num_priorities) { | ||
95 | plic->target_priority[addrid] = value; | ||
96 | sifive_plic_update(plic); | ||
97 | } | ||
98 | - return; | ||
99 | } else if (contextid == 4) { | ||
100 | - if (RISCV_DEBUG_PLIC) { | ||
101 | - qemu_log("plic: write claim: hart%d-%c irq=%x\n", | ||
102 | - plic->addr_config[addrid].hartid, | ||
103 | - mode_to_char(plic->addr_config[addrid].mode), | ||
104 | - (uint32_t)value); | ||
105 | - } | ||
106 | if (value < plic->num_sources) { | ||
107 | sifive_plic_set_claimed(plic, value, false); | ||
108 | sifive_plic_update(plic); | ||
109 | } | ||
110 | - return; | ||
111 | + } else { | ||
112 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
113 | + "%s: Invalid context write 0x%" HWADDR_PRIx "\n", | ||
114 | + __func__, addr); | ||
115 | } | ||
116 | + } else { | ||
117 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
118 | + "%s: Invalid register write 0x%" HWADDR_PRIx "\n", | ||
119 | + __func__, addr); | ||
120 | } | 60 | } |
121 | - | ||
122 | -err: | ||
123 | - qemu_log_mask(LOG_GUEST_ERROR, | ||
124 | - "%s: Invalid register write 0x%" HWADDR_PRIx "\n", | ||
125 | - __func__, addr); | ||
126 | } | ||
127 | |||
128 | static const MemoryRegionOps sifive_plic_ops = { | ||
129 | -- | 61 | -- |
130 | 2.31.1 | 62 | 2.41.0 |
131 | |||
132 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Max Chou <max.chou@sifive.com> | ||
1 | 2 | ||
3 | Adds sm4_ck constant for use in sm4 cryptography across different targets. | ||
4 | |||
5 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
6 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
8 | Message-ID: <20230711165917.2629866-15-max.chou@sifive.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | include/crypto/sm4.h | 1 + | ||
12 | crypto/sm4.c | 10 ++++++++++ | ||
13 | 2 files changed, 11 insertions(+) | ||
14 | |||
15 | diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/crypto/sm4.h | ||
18 | +++ b/include/crypto/sm4.h | ||
19 | @@ -XXX,XX +XXX,XX @@ | ||
20 | #define QEMU_SM4_H | ||
21 | |||
22 | extern const uint8_t sm4_sbox[256]; | ||
23 | +extern const uint32_t sm4_ck[32]; | ||
24 | |||
25 | static inline uint32_t sm4_subword(uint32_t word) | ||
26 | { | ||
27 | diff --git a/crypto/sm4.c b/crypto/sm4.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/crypto/sm4.c | ||
30 | +++ b/crypto/sm4.c | ||
31 | @@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = { | ||
32 | 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, | ||
33 | }; | ||
34 | |||
35 | +uint32_t const sm4_ck[] = { | ||
36 | + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, | ||
37 | + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, | ||
38 | + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, | ||
39 | + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, | ||
40 | + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, | ||
41 | + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, | ||
42 | + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, | ||
43 | + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 | ||
44 | +}; | ||
45 | -- | ||
46 | 2.41.0 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Max Chou <max.chou@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Addition of 128-bit adds and subs in their various sizes, | 3 | This commit adds support for the Zvksed vector-crypto extension, which |
4 | "set if less than"s and branches. | 4 | consists of the following instructions: |
5 | Refactored the code to have a comparison function used for both stls and | 5 | |
6 | branches. | 6 | * vsm4k.vi |
7 | 7 | * vsm4r.[vv,vs] | |
8 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 8 | |
9 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 9 | Translation functions are defined in |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 10 | `target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in |
11 | Message-id: 20220106210108.138226-14-frederic.petrot@univ-grenoble-alpes.fr | 11 | `target/riscv/vcrypto_helper.c`. |
12 | |||
13 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
14 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
15 | [lawrence.hunter@codethink.co.uk: Moved SM4 functions from | ||
16 | crypto_helper.c to vcrypto_helper.c] | ||
17 | [nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to | ||
18 | use macros, and minor style changes] | ||
19 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
20 | Message-ID: <20230711165917.2629866-16-max.chou@sifive.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 22 | --- |
14 | target/riscv/insn32.decode | 3 + | 23 | target/riscv/cpu_cfg.h | 1 + |
15 | target/riscv/translate.c | 63 ++++++++-- | 24 | target/riscv/helper.h | 4 + |
16 | target/riscv/insn_trans/trans_rvb.c.inc | 20 +-- | 25 | target/riscv/insn32.decode | 5 + |
17 | target/riscv/insn_trans/trans_rvi.c.inc | 159 +++++++++++++++++++++--- | 26 | target/riscv/cpu.c | 5 +- |
18 | target/riscv/insn_trans/trans_rvm.c.inc | 26 ++-- | 27 | target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++ |
19 | 5 files changed, 222 insertions(+), 49 deletions(-) | 28 | target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++ |
20 | 29 | 6 files changed, 184 insertions(+), 1 deletion(-) | |
30 | |||
31 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/cpu_cfg.h | ||
34 | +++ b/target/riscv/cpu_cfg.h | ||
35 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
36 | bool ext_zvkned; | ||
37 | bool ext_zvknha; | ||
38 | bool ext_zvknhb; | ||
39 | + bool ext_zvksed; | ||
40 | bool ext_zvksh; | ||
41 | bool ext_zmmul; | ||
42 | bool ext_zvfbfmin; | ||
43 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/helper.h | ||
46 | +++ b/target/riscv/helper.h | ||
47 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32) | ||
48 | |||
49 | DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32) | ||
50 | DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32) | ||
51 | + | ||
52 | +DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32) | ||
53 | +DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32) | ||
54 | +DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32) | ||
21 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 55 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode |
22 | index XXXXXXX..XXXXXXX 100644 | 56 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/insn32.decode | 57 | --- a/target/riscv/insn32.decode |
24 | +++ b/target/riscv/insn32.decode | 58 | +++ b/target/riscv/insn32.decode |
25 | @@ -XXX,XX +XXX,XX @@ sraw 0100000 ..... ..... 101 ..... 0111011 @r | 59 | @@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
26 | ldu ............ ..... 111 ..... 0000011 @i | 60 | # *** Zvkg vector crypto extension *** |
27 | lq ............ ..... 010 ..... 0001111 @i | 61 | vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
28 | sq ............ ..... 100 ..... 0100011 @s | 62 | vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1 |
29 | +addid ............ ..... 000 ..... 1011011 @i | 63 | + |
30 | sllid 000000 ...... ..... 001 ..... 1011011 @sh6 | 64 | +# *** Zvksed vector crypto extension *** |
31 | srlid 000000 ...... ..... 101 ..... 1011011 @sh6 | 65 | +vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1 |
32 | sraid 010000 ...... ..... 101 ..... 1011011 @sh6 | 66 | +vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1 |
33 | +addd 0000000 ..... ..... 000 ..... 1111011 @r | 67 | +vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1 |
34 | +subd 0100000 ..... ..... 000 ..... 1111011 @r | 68 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
35 | slld 0000000 ..... ..... 001 ..... 1111011 @r | 69 | index XXXXXXX..XXXXXXX 100644 |
36 | srld 0000000 ..... ..... 101 ..... 1111011 @r | 70 | --- a/target/riscv/cpu.c |
37 | srad 0100000 ..... ..... 101 ..... 1111011 @r | 71 | +++ b/target/riscv/cpu.c |
38 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 72 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
39 | index XXXXXXX..XXXXXXX 100644 | 73 | ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned), |
40 | --- a/target/riscv/translate.c | 74 | ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha), |
41 | +++ b/target/riscv/translate.c | 75 | ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb), |
42 | @@ -XXX,XX +XXX,XX @@ static bool gen_logic(DisasContext *ctx, arg_r *a, | 76 | + ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed), |
77 | ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh), | ||
78 | ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), | ||
79 | ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
80 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
81 | * in qemu | ||
82 | */ | ||
83 | if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned || | ||
84 | - cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) { | ||
85 | + cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) && | ||
86 | + !cpu->cfg.ext_zve32f) { | ||
87 | error_setg(errp, | ||
88 | "Vector crypto extensions require V or Zve* extensions"); | ||
89 | return; | ||
90 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
91 | DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false), | ||
92 | DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false), | ||
93 | DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false), | ||
94 | + DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false), | ||
95 | DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false), | ||
96 | |||
97 | DEFINE_PROP_END_OF_LIST(), | ||
98 | diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/target/riscv/vcrypto_helper.c | ||
101 | +++ b/target/riscv/vcrypto_helper.c | ||
102 | @@ -XXX,XX +XXX,XX @@ | ||
103 | #include "cpu.h" | ||
104 | #include "crypto/aes.h" | ||
105 | #include "crypto/aes-round.h" | ||
106 | +#include "crypto/sm4.h" | ||
107 | #include "exec/memop.h" | ||
108 | #include "exec/exec-all.h" | ||
109 | #include "exec/helper-proto.h" | ||
110 | @@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env, | ||
111 | vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4); | ||
112 | env->vstart = 0; | ||
43 | } | 113 | } |
44 | 114 | + | |
45 | static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext, | 115 | +void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env, |
46 | - void (*func)(TCGv, TCGv, target_long)) | 116 | + uint32_t desc) |
47 | + void (*func)(TCGv, TCGv, target_long), | 117 | +{ |
48 | + void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long)) | 118 | + const uint32_t egs = 4; |
49 | { | 119 | + uint32_t rnd = uimm5 & 0x7; |
50 | TCGv dest = dest_gpr(ctx, a->rd); | 120 | + uint32_t group_start = env->vstart / egs; |
51 | TCGv src1 = get_gpr(ctx, a->rs1, ext); | 121 | + uint32_t group_end = env->vl / egs; |
52 | 122 | + uint32_t esz = sizeof(uint32_t); | |
53 | - func(dest, src1, a->imm); | 123 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); |
54 | + if (get_ol(ctx) < MXL_RV128) { | 124 | + |
55 | + func(dest, src1, a->imm); | 125 | + for (uint32_t i = group_start; i < group_end; ++i) { |
56 | + gen_set_gpr(ctx, a->rd, dest); | 126 | + uint32_t vstart = i * egs; |
57 | + } else { | 127 | + uint32_t vend = (i + 1) * egs; |
58 | + if (f128 == NULL) { | 128 | + uint32_t rk[4] = {0}; |
59 | + return false; | 129 | + uint32_t tmp[8] = {0}; |
60 | + } | 130 | + |
61 | 131 | + for (uint32_t j = vstart; j < vend; ++j) { | |
62 | - gen_set_gpr(ctx, a->rd, dest); | 132 | + rk[j - vstart] = *((uint32_t *)vs2 + H4(j)); |
63 | + TCGv src1h = get_gprh(ctx, a->rs1); | 133 | + } |
64 | + TCGv desth = dest_gprh(ctx, a->rd); | 134 | + |
65 | + | 135 | + for (uint32_t j = 0; j < egs; ++j) { |
66 | + f128(dest, desth, src1, src1h, a->imm); | 136 | + tmp[j] = rk[j]; |
67 | + gen_set_gpr128(ctx, a->rd, dest, desth); | 137 | + } |
68 | + } | 138 | + |
69 | return true; | 139 | + for (uint32_t j = 0; j < egs; ++j) { |
140 | + uint32_t b, s; | ||
141 | + b = tmp[j + 1] ^ tmp[j + 2] ^ tmp[j + 3] ^ sm4_ck[rnd * 4 + j]; | ||
142 | + | ||
143 | + s = sm4_subword(b); | ||
144 | + | ||
145 | + tmp[j + 4] = tmp[j] ^ (s ^ rol32(s, 13) ^ rol32(s, 23)); | ||
146 | + } | ||
147 | + | ||
148 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
149 | + *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)]; | ||
150 | + } | ||
151 | + } | ||
152 | + | ||
153 | + env->vstart = 0; | ||
154 | + /* set tail elements to 1s */ | ||
155 | + vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz); | ||
156 | +} | ||
157 | + | ||
158 | +static void do_sm4_round(uint32_t *rk, uint32_t *buf) | ||
159 | +{ | ||
160 | + const uint32_t egs = 4; | ||
161 | + uint32_t s, b; | ||
162 | + | ||
163 | + for (uint32_t j = egs; j < egs * 2; ++j) { | ||
164 | + b = buf[j - 3] ^ buf[j - 2] ^ buf[j - 1] ^ rk[j - 4]; | ||
165 | + | ||
166 | + s = sm4_subword(b); | ||
167 | + | ||
168 | + buf[j] = buf[j - 4] ^ (s ^ rol32(s, 2) ^ rol32(s, 10) ^ rol32(s, 18) ^ | ||
169 | + rol32(s, 24)); | ||
170 | + } | ||
171 | +} | ||
172 | + | ||
173 | +void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) | ||
174 | +{ | ||
175 | + const uint32_t egs = 4; | ||
176 | + uint32_t group_start = env->vstart / egs; | ||
177 | + uint32_t group_end = env->vl / egs; | ||
178 | + uint32_t esz = sizeof(uint32_t); | ||
179 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
180 | + | ||
181 | + for (uint32_t i = group_start; i < group_end; ++i) { | ||
182 | + uint32_t vstart = i * egs; | ||
183 | + uint32_t vend = (i + 1) * egs; | ||
184 | + uint32_t rk[4] = {0}; | ||
185 | + uint32_t tmp[8] = {0}; | ||
186 | + | ||
187 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
188 | + rk[j - vstart] = *((uint32_t *)vs2 + H4(j)); | ||
189 | + } | ||
190 | + | ||
191 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
192 | + tmp[j - vstart] = *((uint32_t *)vd + H4(j)); | ||
193 | + } | ||
194 | + | ||
195 | + do_sm4_round(rk, tmp); | ||
196 | + | ||
197 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
198 | + *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)]; | ||
199 | + } | ||
200 | + } | ||
201 | + | ||
202 | + env->vstart = 0; | ||
203 | + /* set tail elements to 1s */ | ||
204 | + vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz); | ||
205 | +} | ||
206 | + | ||
207 | +void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) | ||
208 | +{ | ||
209 | + const uint32_t egs = 4; | ||
210 | + uint32_t group_start = env->vstart / egs; | ||
211 | + uint32_t group_end = env->vl / egs; | ||
212 | + uint32_t esz = sizeof(uint32_t); | ||
213 | + uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
214 | + | ||
215 | + for (uint32_t i = group_start; i < group_end; ++i) { | ||
216 | + uint32_t vstart = i * egs; | ||
217 | + uint32_t vend = (i + 1) * egs; | ||
218 | + uint32_t rk[4] = {0}; | ||
219 | + uint32_t tmp[8] = {0}; | ||
220 | + | ||
221 | + for (uint32_t j = 0; j < egs; ++j) { | ||
222 | + rk[j] = *((uint32_t *)vs2 + H4(j)); | ||
223 | + } | ||
224 | + | ||
225 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
226 | + tmp[j - vstart] = *((uint32_t *)vd + H4(j)); | ||
227 | + } | ||
228 | + | ||
229 | + do_sm4_round(rk, tmp); | ||
230 | + | ||
231 | + for (uint32_t j = vstart; j < vend; ++j) { | ||
232 | + *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)]; | ||
233 | + } | ||
234 | + } | ||
235 | + | ||
236 | + env->vstart = 0; | ||
237 | + /* set tail elements to 1s */ | ||
238 | + vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz); | ||
239 | +} | ||
240 | diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
241 | index XXXXXXX..XXXXXXX 100644 | ||
242 | --- a/target/riscv/insn_trans/trans_rvvk.c.inc | ||
243 | +++ b/target/riscv/insn_trans/trans_rvvk.c.inc | ||
244 | @@ -XXX,XX +XXX,XX @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a) | ||
70 | } | 245 | } |
71 | 246 | ||
72 | static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext, | 247 | GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS) |
73 | - void (*func)(TCGv, TCGv, TCGv)) | 248 | + |
74 | + void (*func)(TCGv, TCGv, TCGv), | 249 | +/* |
75 | + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) | 250 | + * Zvksed |
76 | { | 251 | + */ |
77 | TCGv dest = dest_gpr(ctx, a->rd); | 252 | + |
78 | TCGv src1 = get_gpr(ctx, a->rs1, ext); | 253 | +#define ZVKSED_EGS 4 |
79 | TCGv src2 = tcg_constant_tl(a->imm); | 254 | + |
80 | 255 | +static bool zvksed_check(DisasContext *s) | |
81 | - func(dest, src1, src2); | 256 | +{ |
82 | + if (get_ol(ctx) < MXL_RV128) { | 257 | + int egw_bytes = ZVKSED_EGS << s->sew; |
83 | + func(dest, src1, src2); | 258 | + return s->cfg_ptr->ext_zvksed == true && |
84 | + gen_set_gpr(ctx, a->rd, dest); | 259 | + require_rvv(s) && |
85 | + } else { | 260 | + vext_check_isa_ill(s) && |
86 | + if (f128 == NULL) { | 261 | + MAXSZ(s) >= egw_bytes && |
87 | + return false; | 262 | + s->sew == MO_32; |
88 | + } | 263 | +} |
89 | 264 | + | |
90 | - gen_set_gpr(ctx, a->rd, dest); | 265 | +static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a) |
91 | + TCGv src1h = get_gprh(ctx, a->rs1); | 266 | +{ |
92 | + TCGv src2h = tcg_constant_tl(-(a->imm < 0)); | 267 | + return zvksed_check(s) && |
93 | + TCGv desth = dest_gprh(ctx, a->rd); | 268 | + require_align(a->rd, s->lmul) && |
94 | + | 269 | + require_align(a->rs2, s->lmul); |
95 | + f128(dest, desth, src1, src1h, src2, src2h); | 270 | +} |
96 | + gen_set_gpr128(ctx, a->rd, dest, desth); | 271 | + |
97 | + } | 272 | +GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS) |
98 | return true; | 273 | + |
99 | } | 274 | +static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a) |
100 | 275 | +{ | |
101 | static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext, | 276 | + return zvksed_check(s) && |
102 | - void (*func)(TCGv, TCGv, TCGv)) | 277 | + require_align(a->rd, s->lmul) && |
103 | + void (*func)(TCGv, TCGv, TCGv), | 278 | + require_align(a->rs2, s->lmul); |
104 | + void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) | 279 | +} |
105 | { | 280 | + |
106 | TCGv dest = dest_gpr(ctx, a->rd); | 281 | +GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS) |
107 | TCGv src1 = get_gpr(ctx, a->rs1, ext); | 282 | + |
108 | TCGv src2 = get_gpr(ctx, a->rs2, ext); | 283 | +static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a) |
109 | 284 | +{ | |
110 | - func(dest, src1, src2); | 285 | + return zvksed_check(s) && |
111 | + if (get_ol(ctx) < MXL_RV128) { | 286 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) && |
112 | + func(dest, src1, src2); | 287 | + require_align(a->rd, s->lmul); |
113 | + gen_set_gpr(ctx, a->rd, dest); | 288 | +} |
114 | + } else { | 289 | + |
115 | + if (f128 == NULL) { | 290 | +GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS) |
116 | + return false; | ||
117 | + } | ||
118 | |||
119 | - gen_set_gpr(ctx, a->rd, dest); | ||
120 | + TCGv src1h = get_gprh(ctx, a->rs1); | ||
121 | + TCGv src2h = get_gprh(ctx, a->rs2); | ||
122 | + TCGv desth = dest_gprh(ctx, a->rd); | ||
123 | + | ||
124 | + f128(dest, desth, src1, src1h, src2, src2h); | ||
125 | + gen_set_gpr128(ctx, a->rd, dest, desth); | ||
126 | + } | ||
127 | return true; | ||
128 | } | ||
129 | |||
130 | static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext, | ||
131 | void (*f_tl)(TCGv, TCGv, TCGv), | ||
132 | - void (*f_32)(TCGv, TCGv, TCGv)) | ||
133 | + void (*f_32)(TCGv, TCGv, TCGv), | ||
134 | + void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv)) | ||
135 | { | ||
136 | int olen = get_olen(ctx); | ||
137 | |||
138 | if (olen != TARGET_LONG_BITS) { | ||
139 | if (olen == 32) { | ||
140 | f_tl = f_32; | ||
141 | - } else { | ||
142 | + } else if (olen != 128) { | ||
143 | g_assert_not_reached(); | ||
144 | } | ||
145 | } | ||
146 | - return gen_arith(ctx, a, ext, f_tl); | ||
147 | + return gen_arith(ctx, a, ext, f_tl, f_128); | ||
148 | } | ||
149 | |||
150 | static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext, | ||
151 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | ||
152 | index XXXXXXX..XXXXXXX 100644 | ||
153 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | ||
154 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | ||
155 | @@ -XXX,XX +XXX,XX @@ static bool trans_xnor(DisasContext *ctx, arg_xnor *a) | ||
156 | static bool trans_min(DisasContext *ctx, arg_min *a) | ||
157 | { | ||
158 | REQUIRE_ZBB(ctx); | ||
159 | - return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl); | ||
160 | + return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl, NULL); | ||
161 | } | ||
162 | |||
163 | static bool trans_max(DisasContext *ctx, arg_max *a) | ||
164 | { | ||
165 | REQUIRE_ZBB(ctx); | ||
166 | - return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl); | ||
167 | + return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl, NULL); | ||
168 | } | ||
169 | |||
170 | static bool trans_minu(DisasContext *ctx, arg_minu *a) | ||
171 | { | ||
172 | REQUIRE_ZBB(ctx); | ||
173 | - return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl); | ||
174 | + return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl, NULL); | ||
175 | } | ||
176 | |||
177 | static bool trans_maxu(DisasContext *ctx, arg_maxu *a) | ||
178 | { | ||
179 | REQUIRE_ZBB(ctx); | ||
180 | - return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl); | ||
181 | + return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl, NULL); | ||
182 | } | ||
183 | |||
184 | static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a) | ||
185 | @@ -XXX,XX +XXX,XX @@ GEN_SHADD(3) | ||
186 | static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \ | ||
187 | { \ | ||
188 | REQUIRE_ZBA(ctx); \ | ||
189 | - return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add); \ | ||
190 | + return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add, NULL); \ | ||
191 | } | ||
192 | |||
193 | GEN_TRANS_SHADD(1) | ||
194 | @@ -XXX,XX +XXX,XX @@ static bool trans_sh##SHAMT##add_uw(DisasContext *ctx, \ | ||
195 | { \ | ||
196 | REQUIRE_64BIT(ctx); \ | ||
197 | REQUIRE_ZBA(ctx); \ | ||
198 | - return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw); \ | ||
199 | + return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw, NULL); \ | ||
200 | } | ||
201 | |||
202 | GEN_TRANS_SHADD_UW(1) | ||
203 | @@ -XXX,XX +XXX,XX @@ static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a) | ||
204 | { | ||
205 | REQUIRE_64BIT(ctx); | ||
206 | REQUIRE_ZBA(ctx); | ||
207 | - return gen_arith(ctx, a, EXT_NONE, gen_add_uw); | ||
208 | + return gen_arith(ctx, a, EXT_NONE, gen_add_uw, NULL); | ||
209 | } | ||
210 | |||
211 | static void gen_slli_uw(TCGv dest, TCGv src, target_long shamt) | ||
212 | @@ -XXX,XX +XXX,XX @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a) | ||
213 | static bool trans_clmul(DisasContext *ctx, arg_clmul *a) | ||
214 | { | ||
215 | REQUIRE_ZBC(ctx); | ||
216 | - return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul); | ||
217 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul, NULL); | ||
218 | } | ||
219 | |||
220 | static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) | ||
221 | @@ -XXX,XX +XXX,XX @@ static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) | ||
222 | static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a) | ||
223 | { | ||
224 | REQUIRE_ZBC(ctx); | ||
225 | - return gen_arith(ctx, a, EXT_NONE, gen_clmulh); | ||
226 | + return gen_arith(ctx, a, EXT_NONE, gen_clmulh, NULL); | ||
227 | } | ||
228 | |||
229 | static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a) | ||
230 | { | ||
231 | REQUIRE_ZBC(ctx); | ||
232 | - return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr); | ||
233 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr, NULL); | ||
234 | } | ||
235 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
236 | index XXXXXXX..XXXXXXX 100644 | ||
237 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
238 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
239 | @@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) | ||
240 | return true; | ||
241 | } | ||
242 | |||
243 | +static TCGCond gen_compare_i128(bool bz, TCGv rl, | ||
244 | + TCGv al, TCGv ah, TCGv bl, TCGv bh, | ||
245 | + TCGCond cond) | ||
246 | +{ | ||
247 | + TCGv rh = tcg_temp_new(); | ||
248 | + bool invert = false; | ||
249 | + | ||
250 | + switch (cond) { | ||
251 | + case TCG_COND_EQ: | ||
252 | + case TCG_COND_NE: | ||
253 | + if (bz) { | ||
254 | + tcg_gen_or_tl(rl, al, ah); | ||
255 | + } else { | ||
256 | + tcg_gen_xor_tl(rl, al, bl); | ||
257 | + tcg_gen_xor_tl(rh, ah, bh); | ||
258 | + tcg_gen_or_tl(rl, rl, rh); | ||
259 | + } | ||
260 | + break; | ||
261 | + | ||
262 | + case TCG_COND_GE: | ||
263 | + case TCG_COND_LT: | ||
264 | + if (bz) { | ||
265 | + tcg_gen_mov_tl(rl, ah); | ||
266 | + } else { | ||
267 | + TCGv tmp = tcg_temp_new(); | ||
268 | + | ||
269 | + tcg_gen_sub2_tl(rl, rh, al, ah, bl, bh); | ||
270 | + tcg_gen_xor_tl(rl, rh, ah); | ||
271 | + tcg_gen_xor_tl(tmp, ah, bh); | ||
272 | + tcg_gen_and_tl(rl, rl, tmp); | ||
273 | + tcg_gen_xor_tl(rl, rh, rl); | ||
274 | + | ||
275 | + tcg_temp_free(tmp); | ||
276 | + } | ||
277 | + break; | ||
278 | + | ||
279 | + case TCG_COND_LTU: | ||
280 | + invert = true; | ||
281 | + /* fallthrough */ | ||
282 | + case TCG_COND_GEU: | ||
283 | + { | ||
284 | + TCGv tmp = tcg_temp_new(); | ||
285 | + TCGv zero = tcg_constant_tl(0); | ||
286 | + TCGv one = tcg_constant_tl(1); | ||
287 | + | ||
288 | + cond = TCG_COND_NE; | ||
289 | + /* borrow in to second word */ | ||
290 | + tcg_gen_setcond_tl(TCG_COND_LTU, tmp, al, bl); | ||
291 | + /* seed third word with 1, which will be result */ | ||
292 | + tcg_gen_sub2_tl(tmp, rh, ah, one, tmp, zero); | ||
293 | + tcg_gen_sub2_tl(tmp, rl, tmp, rh, bh, zero); | ||
294 | + | ||
295 | + tcg_temp_free(tmp); | ||
296 | + } | ||
297 | + break; | ||
298 | + | ||
299 | + default: | ||
300 | + g_assert_not_reached(); | ||
301 | + } | ||
302 | + | ||
303 | + if (invert) { | ||
304 | + cond = tcg_invert_cond(cond); | ||
305 | + } | ||
306 | + | ||
307 | + tcg_temp_free(rh); | ||
308 | + return cond; | ||
309 | +} | ||
310 | + | ||
311 | +static void gen_setcond_i128(TCGv rl, TCGv rh, | ||
312 | + TCGv src1l, TCGv src1h, | ||
313 | + TCGv src2l, TCGv src2h, | ||
314 | + TCGCond cond) | ||
315 | +{ | ||
316 | + cond = gen_compare_i128(false, rl, src1l, src1h, src2l, src2h, cond); | ||
317 | + tcg_gen_setcondi_tl(cond, rl, rl, 0); | ||
318 | + tcg_gen_movi_tl(rh, 0); | ||
319 | +} | ||
320 | + | ||
321 | static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) | ||
322 | { | ||
323 | TCGLabel *l = gen_new_label(); | ||
324 | TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
325 | TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN); | ||
326 | |||
327 | - tcg_gen_brcond_tl(cond, src1, src2, l); | ||
328 | + if (get_xl(ctx) == MXL_RV128) { | ||
329 | + TCGv src1h = get_gprh(ctx, a->rs1); | ||
330 | + TCGv src2h = get_gprh(ctx, a->rs2); | ||
331 | + TCGv tmp = tcg_temp_new(); | ||
332 | + | ||
333 | + cond = gen_compare_i128(a->rs2 == 0, | ||
334 | + tmp, src1, src1h, src2, src2h, cond); | ||
335 | + tcg_gen_brcondi_tl(cond, tmp, 0, l); | ||
336 | + | ||
337 | + tcg_temp_free(tmp); | ||
338 | + } else { | ||
339 | + tcg_gen_brcond_tl(cond, src1, src2, l); | ||
340 | + } | ||
341 | gen_goto_tb(ctx, 1, ctx->pc_succ_insn); | ||
342 | |||
343 | gen_set_label(l); /* branch taken */ | ||
344 | @@ -XXX,XX +XXX,XX @@ static bool trans_sq(DisasContext *ctx, arg_sq *a) | ||
345 | return gen_store(ctx, a, MO_TEUO); | ||
346 | } | ||
347 | |||
348 | +static bool trans_addd(DisasContext *ctx, arg_addd *a) | ||
349 | +{ | ||
350 | + REQUIRE_128BIT(ctx); | ||
351 | + ctx->ol = MXL_RV64; | ||
352 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl, NULL); | ||
353 | +} | ||
354 | + | ||
355 | +static bool trans_addid(DisasContext *ctx, arg_addid *a) | ||
356 | +{ | ||
357 | + REQUIRE_128BIT(ctx); | ||
358 | + ctx->ol = MXL_RV64; | ||
359 | + return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl, NULL); | ||
360 | +} | ||
361 | + | ||
362 | +static bool trans_subd(DisasContext *ctx, arg_subd *a) | ||
363 | +{ | ||
364 | + REQUIRE_128BIT(ctx); | ||
365 | + ctx->ol = MXL_RV64; | ||
366 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl, NULL); | ||
367 | +} | ||
368 | + | ||
369 | +static void gen_addi2_i128(TCGv retl, TCGv reth, | ||
370 | + TCGv srcl, TCGv srch, target_long imm) | ||
371 | +{ | ||
372 | + TCGv imml = tcg_constant_tl(imm); | ||
373 | + TCGv immh = tcg_constant_tl(-(imm < 0)); | ||
374 | + tcg_gen_add2_tl(retl, reth, srcl, srch, imml, immh); | ||
375 | +} | ||
376 | + | ||
377 | static bool trans_addi(DisasContext *ctx, arg_addi *a) | ||
378 | { | ||
379 | - return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl); | ||
380 | + return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl, gen_addi2_i128); | ||
381 | } | ||
382 | |||
383 | static void gen_slt(TCGv ret, TCGv s1, TCGv s2) | ||
384 | @@ -XXX,XX +XXX,XX @@ static void gen_slt(TCGv ret, TCGv s1, TCGv s2) | ||
385 | tcg_gen_setcond_tl(TCG_COND_LT, ret, s1, s2); | ||
386 | } | ||
387 | |||
388 | +static void gen_slt_i128(TCGv retl, TCGv reth, | ||
389 | + TCGv s1l, TCGv s1h, TCGv s2l, TCGv s2h) | ||
390 | +{ | ||
391 | + gen_setcond_i128(retl, reth, s1l, s1h, s2l, s2h, TCG_COND_LT); | ||
392 | +} | ||
393 | + | ||
394 | static void gen_sltu(TCGv ret, TCGv s1, TCGv s2) | ||
395 | { | ||
396 | tcg_gen_setcond_tl(TCG_COND_LTU, ret, s1, s2); | ||
397 | } | ||
398 | |||
399 | +static void gen_sltu_i128(TCGv retl, TCGv reth, | ||
400 | + TCGv s1l, TCGv s1h, TCGv s2l, TCGv s2h) | ||
401 | +{ | ||
402 | + gen_setcond_i128(retl, reth, s1l, s1h, s2l, s2h, TCG_COND_LTU); | ||
403 | +} | ||
404 | + | ||
405 | static bool trans_slti(DisasContext *ctx, arg_slti *a) | ||
406 | { | ||
407 | - return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_slt); | ||
408 | + return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_slt, gen_slt_i128); | ||
409 | } | ||
410 | |||
411 | static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a) | ||
412 | { | ||
413 | - return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_sltu); | ||
414 | + return gen_arith_imm_tl(ctx, a, EXT_SIGN, gen_sltu, gen_sltu_i128); | ||
415 | } | ||
416 | |||
417 | static bool trans_xori(DisasContext *ctx, arg_xori *a) | ||
418 | @@ -XXX,XX +XXX,XX @@ static bool trans_srai(DisasContext *ctx, arg_srai *a) | ||
419 | |||
420 | static bool trans_add(DisasContext *ctx, arg_add *a) | ||
421 | { | ||
422 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl); | ||
423 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl, tcg_gen_add2_tl); | ||
424 | } | ||
425 | |||
426 | static bool trans_sub(DisasContext *ctx, arg_sub *a) | ||
427 | { | ||
428 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl); | ||
429 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl, tcg_gen_sub2_tl); | ||
430 | } | ||
431 | |||
432 | static void gen_sll_i128(TCGv destl, TCGv desth, | ||
433 | @@ -XXX,XX +XXX,XX @@ static bool trans_sll(DisasContext *ctx, arg_sll *a) | ||
434 | |||
435 | static bool trans_slt(DisasContext *ctx, arg_slt *a) | ||
436 | { | ||
437 | - return gen_arith(ctx, a, EXT_SIGN, gen_slt); | ||
438 | + return gen_arith(ctx, a, EXT_SIGN, gen_slt, gen_slt_i128); | ||
439 | } | ||
440 | |||
441 | static bool trans_sltu(DisasContext *ctx, arg_sltu *a) | ||
442 | { | ||
443 | - return gen_arith(ctx, a, EXT_SIGN, gen_sltu); | ||
444 | + return gen_arith(ctx, a, EXT_SIGN, gen_sltu, gen_sltu_i128); | ||
445 | } | ||
446 | |||
447 | static void gen_srl_i128(TCGv destl, TCGv desth, | ||
448 | @@ -XXX,XX +XXX,XX @@ static bool trans_and(DisasContext *ctx, arg_and *a) | ||
449 | |||
450 | static bool trans_addiw(DisasContext *ctx, arg_addiw *a) | ||
451 | { | ||
452 | - REQUIRE_64BIT(ctx); | ||
453 | + REQUIRE_64_OR_128BIT(ctx); | ||
454 | ctx->ol = MXL_RV32; | ||
455 | - return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl); | ||
456 | + return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl, NULL); | ||
457 | } | ||
458 | |||
459 | static bool trans_slliw(DisasContext *ctx, arg_slliw *a) | ||
460 | @@ -XXX,XX +XXX,XX @@ static bool trans_sraid(DisasContext *ctx, arg_sraid *a) | ||
461 | |||
462 | static bool trans_addw(DisasContext *ctx, arg_addw *a) | ||
463 | { | ||
464 | - REQUIRE_64BIT(ctx); | ||
465 | + REQUIRE_64_OR_128BIT(ctx); | ||
466 | ctx->ol = MXL_RV32; | ||
467 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl); | ||
468 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl, NULL); | ||
469 | } | ||
470 | |||
471 | static bool trans_subw(DisasContext *ctx, arg_subw *a) | ||
472 | { | ||
473 | - REQUIRE_64BIT(ctx); | ||
474 | + REQUIRE_64_OR_128BIT(ctx); | ||
475 | ctx->ol = MXL_RV32; | ||
476 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl); | ||
477 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl, NULL); | ||
478 | } | ||
479 | |||
480 | static bool trans_sllw(DisasContext *ctx, arg_sllw *a) | ||
481 | diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc | ||
482 | index XXXXXXX..XXXXXXX 100644 | ||
483 | --- a/target/riscv/insn_trans/trans_rvm.c.inc | ||
484 | +++ b/target/riscv/insn_trans/trans_rvm.c.inc | ||
485 | @@ -XXX,XX +XXX,XX @@ | ||
486 | static bool trans_mul(DisasContext *ctx, arg_mul *a) | ||
487 | { | ||
488 | REQUIRE_EXT(ctx, RVM); | ||
489 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl); | ||
490 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL); | ||
491 | } | ||
492 | |||
493 | static void gen_mulh(TCGv ret, TCGv s1, TCGv s2) | ||
494 | @@ -XXX,XX +XXX,XX @@ static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2) | ||
495 | static bool trans_mulh(DisasContext *ctx, arg_mulh *a) | ||
496 | { | ||
497 | REQUIRE_EXT(ctx, RVM); | ||
498 | - return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w); | ||
499 | + return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w, NULL); | ||
500 | } | ||
501 | |||
502 | static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2) | ||
503 | @@ -XXX,XX +XXX,XX @@ static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2) | ||
504 | static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a) | ||
505 | { | ||
506 | REQUIRE_EXT(ctx, RVM); | ||
507 | - return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w); | ||
508 | + return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w, NULL); | ||
509 | } | ||
510 | |||
511 | static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2) | ||
512 | @@ -XXX,XX +XXX,XX @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a) | ||
513 | { | ||
514 | REQUIRE_EXT(ctx, RVM); | ||
515 | /* gen_mulh_w works for either sign as input. */ | ||
516 | - return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w); | ||
517 | + return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w, NULL); | ||
518 | } | ||
519 | |||
520 | static void gen_div(TCGv ret, TCGv source1, TCGv source2) | ||
521 | @@ -XXX,XX +XXX,XX @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2) | ||
522 | static bool trans_div(DisasContext *ctx, arg_div *a) | ||
523 | { | ||
524 | REQUIRE_EXT(ctx, RVM); | ||
525 | - return gen_arith(ctx, a, EXT_SIGN, gen_div); | ||
526 | + return gen_arith(ctx, a, EXT_SIGN, gen_div, NULL); | ||
527 | } | ||
528 | |||
529 | static void gen_divu(TCGv ret, TCGv source1, TCGv source2) | ||
530 | @@ -XXX,XX +XXX,XX @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2) | ||
531 | static bool trans_divu(DisasContext *ctx, arg_divu *a) | ||
532 | { | ||
533 | REQUIRE_EXT(ctx, RVM); | ||
534 | - return gen_arith(ctx, a, EXT_ZERO, gen_divu); | ||
535 | + return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); | ||
536 | } | ||
537 | |||
538 | static void gen_rem(TCGv ret, TCGv source1, TCGv source2) | ||
539 | @@ -XXX,XX +XXX,XX @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2) | ||
540 | static bool trans_rem(DisasContext *ctx, arg_rem *a) | ||
541 | { | ||
542 | REQUIRE_EXT(ctx, RVM); | ||
543 | - return gen_arith(ctx, a, EXT_SIGN, gen_rem); | ||
544 | + return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); | ||
545 | } | ||
546 | |||
547 | static void gen_remu(TCGv ret, TCGv source1, TCGv source2) | ||
548 | @@ -XXX,XX +XXX,XX @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2) | ||
549 | static bool trans_remu(DisasContext *ctx, arg_remu *a) | ||
550 | { | ||
551 | REQUIRE_EXT(ctx, RVM); | ||
552 | - return gen_arith(ctx, a, EXT_ZERO, gen_remu); | ||
553 | + return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); | ||
554 | } | ||
555 | |||
556 | static bool trans_mulw(DisasContext *ctx, arg_mulw *a) | ||
557 | @@ -XXX,XX +XXX,XX @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a) | ||
558 | REQUIRE_64BIT(ctx); | ||
559 | REQUIRE_EXT(ctx, RVM); | ||
560 | ctx->ol = MXL_RV32; | ||
561 | - return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl); | ||
562 | + return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL); | ||
563 | } | ||
564 | |||
565 | static bool trans_divw(DisasContext *ctx, arg_divw *a) | ||
566 | @@ -XXX,XX +XXX,XX @@ static bool trans_divw(DisasContext *ctx, arg_divw *a) | ||
567 | REQUIRE_64BIT(ctx); | ||
568 | REQUIRE_EXT(ctx, RVM); | ||
569 | ctx->ol = MXL_RV32; | ||
570 | - return gen_arith(ctx, a, EXT_SIGN, gen_div); | ||
571 | + return gen_arith(ctx, a, EXT_SIGN, gen_div, NULL); | ||
572 | } | ||
573 | |||
574 | static bool trans_divuw(DisasContext *ctx, arg_divuw *a) | ||
575 | @@ -XXX,XX +XXX,XX @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a) | ||
576 | REQUIRE_64BIT(ctx); | ||
577 | REQUIRE_EXT(ctx, RVM); | ||
578 | ctx->ol = MXL_RV32; | ||
579 | - return gen_arith(ctx, a, EXT_ZERO, gen_divu); | ||
580 | + return gen_arith(ctx, a, EXT_ZERO, gen_divu, NULL); | ||
581 | } | ||
582 | |||
583 | static bool trans_remw(DisasContext *ctx, arg_remw *a) | ||
584 | @@ -XXX,XX +XXX,XX @@ static bool trans_remw(DisasContext *ctx, arg_remw *a) | ||
585 | REQUIRE_64BIT(ctx); | ||
586 | REQUIRE_EXT(ctx, RVM); | ||
587 | ctx->ol = MXL_RV32; | ||
588 | - return gen_arith(ctx, a, EXT_SIGN, gen_rem); | ||
589 | + return gen_arith(ctx, a, EXT_SIGN, gen_rem, NULL); | ||
590 | } | ||
591 | |||
592 | static bool trans_remuw(DisasContext *ctx, arg_remuw *a) | ||
593 | @@ -XXX,XX +XXX,XX @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a) | ||
594 | REQUIRE_64BIT(ctx); | ||
595 | REQUIRE_EXT(ctx, RVM); | ||
596 | ctx->ol = MXL_RV32; | ||
597 | - return gen_arith(ctx, a, EXT_ZERO, gen_remu); | ||
598 | + return gen_arith(ctx, a, EXT_ZERO, gen_remu, NULL); | ||
599 | } | ||
600 | -- | 291 | -- |
601 | 2.31.1 | 292 | 2.41.0 |
602 | |||
603 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Rob Bradford <rbradford@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | Given the side effects they have, the csr instructions are realized as | 3 | These are WARL fields - zero out the bits for unavailable counters and |
4 | helpers. We extend this existing infrastructure for 128-bit sized csr. | 4 | special case the TM bit in mcountinhibit which is hardwired to zero. |
5 | We return 128-bit values using the same approach as for div/rem. | 5 | This patch achieves this by modifying the value written so that any use |
6 | Theses helpers all call a unique function that is currently a fallback | 6 | of the field will see the correctly masked bits. |
7 | on the 64-bit version. | ||
8 | The trans_csrxx functions supporting 128-bit are yet to be implemented. | ||
9 | 7 | ||
10 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 8 | Tested by modifying OpenSBI to write max value to these CSRs and upon |
11 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 9 | subsequent read the appropriate number of bits for number of PMUs is |
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 10 | enabled and the TM bit is zero in mcountinhibit. |
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | |
14 | Message-id: 20220106210108.138226-17-frederic.petrot@univ-grenoble-alpes.fr | 12 | Signed-off-by: Rob Bradford <rbradford@rivosinc.com> |
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Reviewed-by: Atish Patra <atishp@rivosinc.com> | ||
15 | Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 17 | --- |
17 | target/riscv/cpu.h | 5 +++++ | 18 | target/riscv/csr.c | 11 +++++++++-- |
18 | target/riscv/helper.h | 3 +++ | 19 | 1 file changed, 9 insertions(+), 2 deletions(-) |
19 | target/riscv/csr.c | 17 ++++++++++++++++ | ||
20 | target/riscv/op_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++ | ||
21 | 4 files changed, 69 insertions(+) | ||
22 | 20 | ||
23 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/target/riscv/cpu.h | ||
26 | +++ b/target/riscv/cpu.h | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
28 | #include "exec/cpu-defs.h" | ||
29 | #include "fpu/softfloat-types.h" | ||
30 | #include "qom/object.h" | ||
31 | +#include "qemu/int128.h" | ||
32 | #include "cpu_bits.h" | ||
33 | |||
34 | #define TCG_GUEST_DEFAULT_MO 0 | ||
35 | @@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno, | ||
36 | target_ulong new_value, | ||
37 | target_ulong write_mask); | ||
38 | |||
39 | +RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, | ||
40 | + Int128 *ret_value, | ||
41 | + Int128 new_value, Int128 write_mask); | ||
42 | + | ||
43 | typedef struct { | ||
44 | const char *name; | ||
45 | riscv_csr_predicate_fn predicate; | ||
46 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
47 | index XXXXXXX..XXXXXXX 100644 | ||
48 | --- a/target/riscv/helper.h | ||
49 | +++ b/target/riscv/helper.h | ||
50 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64) | ||
51 | DEF_HELPER_2(csrr, tl, env, int) | ||
52 | DEF_HELPER_3(csrw, void, env, int, tl) | ||
53 | DEF_HELPER_4(csrrw, tl, env, int, tl, tl) | ||
54 | +DEF_HELPER_2(csrr_i128, tl, env, int) | ||
55 | +DEF_HELPER_4(csrw_i128, void, env, int, tl, tl) | ||
56 | +DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl) | ||
57 | #ifndef CONFIG_USER_ONLY | ||
58 | DEF_HELPER_2(sret, tl, env, tl) | ||
59 | DEF_HELPER_2(mret, tl, env, tl) | ||
60 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 21 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
61 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
62 | --- a/target/riscv/csr.c | 23 | --- a/target/riscv/csr.c |
63 | +++ b/target/riscv/csr.c | 24 | +++ b/target/riscv/csr.c |
64 | @@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | 25 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno, |
26 | { | ||
27 | int cidx; | ||
28 | PMUCTRState *counter; | ||
29 | + RISCVCPU *cpu = env_archcpu(env); | ||
30 | |||
31 | - env->mcountinhibit = val; | ||
32 | + /* WARL register - disable unavailable counters; TM bit is always 0 */ | ||
33 | + env->mcountinhibit = | ||
34 | + val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR); | ||
35 | |||
36 | /* Check if any other counter is also monitoring cycles/instructions */ | ||
37 | for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) { | ||
38 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno, | ||
39 | static RISCVException write_mcounteren(CPURISCVState *env, int csrno, | ||
40 | target_ulong val) | ||
41 | { | ||
42 | - env->mcounteren = val; | ||
43 | + RISCVCPU *cpu = env_archcpu(env); | ||
44 | + | ||
45 | + /* WARL register - disable unavailable counters */ | ||
46 | + env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM | | ||
47 | + COUNTEREN_IR); | ||
65 | return RISCV_EXCP_NONE; | 48 | return RISCV_EXCP_NONE; |
66 | } | 49 | } |
67 | 50 | ||
68 | +RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, | ||
69 | + Int128 *ret_value, | ||
70 | + Int128 new_value, Int128 write_mask) | ||
71 | +{ | ||
72 | + /* fall back to 64-bit version for now */ | ||
73 | + target_ulong ret_64; | ||
74 | + RISCVException ret = riscv_csrrw(env, csrno, &ret_64, | ||
75 | + int128_getlo(new_value), | ||
76 | + int128_getlo(write_mask)); | ||
77 | + | ||
78 | + if (ret_value) { | ||
79 | + *ret_value = int128_make64(ret_64); | ||
80 | + } | ||
81 | + | ||
82 | + return ret; | ||
83 | +} | ||
84 | + | ||
85 | /* | ||
86 | * Debugger support. If not in user mode, set env->debugger before the | ||
87 | * riscv_csrrw call and clear it after the call. | ||
88 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/target/riscv/op_helper.c | ||
91 | +++ b/target/riscv/op_helper.c | ||
92 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr, | ||
93 | return val; | ||
94 | } | ||
95 | |||
96 | +target_ulong helper_csrr_i128(CPURISCVState *env, int csr) | ||
97 | +{ | ||
98 | + Int128 rv = int128_zero(); | ||
99 | + RISCVException ret = riscv_csrrw_i128(env, csr, &rv, | ||
100 | + int128_zero(), | ||
101 | + int128_zero()); | ||
102 | + | ||
103 | + if (ret != RISCV_EXCP_NONE) { | ||
104 | + riscv_raise_exception(env, ret, GETPC()); | ||
105 | + } | ||
106 | + | ||
107 | + env->retxh = int128_gethi(rv); | ||
108 | + return int128_getlo(rv); | ||
109 | +} | ||
110 | + | ||
111 | +void helper_csrw_i128(CPURISCVState *env, int csr, | ||
112 | + target_ulong srcl, target_ulong srch) | ||
113 | +{ | ||
114 | + RISCVException ret = riscv_csrrw_i128(env, csr, NULL, | ||
115 | + int128_make128(srcl, srch), | ||
116 | + UINT128_MAX); | ||
117 | + | ||
118 | + if (ret != RISCV_EXCP_NONE) { | ||
119 | + riscv_raise_exception(env, ret, GETPC()); | ||
120 | + } | ||
121 | +} | ||
122 | + | ||
123 | +target_ulong helper_csrrw_i128(CPURISCVState *env, int csr, | ||
124 | + target_ulong srcl, target_ulong srch, | ||
125 | + target_ulong maskl, target_ulong maskh) | ||
126 | +{ | ||
127 | + Int128 rv = int128_zero(); | ||
128 | + RISCVException ret = riscv_csrrw_i128(env, csr, &rv, | ||
129 | + int128_make128(srcl, srch), | ||
130 | + int128_make128(maskl, maskh)); | ||
131 | + | ||
132 | + if (ret != RISCV_EXCP_NONE) { | ||
133 | + riscv_raise_exception(env, ret, GETPC()); | ||
134 | + } | ||
135 | + | ||
136 | + env->retxh = int128_gethi(rv); | ||
137 | + return int128_getlo(rv); | ||
138 | +} | ||
139 | + | ||
140 | #ifndef CONFIG_USER_ONLY | ||
141 | |||
142 | target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) | ||
143 | -- | 51 | -- |
144 | 2.31.1 | 52 | 2.41.0 |
145 | |||
146 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Jason Chien <jason.chien@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Let's enable the Hypervisor extension by default. This doesn't affect | 3 | RVA23 Profiles states: |
4 | named CPUs (such as lowrisc-ibex or sifive-u54) but does enable the | 4 | The RVA23 profiles are intended to be used for 64-bit application |
5 | Hypervisor extensions by default for the virt machine. | 5 | processors that will run rich OS stacks from standard binary OS |
6 | distributions and with a substantial number of third-party binary user | ||
7 | applications that will be supported over a considerable length of time | ||
8 | in the field. | ||
6 | 9 | ||
10 | The chapter 4 of the unprivileged spec introduces the Zihintntl extension | ||
11 | and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose | ||
12 | purpose is to enable application and operating system portability across | ||
13 | different implementations. Thus the DTS should contain the Zihintntl ISA | ||
14 | string in order to pass to software. | ||
15 | |||
16 | The unprivileged spec states: | ||
17 | Like any HINTs, these instructions may be freely ignored. Hence, although | ||
18 | they are described in terms of cache-based memory hierarchies, they do not | ||
19 | mandate the provision of caches. | ||
20 | |||
21 | These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2, | ||
22 | which QEMU already supports, and QEMU does not emulate cache. Therefore | ||
23 | these instructions can be considered as a no-op, and we only need to add | ||
24 | a new property for the Zihintntl extension. | ||
25 | |||
26 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
27 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
28 | Signed-off-by: Jason Chien <jason.chien@sifive.com> | ||
29 | Message-ID: <20230726074049.19505-2-jason.chien@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 30 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Anup Patel <anup.patel@wdc.com> | ||
9 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
10 | Message-Id: <20220105213937.1113508-7-alistair.francis@opensource.wdc.com> | ||
11 | --- | 31 | --- |
12 | target/riscv/cpu.c | 2 +- | 32 | target/riscv/cpu_cfg.h | 1 + |
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | 33 | target/riscv/cpu.c | 2 ++ |
34 | 2 files changed, 3 insertions(+) | ||
14 | 35 | ||
36 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/target/riscv/cpu_cfg.h | ||
39 | +++ b/target/riscv/cpu_cfg.h | ||
40 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
41 | bool ext_icbom; | ||
42 | bool ext_icboz; | ||
43 | bool ext_zicond; | ||
44 | + bool ext_zihintntl; | ||
45 | bool ext_zihintpause; | ||
46 | bool ext_smstateen; | ||
47 | bool ext_sstc; | ||
15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 48 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
16 | index XXXXXXX..XXXXXXX 100644 | 49 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu.c | 50 | --- a/target/riscv/cpu.c |
18 | +++ b/target/riscv/cpu.c | 51 | +++ b/target/riscv/cpu.c |
19 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 52 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { |
20 | DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true), | 53 | ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond), |
21 | DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true), | 54 | ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr), |
22 | DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), | 55 | ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei), |
23 | - DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, false), | 56 | + ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl), |
24 | + DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true), | 57 | ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause), |
25 | DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true), | 58 | ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul), |
59 | ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs), | ||
60 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
61 | DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false), | ||
26 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | 62 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), |
27 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | 63 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), |
64 | + DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true), | ||
65 | DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true), | ||
66 | DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true), | ||
67 | DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true), | ||
28 | -- | 68 | -- |
29 | 2.31.1 | 69 | 2.41.0 |
30 | |||
31 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
---|---|---|---|
2 | 2 | ||
3 | The 128-bit bitwise instructions do not need any function prototype change | 3 | Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension. |
4 | as the functions can be applied independently on the lower and upper part of | 4 | However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s |
5 | the registers. | 5 | helper function. |
6 | 6 | ||
7 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 7 | Fixes: a47842d ("riscv: Add support for the Zfa extension") |
8 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 8 | Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
11 | Message-id: 20220106210108.138226-11-frederic.petrot@univ-grenoble-alpes.fr | 11 | Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com> |
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 13 | --- |
14 | target/riscv/translate.c | 21 +++++++++++++++++++-- | 14 | target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++-- |
15 | 1 file changed, 19 insertions(+), 2 deletions(-) | 15 | 1 file changed, 2 insertions(+), 2 deletions(-) |
16 | 16 | ||
17 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 17 | diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc |
18 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/translate.c | 19 | --- a/target/riscv/insn_trans/trans_rvzfa.c.inc |
20 | +++ b/target/riscv/translate.c | 20 | +++ b/target/riscv/insn_trans/trans_rvzfa.c.inc |
21 | @@ -XXX,XX +XXX,XX @@ static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a, | 21 | @@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a) |
22 | 22 | TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); | |
23 | func(dest, src1, a->imm); | 23 | TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); |
24 | 24 | ||
25 | - gen_set_gpr(ctx, a->rd, dest); | 25 | - gen_helper_fltq_s(dest, cpu_env, src1, src2); |
26 | + if (get_xl(ctx) == MXL_RV128) { | 26 | + gen_helper_fleq_d(dest, cpu_env, src1, src2); |
27 | + TCGv src1h = get_gprh(ctx, a->rs1); | 27 | gen_set_gpr(ctx, a->rd, dest); |
28 | + TCGv desth = dest_gprh(ctx, a->rd); | ||
29 | + | ||
30 | + func(desth, src1h, -(a->imm < 0)); | ||
31 | + gen_set_gpr128(ctx, a->rd, dest, desth); | ||
32 | + } else { | ||
33 | + gen_set_gpr(ctx, a->rd, dest); | ||
34 | + } | ||
35 | |||
36 | return true; | 28 | return true; |
37 | } | 29 | } |
38 | @@ -XXX,XX +XXX,XX @@ static bool gen_logic(DisasContext *ctx, arg_r *a, | 30 | @@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a) |
39 | 31 | TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); | |
40 | func(dest, src1, src2); | 32 | TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); |
41 | 33 | ||
42 | - gen_set_gpr(ctx, a->rd, dest); | 34 | - gen_helper_fltq_s(dest, cpu_env, src1, src2); |
43 | + if (get_xl(ctx) == MXL_RV128) { | 35 | + gen_helper_fltq_d(dest, cpu_env, src1, src2); |
44 | + TCGv src1h = get_gprh(ctx, a->rs1); | 36 | gen_set_gpr(ctx, a->rd, dest); |
45 | + TCGv src2h = get_gprh(ctx, a->rs2); | ||
46 | + TCGv desth = dest_gprh(ctx, a->rd); | ||
47 | + | ||
48 | + func(desth, src1h, src2h); | ||
49 | + gen_set_gpr128(ctx, a->rd, dest, desth); | ||
50 | + } else { | ||
51 | + gen_set_gpr(ctx, a->rd, dest); | ||
52 | + } | ||
53 | |||
54 | return true; | 37 | return true; |
55 | } | 38 | } |
56 | -- | 39 | -- |
57 | 2.31.1 | 40 | 2.41.0 |
58 | |||
59 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jason Chien <jason.chien@sifive.com> | ||
1 | 2 | ||
3 | When writing the upper mtime, we should keep the original lower mtime | ||
4 | whose value is given by cpu_riscv_read_rtc() instead of | ||
5 | cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime. | ||
6 | |||
7 | Signed-off-by: Jason Chien <jason.chien@sifive.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-ID: <20230728082502.26439-1-jason.chien@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | hw/intc/riscv_aclint.c | 5 +++-- | ||
13 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
14 | |||
15 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/hw/intc/riscv_aclint.c | ||
18 | +++ b/hw/intc/riscv_aclint.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
20 | return; | ||
21 | } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) { | ||
22 | uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq); | ||
23 | + uint64_t rtc = cpu_riscv_read_rtc(mtimer); | ||
24 | |||
25 | if (addr == mtimer->time_base) { | ||
26 | if (size == 4) { | ||
27 | /* time_lo for RV32/RV64 */ | ||
28 | - mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r; | ||
29 | + mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r; | ||
30 | } else { | ||
31 | /* time for RV64 */ | ||
32 | mtimer->time_delta = value - rtc_r; | ||
33 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
34 | } else { | ||
35 | if (size == 4) { | ||
36 | /* time_hi for RV32/RV64 */ | ||
37 | - mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r; | ||
38 | + mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r; | ||
39 | } else { | ||
40 | qemu_log_mask(LOG_GUEST_ERROR, | ||
41 | "aclint-mtimer: invalid time_hi write: %08x", | ||
42 | -- | ||
43 | 2.41.0 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Jason Chien <jason.chien@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | The stval and mtval registers can optionally contain the faulting | 3 | The variables whose values are given by cpu_riscv_read_rtc() should be named |
4 | instruction on an illegal instruction exception. This patch adds support | 4 | "rtc". The variables whose value are given by cpu_riscv_read_rtc_raw() |
5 | for setting the stval and mtval registers. | 5 | should be named "rtc_r". |
6 | 6 | ||
7 | The RISC-V spec states that "The stval register can optionally also be | 7 | Signed-off-by: Jason Chien <jason.chien@sifive.com> |
8 | used to return the faulting instruction bits on an illegal instruction | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | exception...". In this case we are always writing the value on an | 9 | Message-ID: <20230728082502.26439-2-jason.chien@sifive.com> |
10 | illegal instruction. | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | ||
12 | hw/intc/riscv_aclint.c | 6 +++--- | ||
13 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
11 | 14 | ||
12 | This doesn't match all CPUs (some CPUs won't write the data), but in | 15 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c |
13 | QEMU let's just populate the value on illegal instructions. This won't | ||
14 | break any guest software, but will provide more information to guests. | ||
15 | |||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
18 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
19 | Message-id: 20211220064916.107241-4-alistair.francis@opensource.wdc.com | ||
20 | --- | ||
21 | target/riscv/cpu.h | 2 ++ | ||
22 | target/riscv/cpu_helper.c | 3 +++ | ||
23 | target/riscv/translate.c | 3 +++ | ||
24 | 3 files changed, 8 insertions(+) | ||
25 | |||
26 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/target/riscv/cpu.h | 17 | --- a/hw/intc/riscv_aclint.c |
29 | +++ b/target/riscv/cpu.h | 18 | +++ b/hw/intc/riscv_aclint.c |
30 | @@ -XXX,XX +XXX,XX @@ struct CPURISCVState { | 19 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, |
31 | target_ulong frm; | 20 | uint64_t next; |
32 | 21 | uint64_t diff; | |
33 | target_ulong badaddr; | 22 | |
34 | + uint32_t bins; | 23 | - uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); |
35 | + | 24 | + uint64_t rtc = cpu_riscv_read_rtc(mtimer); |
36 | target_ulong guest_phys_fault_addr; | 25 | |
37 | 26 | /* Compute the relative hartid w.r.t the socket */ | |
38 | target_ulong priv_ver; | 27 | hartid = hartid - mtimer->hartid_base; |
39 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | 28 | |
40 | index XXXXXXX..XXXXXXX 100644 | 29 | mtimer->timecmp[hartid] = value; |
41 | --- a/target/riscv/cpu_helper.c | 30 | - if (mtimer->timecmp[hartid] <= rtc_r) { |
42 | +++ b/target/riscv/cpu_helper.c | 31 | + if (mtimer->timecmp[hartid] <= rtc) { |
43 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | 32 | /* |
44 | write_gva = true; | 33 | * If we're setting an MTIMECMP value in the "past", |
45 | tval = env->badaddr; | 34 | * immediately raise the timer interrupt |
46 | break; | 35 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, |
47 | + case RISCV_EXCP_ILLEGAL_INST: | 36 | |
48 | + tval = env->bins; | 37 | /* otherwise, set up the future timer interrupt */ |
49 | + break; | 38 | qemu_irq_lower(mtimer->timer_irqs[hartid]); |
50 | default: | 39 | - diff = mtimer->timecmp[hartid] - rtc_r; |
51 | break; | 40 | + diff = mtimer->timecmp[hartid] - rtc; |
52 | } | 41 | /* back to ns (note args switched in muldiv64) */ |
53 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 42 | uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); |
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/target/riscv/translate.c | ||
56 | +++ b/target/riscv/translate.c | ||
57 | @@ -XXX,XX +XXX,XX @@ static void generate_exception_mtval(DisasContext *ctx, int excp) | ||
58 | |||
59 | static void gen_exception_illegal(DisasContext *ctx) | ||
60 | { | ||
61 | + tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env, | ||
62 | + offsetof(CPURISCVState, bins)); | ||
63 | + | ||
64 | generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); | ||
65 | } | ||
66 | 43 | ||
67 | -- | 44 | -- |
68 | 2.31.1 | 45 | 2.41.0 |
69 | |||
70 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
---|---|---|---|
2 | 2 | ||
3 | Adding the high part of a very minimal set of csr. | 3 | We should not use types dependend on host arch for target_ucontext. |
4 | This bug is found when run rv32 applications. | ||
4 | 5 | ||
5 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> |
6 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
9 | Message-id: 20220106210108.138226-16-frederic.petrot@univ-grenoble-alpes.fr | 9 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
10 | Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 12 | --- |
12 | target/riscv/cpu.h | 4 ++++ | 13 | linux-user/riscv/signal.c | 4 ++-- |
13 | target/riscv/machine.c | 2 ++ | 14 | 1 file changed, 2 insertions(+), 2 deletions(-) |
14 | 2 files changed, 6 insertions(+) | ||
15 | 15 | ||
16 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 16 | diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/cpu.h | 18 | --- a/linux-user/riscv/signal.c |
19 | +++ b/target/riscv/cpu.h | 19 | +++ b/linux-user/riscv/signal.c |
20 | @@ -XXX,XX +XXX,XX @@ struct CPURISCVState { | 20 | @@ -XXX,XX +XXX,XX @@ struct target_sigcontext { |
21 | target_ulong hgatp; | 21 | }; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */ |
22 | uint64_t htimedelta; | 22 | |
23 | 23 | struct target_ucontext { | |
24 | + /* Upper 64-bits of 128-bit CSRs */ | 24 | - unsigned long uc_flags; |
25 | + uint64_t mscratchh; | 25 | - struct target_ucontext *uc_link; |
26 | + uint64_t sscratchh; | 26 | + abi_ulong uc_flags; |
27 | + | 27 | + abi_ptr uc_link; |
28 | /* Virtual CSRs */ | 28 | target_stack_t uc_stack; |
29 | /* | 29 | target_sigset_t uc_sigmask; |
30 | * For RV32 this is 32-bit vsstatus and 32-bit vsstatush. | 30 | uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)]; |
31 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/machine.c | ||
34 | +++ b/target/riscv/machine.c | ||
35 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_rv128 = { | ||
36 | .needed = rv128_needed, | ||
37 | .fields = (VMStateField[]) { | ||
38 | VMSTATE_UINTTL_ARRAY(env.gprh, RISCVCPU, 32), | ||
39 | + VMSTATE_UINT64(env.mscratchh, RISCVCPU), | ||
40 | + VMSTATE_UINT64(env.sscratchh, RISCVCPU), | ||
41 | VMSTATE_END_OF_LIST() | ||
42 | } | ||
43 | }; | ||
44 | -- | 31 | -- |
45 | 2.31.1 | 32 | 2.41.0 |
46 | 33 | ||
47 | 34 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Addition of div and rem on 128-bit integers, using the 128/64->128 divu and | 3 | In this patch, we create the APLIC and IMSIC FDT helper functions and |
4 | 64x64->128 mulu in host-utils. | 4 | remove M mode AIA devices when using KVM acceleration. |
5 | These operations will be used within div/rem helpers in the 128-bit riscv | ||
6 | target. | ||
7 | 5 | ||
8 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
9 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | Message-id: 20220106210108.138226-4-frederic.petrot@univ-grenoble-alpes.fr | 9 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
10 | Message-ID: <20230727102439.22554-2-yongxuan.wang@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 | include/qemu/int128.h | 27 ++++++++ | 13 | hw/riscv/virt.c | 290 +++++++++++++++++++++++------------------------- |
15 | util/int128.c | 147 ++++++++++++++++++++++++++++++++++++++++++ | 14 | 1 file changed, 137 insertions(+), 153 deletions(-) |
16 | util/meson.build | 1 + | ||
17 | 3 files changed, 175 insertions(+) | ||
18 | create mode 100644 util/int128.c | ||
19 | 15 | ||
20 | diff --git a/include/qemu/int128.h b/include/qemu/int128.h | 16 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
21 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/include/qemu/int128.h | 18 | --- a/hw/riscv/virt.c |
23 | +++ b/include/qemu/int128.h | 19 | +++ b/hw/riscv/virt.c |
24 | @@ -XXX,XX +XXX,XX @@ static inline Int128 bswap128(Int128 a) | 20 | @@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count) |
25 | #endif | 21 | return ret; |
26 | } | 22 | } |
27 | 23 | ||
28 | +static inline Int128 int128_divu(Int128 a, Int128 b) | 24 | -static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, |
25 | - uint32_t *phandle, uint32_t *intc_phandles, | ||
26 | - uint32_t *msi_m_phandle, uint32_t *msi_s_phandle) | ||
27 | +static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr, | ||
28 | + uint32_t *intc_phandles, uint32_t msi_phandle, | ||
29 | + bool m_mode, uint32_t imsic_guest_bits) | ||
30 | { | ||
31 | int cpu, socket; | ||
32 | char *imsic_name; | ||
33 | MachineState *ms = MACHINE(s); | ||
34 | int socket_count = riscv_socket_count(ms); | ||
35 | - uint32_t imsic_max_hart_per_socket, imsic_guest_bits; | ||
36 | + uint32_t imsic_max_hart_per_socket; | ||
37 | uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size; | ||
38 | |||
39 | - *msi_m_phandle = (*phandle)++; | ||
40 | - *msi_s_phandle = (*phandle)++; | ||
41 | imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2); | ||
42 | imsic_regs = g_new0(uint32_t, socket_count * 4); | ||
43 | |||
44 | - /* M-level IMSIC node */ | ||
45 | for (cpu = 0; cpu < ms->smp.cpus; cpu++) { | ||
46 | imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
47 | - imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT); | ||
48 | + imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT); | ||
49 | } | ||
50 | - imsic_max_hart_per_socket = 0; | ||
51 | - for (socket = 0; socket < socket_count; socket++) { | ||
52 | - imsic_addr = memmap[VIRT_IMSIC_M].base + | ||
53 | - socket * VIRT_IMSIC_GROUP_MAX_SIZE; | ||
54 | - imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts; | ||
55 | - imsic_regs[socket * 4 + 0] = 0; | ||
56 | - imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr); | ||
57 | - imsic_regs[socket * 4 + 2] = 0; | ||
58 | - imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size); | ||
59 | - if (imsic_max_hart_per_socket < s->soc[socket].num_harts) { | ||
60 | - imsic_max_hart_per_socket = s->soc[socket].num_harts; | ||
61 | - } | ||
62 | - } | ||
63 | - imsic_name = g_strdup_printf("/soc/imsics@%lx", | ||
64 | - (unsigned long)memmap[VIRT_IMSIC_M].base); | ||
65 | - qemu_fdt_add_subnode(ms->fdt, imsic_name); | ||
66 | - qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", | ||
67 | - "riscv,imsics"); | ||
68 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells", | ||
69 | - FDT_IMSIC_INT_CELLS); | ||
70 | - qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", | ||
71 | - NULL, 0); | ||
72 | - qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", | ||
73 | - NULL, 0); | ||
74 | - qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended", | ||
75 | - imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2); | ||
76 | - qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs, | ||
77 | - socket_count * sizeof(uint32_t) * 4); | ||
78 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids", | ||
79 | - VIRT_IRQCHIP_NUM_MSIS); | ||
80 | - if (socket_count > 1) { | ||
81 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits", | ||
82 | - imsic_num_bits(imsic_max_hart_per_socket)); | ||
83 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits", | ||
84 | - imsic_num_bits(socket_count)); | ||
85 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift", | ||
86 | - IMSIC_MMIO_GROUP_MIN_SHIFT); | ||
87 | - } | ||
88 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle); | ||
89 | - | ||
90 | - g_free(imsic_name); | ||
91 | |||
92 | - /* S-level IMSIC node */ | ||
93 | - for (cpu = 0; cpu < ms->smp.cpus; cpu++) { | ||
94 | - imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
95 | - imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); | ||
96 | - } | ||
97 | - imsic_guest_bits = imsic_num_bits(s->aia_guests + 1); | ||
98 | imsic_max_hart_per_socket = 0; | ||
99 | for (socket = 0; socket < socket_count; socket++) { | ||
100 | - imsic_addr = memmap[VIRT_IMSIC_S].base + | ||
101 | - socket * VIRT_IMSIC_GROUP_MAX_SIZE; | ||
102 | + imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE; | ||
103 | imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) * | ||
104 | s->soc[socket].num_harts; | ||
105 | imsic_regs[socket * 4 + 0] = 0; | ||
106 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, | ||
107 | imsic_max_hart_per_socket = s->soc[socket].num_harts; | ||
108 | } | ||
109 | } | ||
110 | - imsic_name = g_strdup_printf("/soc/imsics@%lx", | ||
111 | - (unsigned long)memmap[VIRT_IMSIC_S].base); | ||
112 | + | ||
113 | + imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr); | ||
114 | qemu_fdt_add_subnode(ms->fdt, imsic_name); | ||
115 | - qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", | ||
116 | - "riscv,imsics"); | ||
117 | + qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics"); | ||
118 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells", | ||
119 | - FDT_IMSIC_INT_CELLS); | ||
120 | - qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", | ||
121 | - NULL, 0); | ||
122 | - qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", | ||
123 | - NULL, 0); | ||
124 | + FDT_IMSIC_INT_CELLS); | ||
125 | + qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0); | ||
126 | + qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0); | ||
127 | qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended", | ||
128 | - imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2); | ||
129 | + imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2); | ||
130 | qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs, | ||
131 | - socket_count * sizeof(uint32_t) * 4); | ||
132 | + socket_count * sizeof(uint32_t) * 4); | ||
133 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids", | ||
134 | - VIRT_IRQCHIP_NUM_MSIS); | ||
135 | + VIRT_IRQCHIP_NUM_MSIS); | ||
136 | + | ||
137 | if (imsic_guest_bits) { | ||
138 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits", | ||
139 | - imsic_guest_bits); | ||
140 | + imsic_guest_bits); | ||
141 | } | ||
142 | + | ||
143 | if (socket_count > 1) { | ||
144 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits", | ||
145 | - imsic_num_bits(imsic_max_hart_per_socket)); | ||
146 | + imsic_num_bits(imsic_max_hart_per_socket)); | ||
147 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits", | ||
148 | - imsic_num_bits(socket_count)); | ||
149 | + imsic_num_bits(socket_count)); | ||
150 | qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift", | ||
151 | - IMSIC_MMIO_GROUP_MIN_SHIFT); | ||
152 | + IMSIC_MMIO_GROUP_MIN_SHIFT); | ||
153 | } | ||
154 | - qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle); | ||
155 | - g_free(imsic_name); | ||
156 | + qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle); | ||
157 | |||
158 | + g_free(imsic_name); | ||
159 | g_free(imsic_regs); | ||
160 | g_free(imsic_cells); | ||
161 | } | ||
162 | |||
163 | -static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
164 | - const MemMapEntry *memmap, int socket, | ||
165 | - uint32_t msi_m_phandle, | ||
166 | - uint32_t msi_s_phandle, | ||
167 | - uint32_t *phandle, | ||
168 | - uint32_t *intc_phandles, | ||
169 | - uint32_t *aplic_phandles) | ||
170 | +static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, | ||
171 | + uint32_t *phandle, uint32_t *intc_phandles, | ||
172 | + uint32_t *msi_m_phandle, uint32_t *msi_s_phandle) | ||
29 | +{ | 173 | +{ |
30 | + return (__uint128_t)a / (__uint128_t)b; | 174 | + *msi_m_phandle = (*phandle)++; |
175 | + *msi_s_phandle = (*phandle)++; | ||
176 | + | ||
177 | + if (!kvm_enabled()) { | ||
178 | + /* M-level IMSIC node */ | ||
179 | + create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles, | ||
180 | + *msi_m_phandle, true, 0); | ||
181 | + } | ||
182 | + | ||
183 | + /* S-level IMSIC node */ | ||
184 | + create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles, | ||
185 | + *msi_s_phandle, false, | ||
186 | + imsic_num_bits(s->aia_guests + 1)); | ||
187 | + | ||
31 | +} | 188 | +} |
32 | + | 189 | + |
33 | +static inline Int128 int128_remu(Int128 a, Int128 b) | 190 | +static void create_fdt_one_aplic(RISCVVirtState *s, int socket, |
191 | + unsigned long aplic_addr, uint32_t aplic_size, | ||
192 | + uint32_t msi_phandle, | ||
193 | + uint32_t *intc_phandles, | ||
194 | + uint32_t aplic_phandle, | ||
195 | + uint32_t aplic_child_phandle, | ||
196 | + bool m_mode) | ||
197 | { | ||
198 | int cpu; | ||
199 | char *aplic_name; | ||
200 | uint32_t *aplic_cells; | ||
201 | - unsigned long aplic_addr; | ||
202 | MachineState *ms = MACHINE(s); | ||
203 | - uint32_t aplic_m_phandle, aplic_s_phandle; | ||
204 | |||
205 | - aplic_m_phandle = (*phandle)++; | ||
206 | - aplic_s_phandle = (*phandle)++; | ||
207 | aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); | ||
208 | |||
209 | - /* M-level APLIC node */ | ||
210 | for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
211 | aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
212 | - aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT); | ||
213 | + aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT); | ||
214 | } | ||
215 | - aplic_addr = memmap[VIRT_APLIC_M].base + | ||
216 | - (memmap[VIRT_APLIC_M].size * socket); | ||
217 | + | ||
218 | aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr); | ||
219 | qemu_fdt_add_subnode(ms->fdt, aplic_name); | ||
220 | qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic"); | ||
221 | qemu_fdt_setprop_cell(ms->fdt, aplic_name, | ||
222 | - "#interrupt-cells", FDT_APLIC_INT_CELLS); | ||
223 | + "#interrupt-cells", FDT_APLIC_INT_CELLS); | ||
224 | qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0); | ||
225 | + | ||
226 | if (s->aia_type == VIRT_AIA_TYPE_APLIC) { | ||
227 | qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended", | ||
228 | - aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); | ||
229 | + aplic_cells, | ||
230 | + s->soc[socket].num_harts * sizeof(uint32_t) * 2); | ||
231 | } else { | ||
232 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", | ||
233 | - msi_m_phandle); | ||
234 | + qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle); | ||
235 | } | ||
236 | + | ||
237 | qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg", | ||
238 | - 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size); | ||
239 | + 0x0, aplic_addr, 0x0, aplic_size); | ||
240 | qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources", | ||
241 | - VIRT_IRQCHIP_NUM_SOURCES); | ||
242 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children", | ||
243 | - aplic_s_phandle); | ||
244 | - qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate", | ||
245 | - aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES); | ||
246 | + VIRT_IRQCHIP_NUM_SOURCES); | ||
247 | + | ||
248 | + if (aplic_child_phandle) { | ||
249 | + qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children", | ||
250 | + aplic_child_phandle); | ||
251 | + qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate", | ||
252 | + aplic_child_phandle, 0x1, | ||
253 | + VIRT_IRQCHIP_NUM_SOURCES); | ||
254 | + } | ||
255 | + | ||
256 | riscv_socket_fdt_write_id(ms, aplic_name, socket); | ||
257 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle); | ||
258 | + qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle); | ||
259 | + | ||
260 | g_free(aplic_name); | ||
261 | + g_free(aplic_cells); | ||
262 | +} | ||
263 | |||
264 | - /* S-level APLIC node */ | ||
265 | - for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
266 | - aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
267 | - aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); | ||
268 | +static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
269 | + const MemMapEntry *memmap, int socket, | ||
270 | + uint32_t msi_m_phandle, | ||
271 | + uint32_t msi_s_phandle, | ||
272 | + uint32_t *phandle, | ||
273 | + uint32_t *intc_phandles, | ||
274 | + uint32_t *aplic_phandles) | ||
34 | +{ | 275 | +{ |
35 | + return (__uint128_t)a % (__uint128_t)b; | 276 | + char *aplic_name; |
36 | +} | 277 | + unsigned long aplic_addr; |
37 | + | 278 | + MachineState *ms = MACHINE(s); |
38 | +static inline Int128 int128_divs(Int128 a, Int128 b) | 279 | + uint32_t aplic_m_phandle, aplic_s_phandle; |
39 | +{ | 280 | + |
40 | + return a / b; | 281 | + aplic_m_phandle = (*phandle)++; |
41 | +} | 282 | + aplic_s_phandle = (*phandle)++; |
42 | + | 283 | + |
43 | +static inline Int128 int128_rems(Int128 a, Int128 b) | 284 | + if (!kvm_enabled()) { |
44 | +{ | 285 | + /* M-level APLIC node */ |
45 | + return a % b; | 286 | + aplic_addr = memmap[VIRT_APLIC_M].base + |
46 | +} | 287 | + (memmap[VIRT_APLIC_M].size * socket); |
47 | + | 288 | + create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size, |
48 | #else /* !CONFIG_INT128 */ | 289 | + msi_m_phandle, intc_phandles, |
49 | 290 | + aplic_m_phandle, aplic_s_phandle, | |
50 | typedef struct Int128 Int128; | 291 | + true); |
51 | @@ -XXX,XX +XXX,XX @@ static inline Int128 bswap128(Int128 a) | 292 | } |
52 | return int128_make128(bswap64(a.hi), bswap64(a.lo)); | 293 | + |
294 | + /* S-level APLIC node */ | ||
295 | aplic_addr = memmap[VIRT_APLIC_S].base + | ||
296 | (memmap[VIRT_APLIC_S].size * socket); | ||
297 | + create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size, | ||
298 | + msi_s_phandle, intc_phandles, | ||
299 | + aplic_s_phandle, 0, | ||
300 | + false); | ||
301 | + | ||
302 | aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr); | ||
303 | - qemu_fdt_add_subnode(ms->fdt, aplic_name); | ||
304 | - qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic"); | ||
305 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, | ||
306 | - "#interrupt-cells", FDT_APLIC_INT_CELLS); | ||
307 | - qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0); | ||
308 | - if (s->aia_type == VIRT_AIA_TYPE_APLIC) { | ||
309 | - qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended", | ||
310 | - aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); | ||
311 | - } else { | ||
312 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", | ||
313 | - msi_s_phandle); | ||
314 | - } | ||
315 | - qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg", | ||
316 | - 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size); | ||
317 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources", | ||
318 | - VIRT_IRQCHIP_NUM_SOURCES); | ||
319 | - riscv_socket_fdt_write_id(ms, aplic_name, socket); | ||
320 | - qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle); | ||
321 | |||
322 | if (!socket) { | ||
323 | platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name, | ||
324 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
325 | |||
326 | g_free(aplic_name); | ||
327 | |||
328 | - g_free(aplic_cells); | ||
329 | aplic_phandles[socket] = aplic_s_phandle; | ||
53 | } | 330 | } |
54 | 331 | ||
55 | +Int128 int128_divu(Int128, Int128); | 332 | @@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests, |
56 | +Int128 int128_remu(Int128, Int128); | 333 | int i; |
57 | +Int128 int128_divs(Int128, Int128); | 334 | hwaddr addr; |
58 | +Int128 int128_rems(Int128, Int128); | 335 | uint32_t guest_bits; |
59 | + | 336 | - DeviceState *aplic_m; |
60 | #endif /* CONFIG_INT128 */ | 337 | - bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false; |
61 | 338 | + DeviceState *aplic_s = NULL; | |
62 | static inline void bswap128s(Int128 *s) | 339 | + DeviceState *aplic_m = NULL; |
63 | @@ -XXX,XX +XXX,XX @@ static inline void bswap128s(Int128 *s) | 340 | + bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC; |
64 | *s = bswap128(*s); | 341 | |
342 | if (msimode) { | ||
343 | - /* Per-socket M-level IMSICs */ | ||
344 | - addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE; | ||
345 | - for (i = 0; i < hart_count; i++) { | ||
346 | - riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), | ||
347 | - base_hartid + i, true, 1, | ||
348 | - VIRT_IRQCHIP_NUM_MSIS); | ||
349 | + if (!kvm_enabled()) { | ||
350 | + /* Per-socket M-level IMSICs */ | ||
351 | + addr = memmap[VIRT_IMSIC_M].base + | ||
352 | + socket * VIRT_IMSIC_GROUP_MAX_SIZE; | ||
353 | + for (i = 0; i < hart_count; i++) { | ||
354 | + riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), | ||
355 | + base_hartid + i, true, 1, | ||
356 | + VIRT_IRQCHIP_NUM_MSIS); | ||
357 | + } | ||
358 | } | ||
359 | |||
360 | /* Per-socket S-level IMSICs */ | ||
361 | @@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests, | ||
362 | } | ||
363 | } | ||
364 | |||
365 | - /* Per-socket M-level APLIC */ | ||
366 | - aplic_m = riscv_aplic_create( | ||
367 | - memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size, | ||
368 | - memmap[VIRT_APLIC_M].size, | ||
369 | - (msimode) ? 0 : base_hartid, | ||
370 | - (msimode) ? 0 : hart_count, | ||
371 | - VIRT_IRQCHIP_NUM_SOURCES, | ||
372 | - VIRT_IRQCHIP_NUM_PRIO_BITS, | ||
373 | - msimode, true, NULL); | ||
374 | - | ||
375 | - if (aplic_m) { | ||
376 | - /* Per-socket S-level APLIC */ | ||
377 | - riscv_aplic_create( | ||
378 | - memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size, | ||
379 | - memmap[VIRT_APLIC_S].size, | ||
380 | - (msimode) ? 0 : base_hartid, | ||
381 | - (msimode) ? 0 : hart_count, | ||
382 | - VIRT_IRQCHIP_NUM_SOURCES, | ||
383 | - VIRT_IRQCHIP_NUM_PRIO_BITS, | ||
384 | - msimode, false, aplic_m); | ||
385 | + if (!kvm_enabled()) { | ||
386 | + /* Per-socket M-level APLIC */ | ||
387 | + aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base + | ||
388 | + socket * memmap[VIRT_APLIC_M].size, | ||
389 | + memmap[VIRT_APLIC_M].size, | ||
390 | + (msimode) ? 0 : base_hartid, | ||
391 | + (msimode) ? 0 : hart_count, | ||
392 | + VIRT_IRQCHIP_NUM_SOURCES, | ||
393 | + VIRT_IRQCHIP_NUM_PRIO_BITS, | ||
394 | + msimode, true, NULL); | ||
395 | } | ||
396 | |||
397 | - return aplic_m; | ||
398 | + /* Per-socket S-level APLIC */ | ||
399 | + aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base + | ||
400 | + socket * memmap[VIRT_APLIC_S].size, | ||
401 | + memmap[VIRT_APLIC_S].size, | ||
402 | + (msimode) ? 0 : base_hartid, | ||
403 | + (msimode) ? 0 : hart_count, | ||
404 | + VIRT_IRQCHIP_NUM_SOURCES, | ||
405 | + VIRT_IRQCHIP_NUM_PRIO_BITS, | ||
406 | + msimode, false, aplic_m); | ||
407 | + | ||
408 | + return kvm_enabled() ? aplic_s : aplic_m; | ||
65 | } | 409 | } |
66 | 410 | ||
67 | +#define UINT128_MAX int128_make128(~0LL, ~0LL) | 411 | static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip) |
68 | + | ||
69 | #endif /* INT128_H */ | ||
70 | diff --git a/util/int128.c b/util/int128.c | ||
71 | new file mode 100644 | ||
72 | index XXXXXXX..XXXXXXX | ||
73 | --- /dev/null | ||
74 | +++ b/util/int128.c | ||
75 | @@ -XXX,XX +XXX,XX @@ | ||
76 | +/* | ||
77 | + * 128-bit division and remainder for compilers not supporting __int128 | ||
78 | + * | ||
79 | + * Copyright (c) 2021 Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | ||
80 | + * | ||
81 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
82 | + * of this software and associated documentation files (the "Software"), to deal | ||
83 | + * in the Software without restriction, including without limitation the rights | ||
84 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
85 | + * copies of the Software, and to permit persons to whom the Software is | ||
86 | + * furnished to do so, subject to the following conditions: | ||
87 | + * | ||
88 | + * The above copyright notice and this permission notice shall be included in | ||
89 | + * all copies or substantial portions of the Software. | ||
90 | + * | ||
91 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
92 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
93 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
94 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
95 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
96 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
97 | + * THE SOFTWARE. | ||
98 | + */ | ||
99 | + | ||
100 | +#include "qemu/osdep.h" | ||
101 | +#include "qemu/host-utils.h" | ||
102 | +#include "qemu/int128.h" | ||
103 | + | ||
104 | +#ifndef CONFIG_INT128 | ||
105 | + | ||
106 | +/* | ||
107 | + * Division and remainder algorithms for 128-bit due to Stefan Kanthak, | ||
108 | + * https://skanthak.homepage.t-online.de/integer.html#udivmodti4 | ||
109 | + * Preconditions: | ||
110 | + * - function should never be called with v equals to 0, it has to | ||
111 | + * be dealt with beforehand | ||
112 | + * - quotien pointer must be valid | ||
113 | + */ | ||
114 | +static Int128 divrem128(Int128 u, Int128 v, Int128 *q) | ||
115 | +{ | ||
116 | + Int128 qq; | ||
117 | + uint64_t hi, lo, tmp; | ||
118 | + int s = clz64(v.hi); | ||
119 | + | ||
120 | + if (s == 64) { | ||
121 | + /* we have uu÷0v => let's use divu128 */ | ||
122 | + hi = u.hi; | ||
123 | + lo = u.lo; | ||
124 | + tmp = divu128(&lo, &hi, v.lo); | ||
125 | + *q = int128_make128(lo, hi); | ||
126 | + return int128_make128(tmp, 0); | ||
127 | + } else { | ||
128 | + hi = int128_gethi(int128_lshift(v, s)); | ||
129 | + | ||
130 | + if (hi > u.hi) { | ||
131 | + lo = u.lo; | ||
132 | + tmp = u.hi; | ||
133 | + divu128(&lo, &tmp, hi); | ||
134 | + lo = int128_gethi(int128_lshift(int128_make128(lo, 0), s)); | ||
135 | + } else { /* prevent overflow */ | ||
136 | + lo = u.lo; | ||
137 | + tmp = u.hi - hi; | ||
138 | + divu128(&lo, &tmp, hi); | ||
139 | + lo = int128_gethi(int128_lshift(int128_make128(lo, 1), s)); | ||
140 | + } | ||
141 | + | ||
142 | + qq = int128_make64(lo); | ||
143 | + | ||
144 | + tmp = lo * v.hi; | ||
145 | + mulu64(&lo, &hi, lo, v.lo); | ||
146 | + hi += tmp; | ||
147 | + | ||
148 | + if (hi < tmp /* quotient * divisor >= 2**128 > dividend */ | ||
149 | + || hi > u.hi /* quotient * divisor > dividend */ | ||
150 | + || (hi == u.hi && lo > u.lo)) { | ||
151 | + qq.lo -= 1; | ||
152 | + mulu64(&lo, &hi, qq.lo, v.lo); | ||
153 | + hi += qq.lo * v.hi; | ||
154 | + } | ||
155 | + | ||
156 | + *q = qq; | ||
157 | + u.hi -= hi + (u.lo < lo); | ||
158 | + u.lo -= lo; | ||
159 | + return u; | ||
160 | + } | ||
161 | +} | ||
162 | + | ||
163 | +Int128 int128_divu(Int128 a, Int128 b) | ||
164 | +{ | ||
165 | + Int128 q; | ||
166 | + divrem128(a, b, &q); | ||
167 | + return q; | ||
168 | +} | ||
169 | + | ||
170 | +Int128 int128_remu(Int128 a, Int128 b) | ||
171 | +{ | ||
172 | + Int128 q; | ||
173 | + return divrem128(a, b, &q); | ||
174 | +} | ||
175 | + | ||
176 | +Int128 int128_divs(Int128 a, Int128 b) | ||
177 | +{ | ||
178 | + Int128 q; | ||
179 | + bool sgna = !int128_nonneg(a); | ||
180 | + bool sgnb = !int128_nonneg(b); | ||
181 | + | ||
182 | + if (sgna) { | ||
183 | + a = int128_neg(a); | ||
184 | + } | ||
185 | + | ||
186 | + if (sgnb) { | ||
187 | + b = int128_neg(b); | ||
188 | + } | ||
189 | + | ||
190 | + divrem128(a, b, &q); | ||
191 | + | ||
192 | + if (sgna != sgnb) { | ||
193 | + q = int128_neg(q); | ||
194 | + } | ||
195 | + | ||
196 | + return q; | ||
197 | +} | ||
198 | + | ||
199 | +Int128 int128_rems(Int128 a, Int128 b) | ||
200 | +{ | ||
201 | + Int128 q, r; | ||
202 | + bool sgna = !int128_nonneg(a); | ||
203 | + bool sgnb = !int128_nonneg(b); | ||
204 | + | ||
205 | + if (sgna) { | ||
206 | + a = int128_neg(a); | ||
207 | + } | ||
208 | + | ||
209 | + if (sgnb) { | ||
210 | + b = int128_neg(b); | ||
211 | + } | ||
212 | + | ||
213 | + r = divrem128(a, b, &q); | ||
214 | + | ||
215 | + if (sgna) { | ||
216 | + r = int128_neg(r); | ||
217 | + } | ||
218 | + | ||
219 | + return r; | ||
220 | +} | ||
221 | + | ||
222 | +#endif | ||
223 | diff --git a/util/meson.build b/util/meson.build | ||
224 | index XXXXXXX..XXXXXXX 100644 | ||
225 | --- a/util/meson.build | ||
226 | +++ b/util/meson.build | ||
227 | @@ -XXX,XX +XXX,XX @@ util_ss.add(files('transactions.c')) | ||
228 | util_ss.add(when: 'CONFIG_POSIX', if_true: files('drm.c')) | ||
229 | util_ss.add(files('guest-random.c')) | ||
230 | util_ss.add(files('yank.c')) | ||
231 | +util_ss.add(files('int128.c')) | ||
232 | |||
233 | if have_user | ||
234 | util_ss.add(files('selfmap.c')) | ||
235 | -- | 412 | -- |
236 | 2.31.1 | 413 | 2.41.0 |
237 | |||
238 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Given that the 128-bit version of the riscv spec adds new instructions, and | 3 | We check the in-kernel irqchip support when using KVM acceleration. |
4 | that some instructions that were previously only available in 64-bit mode | ||
5 | are now available for both 64-bit and 128-bit, we added new macros to check | ||
6 | for the processor mode during translation. | ||
7 | Although RV128 is a superset of RV64, we keep for now the RV64 only tests | ||
8 | for extensions other than RVI and RVM. | ||
9 | 4 | ||
10 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 5 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
11 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 6 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
14 | Message-id: 20220106210108.138226-5-frederic.petrot@univ-grenoble-alpes.fr | 9 | Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com> |
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 11 | --- |
17 | target/riscv/translate.c | 20 ++++++++++++++++---- | 12 | target/riscv/kvm.c | 10 +++++++++- |
18 | 1 file changed, 16 insertions(+), 4 deletions(-) | 13 | 1 file changed, 9 insertions(+), 1 deletion(-) |
19 | 14 | ||
20 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 15 | diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c |
21 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/translate.c | 17 | --- a/target/riscv/kvm.c |
23 | +++ b/target/riscv/translate.c | 18 | +++ b/target/riscv/kvm.c |
24 | @@ -XXX,XX +XXX,XX @@ EX_SH(12) | 19 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s) |
25 | } \ | 20 | |
26 | } while (0) | 21 | int kvm_arch_irqchip_create(KVMState *s) |
27 | 22 | { | |
28 | -#define REQUIRE_64BIT(ctx) do { \ | 23 | - return 0; |
29 | - if (get_xl(ctx) < MXL_RV64) { \ | 24 | + if (kvm_kernel_irqchip_split()) { |
30 | - return false; \ | 25 | + error_report("-machine kernel_irqchip=split is not supported on RISC-V."); |
31 | - } \ | 26 | + exit(1); |
32 | +#define REQUIRE_64BIT(ctx) do { \ | 27 | + } |
33 | + if (get_xl(ctx) != MXL_RV64) { \ | ||
34 | + return false; \ | ||
35 | + } \ | ||
36 | +} while (0) | ||
37 | + | 28 | + |
38 | +#define REQUIRE_128BIT(ctx) do { \ | 29 | + /* |
39 | + if (get_xl(ctx) != MXL_RV128) { \ | 30 | + * We can create the VAIA using the newer device control API. |
40 | + return false; \ | 31 | + */ |
41 | + } \ | 32 | + return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL); |
42 | +} while (0) | 33 | } |
43 | + | 34 | |
44 | +#define REQUIRE_64_OR_128BIT(ctx) do { \ | 35 | int kvm_arch_process_async_events(CPUState *cs) |
45 | + if (get_xl(ctx) == MXL_RV32) { \ | ||
46 | + return false; \ | ||
47 | + } \ | ||
48 | } while (0) | ||
49 | |||
50 | static int ex_rvc_register(DisasContext *ctx, int reg) | ||
51 | -- | 36 | -- |
52 | 2.31.1 | 37 | 2.41.0 |
53 | |||
54 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | As opposed to the gen_arith and gen_shift generation helpers, the csr insns | 3 | We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up |
4 | do not have a common prototype, so the choice to generate 32/64 or 128-bit | 4 | the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs. |
5 | helper calls is done in the trans_csrxx functions. | 5 | We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia" |
6 | parameter is passed along with --accel in QEMU command-line. | ||
7 | 1) "riscv-aia=emul": IMSIC is emulated by hypervisor | ||
8 | 2) "riscv-aia=hwaccel": use hardware guest IMSIC | ||
9 | 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available | ||
10 | otherwise we fallback to software emulation. | ||
6 | 11 | ||
7 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 12 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
8 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 13 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
11 | Message-id: 20220106210108.138226-18-frederic.petrot@univ-grenoble-alpes.fr | 16 | Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com> |
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 18 | --- |
14 | target/riscv/insn_trans/trans_rvi.c.inc | 201 +++++++++++++++++++----- | 19 | target/riscv/kvm_riscv.h | 4 + |
15 | 1 file changed, 158 insertions(+), 43 deletions(-) | 20 | target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++ |
21 | 2 files changed, 190 insertions(+) | ||
16 | 22 | ||
17 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | 23 | diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h |
18 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | 25 | --- a/target/riscv/kvm_riscv.h |
20 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | 26 | +++ b/target/riscv/kvm_riscv.h |
21 | @@ -XXX,XX +XXX,XX @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask) | 27 | @@ -XXX,XX +XXX,XX @@ |
22 | return do_csr_post(ctx); | 28 | void kvm_riscv_init_user_properties(Object *cpu_obj); |
29 | void kvm_riscv_reset_vcpu(RISCVCPU *cpu); | ||
30 | void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level); | ||
31 | +void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, | ||
32 | + uint64_t aia_irq_num, uint64_t aia_msi_num, | ||
33 | + uint64_t aplic_base, uint64_t imsic_base, | ||
34 | + uint64_t guest_num); | ||
35 | |||
36 | #endif | ||
37 | diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/target/riscv/kvm.c | ||
40 | +++ b/target/riscv/kvm.c | ||
41 | @@ -XXX,XX +XXX,XX @@ | ||
42 | #include "exec/address-spaces.h" | ||
43 | #include "hw/boards.h" | ||
44 | #include "hw/irq.h" | ||
45 | +#include "hw/intc/riscv_imsic.h" | ||
46 | #include "qemu/log.h" | ||
47 | #include "hw/loader.h" | ||
48 | #include "kvm_riscv.h" | ||
49 | @@ -XXX,XX +XXX,XX @@ | ||
50 | #include "chardev/char-fe.h" | ||
51 | #include "migration/migration.h" | ||
52 | #include "sysemu/runstate.h" | ||
53 | +#include "hw/riscv/numa.h" | ||
54 | |||
55 | static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, | ||
56 | uint64_t idx) | ||
57 | @@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void) | ||
58 | return true; | ||
23 | } | 59 | } |
24 | 60 | ||
25 | -static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a) | 61 | +static int aia_mode; |
26 | +static bool do_csrr_i128(DisasContext *ctx, int rd, int rc) | 62 | + |
63 | +static const char *kvm_aia_mode_str(uint64_t mode) | ||
64 | +{ | ||
65 | + switch (mode) { | ||
66 | + case KVM_DEV_RISCV_AIA_MODE_EMUL: | ||
67 | + return "emul"; | ||
68 | + case KVM_DEV_RISCV_AIA_MODE_HWACCEL: | ||
69 | + return "hwaccel"; | ||
70 | + case KVM_DEV_RISCV_AIA_MODE_AUTO: | ||
71 | + default: | ||
72 | + return "auto"; | ||
73 | + }; | ||
74 | +} | ||
75 | + | ||
76 | +static char *riscv_get_kvm_aia(Object *obj, Error **errp) | ||
77 | +{ | ||
78 | + return g_strdup(kvm_aia_mode_str(aia_mode)); | ||
79 | +} | ||
80 | + | ||
81 | +static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp) | ||
82 | +{ | ||
83 | + if (!strcmp(val, "emul")) { | ||
84 | + aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL; | ||
85 | + } else if (!strcmp(val, "hwaccel")) { | ||
86 | + aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL; | ||
87 | + } else if (!strcmp(val, "auto")) { | ||
88 | + aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO; | ||
89 | + } else { | ||
90 | + error_setg(errp, "Invalid KVM AIA mode"); | ||
91 | + error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n"); | ||
92 | + } | ||
93 | +} | ||
94 | + | ||
95 | void kvm_arch_accel_class_init(ObjectClass *oc) | ||
27 | { | 96 | { |
28 | - TCGv src = get_gpr(ctx, a->rs1, EXT_NONE); | 97 | + object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia, |
29 | + TCGv destl = dest_gpr(ctx, rd); | 98 | + riscv_set_kvm_aia); |
30 | + TCGv desth = dest_gprh(ctx, rd); | 99 | + object_class_property_set_description(oc, "riscv-aia", |
31 | + TCGv_i32 csr = tcg_constant_i32(rc); | 100 | + "Set KVM AIA mode. Valid values are " |
32 | 101 | + "emul, hwaccel, and auto. Default " | |
33 | - /* | 102 | + "is auto."); |
34 | - * If rd == 0, the insn shall not read the csr, nor cause any of the | 103 | + object_property_set_default_str(object_class_property_find(oc, "riscv-aia"), |
35 | - * side effects that might occur on a csr read. | 104 | + "auto"); |
36 | - */ | 105 | +} |
37 | - if (a->rd == 0) { | 106 | + |
38 | - return do_csrw(ctx, a->csr, src); | 107 | +void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, |
39 | + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { | 108 | + uint64_t aia_irq_num, uint64_t aia_msi_num, |
40 | + gen_io_start(); | 109 | + uint64_t aplic_base, uint64_t imsic_base, |
41 | } | 110 | + uint64_t guest_num) |
42 | + gen_helper_csrr_i128(destl, cpu_env, csr); | 111 | +{ |
43 | + tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh)); | 112 | + int ret, i; |
44 | + gen_set_gpr128(ctx, rd, destl, desth); | 113 | + int aia_fd = -1; |
45 | + return do_csr_post(ctx); | 114 | + uint64_t default_aia_mode; |
46 | +} | 115 | + uint64_t socket_count = riscv_socket_count(machine); |
47 | + | 116 | + uint64_t max_hart_per_socket = 0; |
48 | +static bool do_csrw_i128(DisasContext *ctx, int rc, TCGv srcl, TCGv srch) | 117 | + uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr; |
49 | +{ | 118 | + uint64_t socket_bits, hart_bits, guest_bits; |
50 | + TCGv_i32 csr = tcg_constant_i32(rc); | 119 | + |
51 | + | 120 | + aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false); |
52 | + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { | 121 | + |
53 | + gen_io_start(); | 122 | + if (aia_fd < 0) { |
54 | + } | 123 | + error_report("Unable to create in-kernel irqchip"); |
55 | + gen_helper_csrw_i128(cpu_env, csr, srcl, srch); | 124 | + exit(1); |
56 | + return do_csr_post(ctx); | 125 | + } |
57 | +} | 126 | + |
58 | 127 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | |
59 | - TCGv mask = tcg_constant_tl(-1); | 128 | + KVM_DEV_RISCV_AIA_CONFIG_MODE, |
60 | - return do_csrrw(ctx, a->rd, a->csr, src, mask); | 129 | + &default_aia_mode, false, NULL); |
61 | +static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc, | 130 | + if (ret < 0) { |
62 | + TCGv srcl, TCGv srch, TCGv maskl, TCGv maskh) | 131 | + error_report("KVM AIA: failed to get current KVM AIA mode"); |
63 | +{ | 132 | + exit(1); |
64 | + TCGv destl = dest_gpr(ctx, rd); | 133 | + } |
65 | + TCGv desth = dest_gprh(ctx, rd); | 134 | + qemu_log("KVM AIA: default mode is %s\n", |
66 | + TCGv_i32 csr = tcg_constant_i32(rc); | 135 | + kvm_aia_mode_str(default_aia_mode)); |
67 | + | 136 | + |
68 | + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { | 137 | + if (default_aia_mode != aia_mode) { |
69 | + gen_io_start(); | 138 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
70 | + } | 139 | + KVM_DEV_RISCV_AIA_CONFIG_MODE, |
71 | + gen_helper_csrrw_i128(destl, cpu_env, csr, srcl, srch, maskl, maskh); | 140 | + &aia_mode, true, NULL); |
72 | + tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh)); | 141 | + if (ret < 0) |
73 | + gen_set_gpr128(ctx, rd, destl, desth); | 142 | + warn_report("KVM AIA: failed to set KVM AIA mode"); |
74 | + return do_csr_post(ctx); | 143 | + else |
75 | +} | 144 | + qemu_log("KVM AIA: set current mode to %s\n", |
76 | + | 145 | + kvm_aia_mode_str(aia_mode)); |
77 | +static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a) | 146 | + } |
78 | +{ | 147 | + |
79 | + if (get_xl(ctx) < MXL_RV128) { | 148 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
80 | + TCGv src = get_gpr(ctx, a->rs1, EXT_NONE); | 149 | + KVM_DEV_RISCV_AIA_CONFIG_SRCS, |
81 | + | 150 | + &aia_irq_num, true, NULL); |
82 | + /* | 151 | + if (ret < 0) { |
83 | + * If rd == 0, the insn shall not read the csr, nor cause any of the | 152 | + error_report("KVM AIA: failed to set number of input irq lines"); |
84 | + * side effects that might occur on a csr read. | 153 | + exit(1); |
85 | + */ | 154 | + } |
86 | + if (a->rd == 0) { | 155 | + |
87 | + return do_csrw(ctx, a->csr, src); | 156 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
157 | + KVM_DEV_RISCV_AIA_CONFIG_IDS, | ||
158 | + &aia_msi_num, true, NULL); | ||
159 | + if (ret < 0) { | ||
160 | + error_report("KVM AIA: failed to set number of msi"); | ||
161 | + exit(1); | ||
162 | + } | ||
163 | + | ||
164 | + socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1; | ||
165 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | ||
166 | + KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS, | ||
167 | + &socket_bits, true, NULL); | ||
168 | + if (ret < 0) { | ||
169 | + error_report("KVM AIA: failed to set group_bits"); | ||
170 | + exit(1); | ||
171 | + } | ||
172 | + | ||
173 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | ||
174 | + KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT, | ||
175 | + &group_shift, true, NULL); | ||
176 | + if (ret < 0) { | ||
177 | + error_report("KVM AIA: failed to set group_shift"); | ||
178 | + exit(1); | ||
179 | + } | ||
180 | + | ||
181 | + guest_bits = guest_num == 0 ? 0 : | ||
182 | + find_last_bit(&guest_num, BITS_PER_LONG) + 1; | ||
183 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | ||
184 | + KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS, | ||
185 | + &guest_bits, true, NULL); | ||
186 | + if (ret < 0) { | ||
187 | + error_report("KVM AIA: failed to set guest_bits"); | ||
188 | + exit(1); | ||
189 | + } | ||
190 | + | ||
191 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR, | ||
192 | + KVM_DEV_RISCV_AIA_ADDR_APLIC, | ||
193 | + &aplic_base, true, NULL); | ||
194 | + if (ret < 0) { | ||
195 | + error_report("KVM AIA: failed to set the base address of APLIC"); | ||
196 | + exit(1); | ||
197 | + } | ||
198 | + | ||
199 | + for (socket = 0; socket < socket_count; socket++) { | ||
200 | + socket_imsic_base = imsic_base + socket * (1U << group_shift); | ||
201 | + hart_count = riscv_socket_hart_count(machine, socket); | ||
202 | + base_hart = riscv_socket_first_hartid(machine, socket); | ||
203 | + | ||
204 | + if (max_hart_per_socket < hart_count) { | ||
205 | + max_hart_per_socket = hart_count; | ||
88 | + } | 206 | + } |
89 | + | 207 | + |
90 | + TCGv mask = tcg_constant_tl(-1); | 208 | + for (i = 0; i < hart_count; i++) { |
91 | + return do_csrrw(ctx, a->rd, a->csr, src, mask); | 209 | + imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits); |
92 | + } else { | 210 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR, |
93 | + TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE); | 211 | + KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart), |
94 | + TCGv srch = get_gprh(ctx, a->rs1); | 212 | + &imsic_addr, true, NULL); |
95 | + | 213 | + if (ret < 0) { |
96 | + /* | 214 | + error_report("KVM AIA: failed to set the IMSIC address for hart %d", i); |
97 | + * If rd == 0, the insn shall not read the csr, nor cause any of the | 215 | + exit(1); |
98 | + * side effects that might occur on a csr read. | 216 | + } |
99 | + */ | ||
100 | + if (a->rd == 0) { | ||
101 | + return do_csrw_i128(ctx, a->csr, srcl, srch); | ||
102 | + } | 217 | + } |
103 | + | 218 | + } |
104 | + TCGv mask = tcg_constant_tl(-1); | 219 | + |
105 | + return do_csrrw_i128(ctx, a->rd, a->csr, srcl, srch, mask, mask); | 220 | + hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1; |
106 | + } | 221 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
107 | } | 222 | + KVM_DEV_RISCV_AIA_CONFIG_HART_BITS, |
108 | 223 | + &hart_bits, true, NULL); | |
109 | static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a) | 224 | + if (ret < 0) { |
110 | @@ -XXX,XX +XXX,XX @@ static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a) | 225 | + error_report("KVM AIA: failed to set hart_bits"); |
111 | * a zero value, the instruction will still attempt to write the | 226 | + exit(1); |
112 | * unmodified value back to the csr and will cause side effects. | 227 | + } |
113 | */ | 228 | + |
114 | - if (a->rs1 == 0) { | 229 | + if (kvm_has_gsi_routing()) { |
115 | - return do_csrr(ctx, a->rd, a->csr); | 230 | + for (uint64_t idx = 0; idx < aia_irq_num + 1; ++idx) { |
116 | - } | 231 | + /* KVM AIA only has one APLIC instance */ |
117 | + if (get_xl(ctx) < MXL_RV128) { | 232 | + kvm_irqchip_add_irq_route(kvm_state, idx, 0, idx); |
118 | + if (a->rs1 == 0) { | ||
119 | + return do_csrr(ctx, a->rd, a->csr); | ||
120 | + } | 233 | + } |
121 | 234 | + kvm_gsi_routing_allowed = true; | |
122 | - TCGv ones = tcg_constant_tl(-1); | 235 | + kvm_irqchip_commit_routes(kvm_state); |
123 | - TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO); | 236 | + } |
124 | - return do_csrrw(ctx, a->rd, a->csr, ones, mask); | 237 | + |
125 | + TCGv ones = tcg_constant_tl(-1); | 238 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL, |
126 | + TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO); | 239 | + KVM_DEV_RISCV_AIA_CTRL_INIT, |
127 | + return do_csrrw(ctx, a->rd, a->csr, ones, mask); | 240 | + NULL, true, NULL); |
128 | + } else { | 241 | + if (ret < 0) { |
129 | + if (a->rs1 == 0) { | 242 | + error_report("KVM AIA: initialized fail"); |
130 | + return do_csrr_i128(ctx, a->rd, a->csr); | 243 | + exit(1); |
131 | + } | 244 | + } |
132 | + | 245 | + |
133 | + TCGv ones = tcg_constant_tl(-1); | 246 | + kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); |
134 | + TCGv maskl = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
135 | + TCGv maskh = get_gprh(ctx, a->rs1); | ||
136 | + return do_csrrw_i128(ctx, a->rd, a->csr, ones, ones, maskl, maskh); | ||
137 | + } | ||
138 | } | ||
139 | |||
140 | static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a) | ||
141 | @@ -XXX,XX +XXX,XX @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a) | ||
142 | * a zero value, the instruction will still attempt to write the | ||
143 | * unmodified value back to the csr and will cause side effects. | ||
144 | */ | ||
145 | - if (a->rs1 == 0) { | ||
146 | - return do_csrr(ctx, a->rd, a->csr); | ||
147 | - } | ||
148 | + if (get_xl(ctx) < MXL_RV128) { | ||
149 | + if (a->rs1 == 0) { | ||
150 | + return do_csrr(ctx, a->rd, a->csr); | ||
151 | + } | ||
152 | |||
153 | - TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
154 | - return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask); | ||
155 | + TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
156 | + return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask); | ||
157 | + } else { | ||
158 | + if (a->rs1 == 0) { | ||
159 | + return do_csrr_i128(ctx, a->rd, a->csr); | ||
160 | + } | ||
161 | + | ||
162 | + TCGv maskl = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
163 | + TCGv maskh = get_gprh(ctx, a->rs1); | ||
164 | + return do_csrrw_i128(ctx, a->rd, a->csr, | ||
165 | + ctx->zero, ctx->zero, maskl, maskh); | ||
166 | + } | ||
167 | } | ||
168 | |||
169 | static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a) | ||
170 | { | ||
171 | - TCGv src = tcg_constant_tl(a->rs1); | ||
172 | + if (get_xl(ctx) < MXL_RV128) { | ||
173 | + TCGv src = tcg_constant_tl(a->rs1); | ||
174 | |||
175 | - /* | ||
176 | - * If rd == 0, the insn shall not read the csr, nor cause any of the | ||
177 | - * side effects that might occur on a csr read. | ||
178 | - */ | ||
179 | - if (a->rd == 0) { | ||
180 | - return do_csrw(ctx, a->csr, src); | ||
181 | - } | ||
182 | + /* | ||
183 | + * If rd == 0, the insn shall not read the csr, nor cause any of the | ||
184 | + * side effects that might occur on a csr read. | ||
185 | + */ | ||
186 | + if (a->rd == 0) { | ||
187 | + return do_csrw(ctx, a->csr, src); | ||
188 | + } | ||
189 | |||
190 | - TCGv mask = tcg_constant_tl(-1); | ||
191 | - return do_csrrw(ctx, a->rd, a->csr, src, mask); | ||
192 | + TCGv mask = tcg_constant_tl(-1); | ||
193 | + return do_csrrw(ctx, a->rd, a->csr, src, mask); | ||
194 | + } else { | ||
195 | + TCGv src = tcg_constant_tl(a->rs1); | ||
196 | + | ||
197 | + /* | ||
198 | + * If rd == 0, the insn shall not read the csr, nor cause any of the | ||
199 | + * side effects that might occur on a csr read. | ||
200 | + */ | ||
201 | + if (a->rd == 0) { | ||
202 | + return do_csrw_i128(ctx, a->csr, src, ctx->zero); | ||
203 | + } | ||
204 | + | ||
205 | + TCGv mask = tcg_constant_tl(-1); | ||
206 | + return do_csrrw_i128(ctx, a->rd, a->csr, src, ctx->zero, mask, mask); | ||
207 | + } | ||
208 | } | ||
209 | |||
210 | static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a) | ||
211 | @@ -XXX,XX +XXX,XX @@ static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a) | ||
212 | * a zero value, the instruction will still attempt to write the | ||
213 | * unmodified value back to the csr and will cause side effects. | ||
214 | */ | ||
215 | - if (a->rs1 == 0) { | ||
216 | - return do_csrr(ctx, a->rd, a->csr); | ||
217 | - } | ||
218 | + if (get_xl(ctx) < MXL_RV128) { | ||
219 | + if (a->rs1 == 0) { | ||
220 | + return do_csrr(ctx, a->rd, a->csr); | ||
221 | + } | ||
222 | + | ||
223 | + TCGv ones = tcg_constant_tl(-1); | ||
224 | + TCGv mask = tcg_constant_tl(a->rs1); | ||
225 | + return do_csrrw(ctx, a->rd, a->csr, ones, mask); | ||
226 | + } else { | ||
227 | + if (a->rs1 == 0) { | ||
228 | + return do_csrr_i128(ctx, a->rd, a->csr); | ||
229 | + } | ||
230 | |||
231 | - TCGv ones = tcg_constant_tl(-1); | ||
232 | - TCGv mask = tcg_constant_tl(a->rs1); | ||
233 | - return do_csrrw(ctx, a->rd, a->csr, ones, mask); | ||
234 | + TCGv ones = tcg_constant_tl(-1); | ||
235 | + TCGv mask = tcg_constant_tl(a->rs1); | ||
236 | + return do_csrrw_i128(ctx, a->rd, a->csr, ones, ones, mask, ctx->zero); | ||
237 | + } | ||
238 | } | ||
239 | |||
240 | -static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a) | ||
241 | +static bool trans_csrrci(DisasContext *ctx, arg_csrrci * a) | ||
242 | { | ||
243 | /* | ||
244 | * If rs1 == 0, the insn shall not write to the csr at all, nor | ||
245 | @@ -XXX,XX +XXX,XX @@ static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a) | ||
246 | * a zero value, the instruction will still attempt to write the | ||
247 | * unmodified value back to the csr and will cause side effects. | ||
248 | */ | ||
249 | - if (a->rs1 == 0) { | ||
250 | - return do_csrr(ctx, a->rd, a->csr); | ||
251 | - } | ||
252 | + if (get_xl(ctx) < MXL_RV128) { | ||
253 | + if (a->rs1 == 0) { | ||
254 | + return do_csrr(ctx, a->rd, a->csr); | ||
255 | + } | ||
256 | |||
257 | - TCGv mask = tcg_constant_tl(a->rs1); | ||
258 | - return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask); | ||
259 | + TCGv mask = tcg_constant_tl(a->rs1); | ||
260 | + return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask); | ||
261 | + } else { | ||
262 | + if (a->rs1 == 0) { | ||
263 | + return do_csrr_i128(ctx, a->rd, a->csr); | ||
264 | + } | ||
265 | + | ||
266 | + TCGv mask = tcg_constant_tl(a->rs1); | ||
267 | + return do_csrrw_i128(ctx, a->rd, a->csr, | ||
268 | + ctx->zero, ctx->zero, mask, ctx->zero); | ||
269 | + } | ||
270 | } | 247 | } |
271 | -- | 248 | -- |
272 | 2.31.1 | 249 | 2.41.0 |
273 | |||
274 | diff view generated by jsdifflib |
1 | From: Jim Shu <jim.shu@sifive.com> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Real PDMA supports high 32-bit read/write memory access of 64-bit | 3 | KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed, |
4 | register. | 4 | APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the |
5 | mmio operations of APLIC when using KVM AIA and send wired interrupt | ||
6 | signal via KVM_IRQ_LINE API. | ||
7 | After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API | ||
8 | when the IMSICs receive mmio write requests. | ||
5 | 9 | ||
6 | The following result is PDMA tested in U-Boot on Unmatched board: | 10 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
7 | 11 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | |
8 | 1. Real PDMA allows high 32-bit read/write to 64-bit register. | 12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
9 | => mw.l 0x3000000 0x0 <= Disclaim channel 0 | 13 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
10 | => mw.l 0x3000000 0x1 <= Claim channel 0 | 14 | Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com> |
11 | => mw.l 0x3000010 0x80000000 <= Write low 32-bit NextDest (NextDest = 0x280000000) | ||
12 | => mw.l 0x3000014 0x2 <= Write high 32-bit NextDest | ||
13 | => md.l 0x3000010 1 <= Dump low 32-bit NextDest | ||
14 | 03000010: 80000000 | ||
15 | => md.l 0x3000014 1 <= Dump high 32-bit NextDest | ||
16 | 03000014: 00000002 | ||
17 | => mw.l 0x3000018 0x80001000 <= Write low 32-bit NextSrc (NextSrc = 0x280001000) | ||
18 | => mw.l 0x300001c 0x2 <= Write high 32-bit NextSrc | ||
19 | => md.l 0x3000018 1 <= Dump low 32-bit NextSrc | ||
20 | 03000010: 80001000 | ||
21 | => md.l 0x300001c 1 <= Dump high 32-bit NextSrc | ||
22 | 03000014: 00000002 | ||
23 | |||
24 | 2. PDMA transfer from 0x280001000 to 0x280000000 is OK. | ||
25 | => mw.q 0x3000008 0x4 <= NextBytes = 4 | ||
26 | => mw.l 0x3000004 0x22000000 <= wsize = rsize = 2 (2^2 = 4 bytes) | ||
27 | => mw.l 0x280000000 0x87654321 <= Fill test data to dst | ||
28 | => mw.l 0x280001000 0x12345678 <= Fill test data to src | ||
29 | => md.l 0x280000000 1; md.l 0x280001000 1 <= Dump src/dst memory contents | ||
30 | 280000000: 87654321 !Ce. | ||
31 | 280001000: 12345678 xV4. | ||
32 | => md.l 0x3000000 8 <= Dump PDMA status | ||
33 | 03000000: 00000001 22000000 00000004 00000000 ......."........ | ||
34 | 03000010: 80000000 00000002 80001000 00000002 ................ | ||
35 | => mw.l 0x3000000 0x3 <= Set channel 0 run and claim bits | ||
36 | => md.l 0x3000000 8 <= Dump PDMA status | ||
37 | 03000000: 40000001 22000000 00000004 00000000 ...@..."........ | ||
38 | 03000010: 80000000 00000002 80001000 00000002 ................ | ||
39 | => md.l 0x280000000 1; md.l 0x280001000 1 <= Dump src/dst memory contents | ||
40 | 280000000: 12345678 xV4. | ||
41 | 280001000: 12345678 xV4. | ||
42 | |||
43 | Signed-off-by: Jim Shu <jim.shu@sifive.com> | ||
44 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
45 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
46 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
47 | Tested-by: Bin Meng <bmeng.cn@gmail.com> | ||
48 | Message-id: 20220104063408.658169-2-jim.shu@sifive.com | ||
49 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
50 | --- | 16 | --- |
51 | hw/dma/sifive_pdma.c | 177 +++++++++++++++++++++++++++++++++++++------ | 17 | hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++------------- |
52 | 1 file changed, 155 insertions(+), 22 deletions(-) | 18 | hw/intc/riscv_imsic.c | 25 +++++++++++++++---- |
19 | 2 files changed, 61 insertions(+), 20 deletions(-) | ||
53 | 20 | ||
54 | diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c | 21 | diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c |
55 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/hw/dma/sifive_pdma.c | 23 | --- a/hw/intc/riscv_aplic.c |
57 | +++ b/hw/dma/sifive_pdma.c | 24 | +++ b/hw/intc/riscv_aplic.c |
58 | @@ -XXX,XX +XXX,XX @@ static inline void sifive_pdma_update_irq(SiFivePDMAState *s, int ch) | 25 | @@ -XXX,XX +XXX,XX @@ |
59 | s->chan[ch].state = DMA_CHAN_STATE_IDLE; | 26 | #include "hw/irq.h" |
60 | } | 27 | #include "target/riscv/cpu.h" |
61 | 28 | #include "sysemu/sysemu.h" | |
62 | -static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size) | 29 | +#include "sysemu/kvm.h" |
63 | +static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr offset) | 30 | #include "migration/vmstate.h" |
64 | { | 31 | |
65 | - SiFivePDMAState *s = opaque; | 32 | #define APLIC_MAX_IDC (1UL << 14) |
66 | - int ch = SIFIVE_PDMA_CHAN_NO(offset); | 33 | @@ -XXX,XX +XXX,XX @@ |
67 | uint64_t val = 0; | 34 | |
68 | 35 | #define APLIC_IDC_CLAIMI 0x1c | |
69 | - if (ch >= SIFIVE_PDMA_CHANS) { | 36 | |
70 | - qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n", | 37 | +/* |
71 | - __func__, ch); | 38 | + * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use |
72 | - return 0; | 39 | + * APLIC Wired. |
73 | + offset &= 0xfff; | 40 | + */ |
74 | + switch (offset) { | 41 | +static bool is_kvm_aia(bool msimode) |
75 | + case DMA_NEXT_BYTES: | 42 | +{ |
76 | + val = s->chan[ch].next_bytes; | 43 | + return kvm_irqchip_in_kernel() && msimode; |
77 | + break; | ||
78 | + case DMA_NEXT_DST: | ||
79 | + val = s->chan[ch].next_dst; | ||
80 | + break; | ||
81 | + case DMA_NEXT_SRC: | ||
82 | + val = s->chan[ch].next_src; | ||
83 | + break; | ||
84 | + case DMA_EXEC_BYTES: | ||
85 | + val = s->chan[ch].exec_bytes; | ||
86 | + break; | ||
87 | + case DMA_EXEC_DST: | ||
88 | + val = s->chan[ch].exec_dst; | ||
89 | + break; | ||
90 | + case DMA_EXEC_SRC: | ||
91 | + val = s->chan[ch].exec_src; | ||
92 | + break; | ||
93 | + default: | ||
94 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
95 | + "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n", | ||
96 | + __func__, offset); | ||
97 | + break; | ||
98 | } | ||
99 | |||
100 | + return val; | ||
101 | +} | 44 | +} |
102 | + | 45 | + |
103 | +static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr offset) | 46 | static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic, |
47 | uint32_t word) | ||
48 | { | ||
49 | @@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc) | ||
50 | return topi; | ||
51 | } | ||
52 | |||
53 | +static void riscv_kvm_aplic_request(void *opaque, int irq, int level) | ||
104 | +{ | 54 | +{ |
105 | + uint32_t val = 0; | 55 | + kvm_set_irq(kvm_state, irq, !!level); |
106 | + | ||
107 | offset &= 0xfff; | ||
108 | switch (offset) { | ||
109 | case DMA_CONTROL: | ||
110 | @@ -XXX,XX +XXX,XX @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size) | ||
111 | val = s->chan[ch].next_config; | ||
112 | break; | ||
113 | case DMA_NEXT_BYTES: | ||
114 | - val = s->chan[ch].next_bytes; | ||
115 | + val = extract64(s->chan[ch].next_bytes, 0, 32); | ||
116 | + break; | ||
117 | + case DMA_NEXT_BYTES + 4: | ||
118 | + val = extract64(s->chan[ch].next_bytes, 32, 32); | ||
119 | break; | ||
120 | case DMA_NEXT_DST: | ||
121 | - val = s->chan[ch].next_dst; | ||
122 | + val = extract64(s->chan[ch].next_dst, 0, 32); | ||
123 | + break; | ||
124 | + case DMA_NEXT_DST + 4: | ||
125 | + val = extract64(s->chan[ch].next_dst, 32, 32); | ||
126 | break; | ||
127 | case DMA_NEXT_SRC: | ||
128 | - val = s->chan[ch].next_src; | ||
129 | + val = extract64(s->chan[ch].next_src, 0, 32); | ||
130 | + break; | ||
131 | + case DMA_NEXT_SRC + 4: | ||
132 | + val = extract64(s->chan[ch].next_src, 32, 32); | ||
133 | break; | ||
134 | case DMA_EXEC_CONFIG: | ||
135 | val = s->chan[ch].exec_config; | ||
136 | break; | ||
137 | case DMA_EXEC_BYTES: | ||
138 | - val = s->chan[ch].exec_bytes; | ||
139 | + val = extract64(s->chan[ch].exec_bytes, 0, 32); | ||
140 | + break; | ||
141 | + case DMA_EXEC_BYTES + 4: | ||
142 | + val = extract64(s->chan[ch].exec_bytes, 32, 32); | ||
143 | break; | ||
144 | case DMA_EXEC_DST: | ||
145 | - val = s->chan[ch].exec_dst; | ||
146 | + val = extract64(s->chan[ch].exec_dst, 0, 32); | ||
147 | + break; | ||
148 | + case DMA_EXEC_DST + 4: | ||
149 | + val = extract64(s->chan[ch].exec_dst, 32, 32); | ||
150 | break; | ||
151 | case DMA_EXEC_SRC: | ||
152 | - val = s->chan[ch].exec_src; | ||
153 | + val = extract64(s->chan[ch].exec_src, 0, 32); | ||
154 | + break; | ||
155 | + case DMA_EXEC_SRC + 4: | ||
156 | + val = extract64(s->chan[ch].exec_src, 32, 32); | ||
157 | break; | ||
158 | default: | ||
159 | - qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", | ||
160 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
161 | + "%s: Unexpected 32-bit access to 0x%" HWADDR_PRIX "\n", | ||
162 | __func__, offset); | ||
163 | break; | ||
164 | } | ||
165 | @@ -XXX,XX +XXX,XX @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size) | ||
166 | return val; | ||
167 | } | ||
168 | |||
169 | -static void sifive_pdma_write(void *opaque, hwaddr offset, | ||
170 | - uint64_t value, unsigned size) | ||
171 | +static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size) | ||
172 | { | ||
173 | SiFivePDMAState *s = opaque; | ||
174 | int ch = SIFIVE_PDMA_CHAN_NO(offset); | ||
175 | - bool claimed, run; | ||
176 | + uint64_t val = 0; | ||
177 | |||
178 | if (ch >= SIFIVE_PDMA_CHANS) { | ||
179 | qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n", | ||
180 | __func__, ch); | ||
181 | - return; | ||
182 | + return 0; | ||
183 | + } | ||
184 | + | ||
185 | + switch (size) { | ||
186 | + case 8: | ||
187 | + val = sifive_pdma_readq(s, ch, offset); | ||
188 | + break; | ||
189 | + case 4: | ||
190 | + val = sifive_pdma_readl(s, ch, offset); | ||
191 | + break; | ||
192 | + default: | ||
193 | + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid read size %u to PDMA\n", | ||
194 | + __func__, size); | ||
195 | + return 0; | ||
196 | } | ||
197 | |||
198 | + return val; | ||
199 | +} | 56 | +} |
200 | + | 57 | + |
201 | +static void sifive_pdma_writeq(SiFivePDMAState *s, int ch, | 58 | static void riscv_aplic_request(void *opaque, int irq, int level) |
202 | + hwaddr offset, uint64_t value) | 59 | { |
203 | +{ | 60 | bool update = false; |
204 | + offset &= 0xfff; | 61 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) |
205 | + switch (offset) { | 62 | uint32_t i; |
206 | + case DMA_NEXT_BYTES: | 63 | RISCVAPLICState *aplic = RISCV_APLIC(dev); |
207 | + s->chan[ch].next_bytes = value; | 64 | |
208 | + break; | 65 | - aplic->bitfield_words = (aplic->num_irqs + 31) >> 5; |
209 | + case DMA_NEXT_DST: | 66 | - aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs); |
210 | + s->chan[ch].next_dst = value; | 67 | - aplic->state = g_new0(uint32_t, aplic->num_irqs); |
211 | + break; | 68 | - aplic->target = g_new0(uint32_t, aplic->num_irqs); |
212 | + case DMA_NEXT_SRC: | 69 | - if (!aplic->msimode) { |
213 | + s->chan[ch].next_src = value; | 70 | - for (i = 0; i < aplic->num_irqs; i++) { |
214 | + break; | 71 | - aplic->target[i] = 1; |
215 | + case DMA_EXEC_BYTES: | 72 | + if (!is_kvm_aia(aplic->msimode)) { |
216 | + case DMA_EXEC_DST: | 73 | + aplic->bitfield_words = (aplic->num_irqs + 31) >> 5; |
217 | + case DMA_EXEC_SRC: | 74 | + aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs); |
218 | + /* these are read-only registers */ | 75 | + aplic->state = g_new0(uint32_t, aplic->num_irqs); |
219 | + break; | 76 | + aplic->target = g_new0(uint32_t, aplic->num_irqs); |
220 | + default: | 77 | + if (!aplic->msimode) { |
221 | + qemu_log_mask(LOG_GUEST_ERROR, | 78 | + for (i = 0; i < aplic->num_irqs; i++) { |
222 | + "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n", | 79 | + aplic->target[i] = 1; |
223 | + __func__, offset); | 80 | + } |
224 | + break; | 81 | } |
82 | - } | ||
83 | - aplic->idelivery = g_new0(uint32_t, aplic->num_harts); | ||
84 | - aplic->iforce = g_new0(uint32_t, aplic->num_harts); | ||
85 | - aplic->ithreshold = g_new0(uint32_t, aplic->num_harts); | ||
86 | + aplic->idelivery = g_new0(uint32_t, aplic->num_harts); | ||
87 | + aplic->iforce = g_new0(uint32_t, aplic->num_harts); | ||
88 | + aplic->ithreshold = g_new0(uint32_t, aplic->num_harts); | ||
89 | |||
90 | - memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic, | ||
91 | - TYPE_RISCV_APLIC, aplic->aperture_size); | ||
92 | - sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio); | ||
93 | + memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, | ||
94 | + aplic, TYPE_RISCV_APLIC, aplic->aperture_size); | ||
95 | + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio); | ||
225 | + } | 96 | + } |
226 | +} | 97 | |
98 | /* | ||
99 | * Only root APLICs have hardware IRQ lines. All non-root APLICs | ||
100 | * have IRQ lines delegated by their parent APLIC. | ||
101 | */ | ||
102 | if (!aplic->parent) { | ||
103 | - qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs); | ||
104 | + if (is_kvm_aia(aplic->msimode)) { | ||
105 | + qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs); | ||
106 | + } else { | ||
107 | + qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs); | ||
108 | + } | ||
109 | } | ||
110 | |||
111 | /* Create output IRQ lines for non-MSI mode */ | ||
112 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, | ||
113 | qdev_prop_set_bit(dev, "mmode", mmode); | ||
114 | |||
115 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
116 | - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); | ||
227 | + | 117 | + |
228 | +static void sifive_pdma_writel(SiFivePDMAState *s, int ch, | 118 | + if (!is_kvm_aia(msimode)) { |
229 | + hwaddr offset, uint32_t value) | 119 | + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); |
230 | +{ | 120 | + } |
231 | + bool claimed, run; | 121 | |
122 | if (parent) { | ||
123 | riscv_aplic_add_child(parent, dev); | ||
124 | diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c | ||
125 | index XXXXXXX..XXXXXXX 100644 | ||
126 | --- a/hw/intc/riscv_imsic.c | ||
127 | +++ b/hw/intc/riscv_imsic.c | ||
128 | @@ -XXX,XX +XXX,XX @@ | ||
129 | #include "target/riscv/cpu.h" | ||
130 | #include "target/riscv/cpu_bits.h" | ||
131 | #include "sysemu/sysemu.h" | ||
132 | +#include "sysemu/kvm.h" | ||
133 | #include "migration/vmstate.h" | ||
134 | |||
135 | #define IMSIC_MMIO_PAGE_LE 0x00 | ||
136 | @@ -XXX,XX +XXX,XX @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value, | ||
137 | goto err; | ||
138 | } | ||
139 | |||
140 | +#if defined(CONFIG_KVM) | ||
141 | + if (kvm_irqchip_in_kernel()) { | ||
142 | + struct kvm_msi msi; | ||
232 | + | 143 | + |
233 | offset &= 0xfff; | 144 | + msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32); |
234 | switch (offset) { | 145 | + msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32); |
235 | case DMA_CONTROL: | 146 | + msi.data = le32_to_cpu(value); |
236 | @@ -XXX,XX +XXX,XX @@ static void sifive_pdma_write(void *opaque, hwaddr offset, | ||
237 | s->chan[ch].next_config = value; | ||
238 | break; | ||
239 | case DMA_NEXT_BYTES: | ||
240 | - s->chan[ch].next_bytes = value; | ||
241 | + s->chan[ch].next_bytes = | ||
242 | + deposit64(s->chan[ch].next_bytes, 0, 32, value); | ||
243 | + break; | ||
244 | + case DMA_NEXT_BYTES + 4: | ||
245 | + s->chan[ch].next_bytes = | ||
246 | + deposit64(s->chan[ch].next_bytes, 32, 32, value); | ||
247 | break; | ||
248 | case DMA_NEXT_DST: | ||
249 | - s->chan[ch].next_dst = value; | ||
250 | + s->chan[ch].next_dst = deposit64(s->chan[ch].next_dst, 0, 32, value); | ||
251 | + break; | ||
252 | + case DMA_NEXT_DST + 4: | ||
253 | + s->chan[ch].next_dst = deposit64(s->chan[ch].next_dst, 32, 32, value); | ||
254 | break; | ||
255 | case DMA_NEXT_SRC: | ||
256 | - s->chan[ch].next_src = value; | ||
257 | + s->chan[ch].next_src = deposit64(s->chan[ch].next_src, 0, 32, value); | ||
258 | + break; | ||
259 | + case DMA_NEXT_SRC + 4: | ||
260 | + s->chan[ch].next_src = deposit64(s->chan[ch].next_src, 32, 32, value); | ||
261 | break; | ||
262 | case DMA_EXEC_CONFIG: | ||
263 | case DMA_EXEC_BYTES: | ||
264 | + case DMA_EXEC_BYTES + 4: | ||
265 | case DMA_EXEC_DST: | ||
266 | + case DMA_EXEC_DST + 4: | ||
267 | case DMA_EXEC_SRC: | ||
268 | + case DMA_EXEC_SRC + 4: | ||
269 | /* these are read-only registers */ | ||
270 | break; | ||
271 | default: | ||
272 | - qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", | ||
273 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
274 | + "%s: Unexpected 32-bit access to 0x%" HWADDR_PRIX "\n", | ||
275 | __func__, offset); | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | +static void sifive_pdma_write(void *opaque, hwaddr offset, | ||
281 | + uint64_t value, unsigned size) | ||
282 | +{ | ||
283 | + SiFivePDMAState *s = opaque; | ||
284 | + int ch = SIFIVE_PDMA_CHAN_NO(offset); | ||
285 | + | 147 | + |
286 | + if (ch >= SIFIVE_PDMA_CHANS) { | 148 | + kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); |
287 | + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n", | 149 | + |
288 | + __func__, ch); | ||
289 | + return; | 150 | + return; |
290 | + } | 151 | + } |
152 | +#endif | ||
291 | + | 153 | + |
292 | + switch (size) { | 154 | /* Writes only supported for MSI little-endian registers */ |
293 | + case 8: | 155 | page = addr >> IMSIC_MMIO_PAGE_SHIFT; |
294 | + sifive_pdma_writeq(s, ch, offset, value); | 156 | if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) { |
295 | + break; | 157 | @@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) |
296 | + case 4: | 158 | CPUState *cpu = cpu_by_arch_id(imsic->hartid); |
297 | + sifive_pdma_writel(s, ch, offset, (uint32_t) value); | 159 | CPURISCVState *env = cpu ? cpu->env_ptr : NULL; |
298 | + break; | 160 | |
299 | + default: | 161 | - imsic->num_eistate = imsic->num_pages * imsic->num_irqs; |
300 | + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid write size %u to PDMA\n", | 162 | - imsic->eidelivery = g_new0(uint32_t, imsic->num_pages); |
301 | + __func__, size); | 163 | - imsic->eithreshold = g_new0(uint32_t, imsic->num_pages); |
302 | + break; | 164 | - imsic->eistate = g_new0(uint32_t, imsic->num_eistate); |
165 | + if (!kvm_irqchip_in_kernel()) { | ||
166 | + imsic->num_eistate = imsic->num_pages * imsic->num_irqs; | ||
167 | + imsic->eidelivery = g_new0(uint32_t, imsic->num_pages); | ||
168 | + imsic->eithreshold = g_new0(uint32_t, imsic->num_pages); | ||
169 | + imsic->eistate = g_new0(uint32_t, imsic->num_eistate); | ||
303 | + } | 170 | + } |
304 | +} | 171 | |
305 | + | 172 | memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops, |
306 | static const MemoryRegionOps sifive_pdma_ops = { | 173 | imsic, TYPE_RISCV_IMSIC, |
307 | .read = sifive_pdma_read, | ||
308 | .write = sifive_pdma_write, | ||
309 | -- | 174 | -- |
310 | 2.31.1 | 175 | 2.41.0 |
311 | |||
312 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Renaming defines for quad in their various forms so that their signedness is | 3 | Select KVM AIA when the host kernel has in-kernel AIA chip support. |
4 | now explicit. | 4 | Since KVM AIA only has one APLIC instance, we map the QEMU APLIC |
5 | Done using git grep as suggested by Philippe, with a bit of hand edition to | 5 | devices to KVM APLIC. |
6 | keep assignments aligned. | ||
7 | 6 | ||
8 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 7 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
9 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 8 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
12 | Message-id: 20220106210108.138226-2-frederic.petrot@univ-grenoble-alpes.fr | 11 | Message-ID: <20230727102439.22554-6-yongxuan.wang@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 | include/exec/memop.h | 8 +-- | 14 | hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++---------------- |
16 | include/tcg/tcg-op.h | 4 +- | 15 | 1 file changed, 63 insertions(+), 31 deletions(-) |
17 | target/arm/translate-a32.h | 4 +- | ||
18 | accel/tcg/cputlb.c | 30 +++++------ | ||
19 | accel/tcg/user-exec.c | 8 +-- | ||
20 | target/alpha/translate.c | 32 ++++++------ | ||
21 | target/arm/helper-a64.c | 8 +-- | ||
22 | target/arm/translate-a64.c | 8 +-- | ||
23 | target/arm/translate-neon.c | 6 +-- | ||
24 | target/arm/translate-sve.c | 10 ++-- | ||
25 | target/arm/translate-vfp.c | 8 +-- | ||
26 | target/arm/translate.c | 2 +- | ||
27 | target/cris/translate.c | 2 +- | ||
28 | target/hppa/translate.c | 4 +- | ||
29 | target/i386/tcg/mem_helper.c | 2 +- | ||
30 | target/i386/tcg/translate.c | 36 +++++++------- | ||
31 | target/m68k/op_helper.c | 2 +- | ||
32 | target/mips/tcg/translate.c | 58 +++++++++++----------- | ||
33 | target/mips/tcg/tx79_translate.c | 8 +-- | ||
34 | target/ppc/translate.c | 32 ++++++------ | ||
35 | target/s390x/tcg/mem_helper.c | 8 +-- | ||
36 | target/s390x/tcg/translate.c | 8 +-- | ||
37 | target/sh4/translate.c | 12 ++--- | ||
38 | target/sparc/translate.c | 36 +++++++------- | ||
39 | target/tricore/translate.c | 4 +- | ||
40 | target/xtensa/translate.c | 4 +- | ||
41 | tcg/tcg.c | 4 +- | ||
42 | tcg/tci.c | 16 +++--- | ||
43 | accel/tcg/ldst_common.c.inc | 8 +-- | ||
44 | target/mips/tcg/micromips_translate.c.inc | 10 ++-- | ||
45 | target/ppc/translate/fixedpoint-impl.c.inc | 22 ++++---- | ||
46 | target/ppc/translate/fp-impl.c.inc | 4 +- | ||
47 | target/ppc/translate/vsx-impl.c.inc | 42 ++++++++-------- | ||
48 | target/riscv/insn_trans/trans_rva.c.inc | 22 ++++---- | ||
49 | target/riscv/insn_trans/trans_rvd.c.inc | 4 +- | ||
50 | target/riscv/insn_trans/trans_rvh.c.inc | 4 +- | ||
51 | target/riscv/insn_trans/trans_rvi.c.inc | 4 +- | ||
52 | target/s390x/tcg/translate_vx.c.inc | 18 +++---- | ||
53 | tcg/aarch64/tcg-target.c.inc | 2 +- | ||
54 | tcg/arm/tcg-target.c.inc | 10 ++-- | ||
55 | tcg/i386/tcg-target.c.inc | 12 ++--- | ||
56 | tcg/mips/tcg-target.c.inc | 12 ++--- | ||
57 | tcg/ppc/tcg-target.c.inc | 16 +++--- | ||
58 | tcg/riscv/tcg-target.c.inc | 6 +-- | ||
59 | tcg/s390x/tcg-target.c.inc | 18 +++---- | ||
60 | tcg/sparc/tcg-target.c.inc | 16 +++--- | ||
61 | target/s390x/tcg/insn-data.def | 28 +++++------ | ||
62 | 47 files changed, 311 insertions(+), 311 deletions(-) | ||
63 | 16 | ||
64 | diff --git a/include/exec/memop.h b/include/exec/memop.h | 17 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
65 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
66 | --- a/include/exec/memop.h | 19 | --- a/hw/riscv/virt.c |
67 | +++ b/include/exec/memop.h | 20 | +++ b/hw/riscv/virt.c |
68 | @@ -XXX,XX +XXX,XX @@ typedef enum MemOp { | 21 | @@ -XXX,XX +XXX,XX @@ |
69 | MO_UB = MO_8, | 22 | #include "hw/riscv/virt.h" |
70 | MO_UW = MO_16, | 23 | #include "hw/riscv/boot.h" |
71 | MO_UL = MO_32, | 24 | #include "hw/riscv/numa.h" |
72 | + MO_UQ = MO_64, | 25 | +#include "kvm_riscv.h" |
73 | MO_SB = MO_SIGN | MO_8, | 26 | #include "hw/intc/riscv_aclint.h" |
74 | MO_SW = MO_SIGN | MO_16, | 27 | #include "hw/intc/riscv_aplic.h" |
75 | MO_SL = MO_SIGN | MO_32, | 28 | #include "hw/intc/riscv_imsic.h" |
76 | - MO_Q = MO_64, | 29 | @@ -XXX,XX +XXX,XX @@ |
77 | 30 | #error "Can't accommodate all IMSIC groups in address space" | |
78 | MO_LEUW = MO_LE | MO_UW, | ||
79 | MO_LEUL = MO_LE | MO_UL, | ||
80 | + MO_LEUQ = MO_LE | MO_UQ, | ||
81 | MO_LESW = MO_LE | MO_SW, | ||
82 | MO_LESL = MO_LE | MO_SL, | ||
83 | - MO_LEQ = MO_LE | MO_Q, | ||
84 | |||
85 | MO_BEUW = MO_BE | MO_UW, | ||
86 | MO_BEUL = MO_BE | MO_UL, | ||
87 | + MO_BEUQ = MO_BE | MO_UQ, | ||
88 | MO_BESW = MO_BE | MO_SW, | ||
89 | MO_BESL = MO_BE | MO_SL, | ||
90 | - MO_BEQ = MO_BE | MO_Q, | ||
91 | |||
92 | #ifdef NEED_CPU_H | ||
93 | MO_TEUW = MO_TE | MO_UW, | ||
94 | MO_TEUL = MO_TE | MO_UL, | ||
95 | + MO_TEUQ = MO_TE | MO_UQ, | ||
96 | MO_TESW = MO_TE | MO_SW, | ||
97 | MO_TESL = MO_TE | MO_SL, | ||
98 | - MO_TEQ = MO_TE | MO_Q, | ||
99 | #endif | 31 | #endif |
100 | 32 | ||
101 | MO_SSIZE = MO_SIZE | MO_SIGN, | 33 | +/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */ |
102 | diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h | 34 | +static bool virt_use_kvm_aia(RISCVVirtState *s) |
103 | index XXXXXXX..XXXXXXX 100644 | 35 | +{ |
104 | --- a/include/tcg/tcg-op.h | 36 | + return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC; |
105 | +++ b/include/tcg/tcg-op.h | 37 | +} |
106 | @@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index) | 38 | + |
107 | 39 | static const MemMapEntry virt_memmap[] = { | |
108 | static inline void tcg_gen_qemu_ld64(TCGv_i64 ret, TCGv addr, int mem_index) | 40 | [VIRT_DEBUG] = { 0x0, 0x100 }, |
41 | [VIRT_MROM] = { 0x1000, 0xf000 }, | ||
42 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket, | ||
43 | uint32_t *intc_phandles, | ||
44 | uint32_t aplic_phandle, | ||
45 | uint32_t aplic_child_phandle, | ||
46 | - bool m_mode) | ||
47 | + bool m_mode, int num_harts) | ||
109 | { | 48 | { |
110 | - tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEQ); | 49 | int cpu; |
111 | + tcg_gen_qemu_ld_i64(ret, addr, mem_index, MO_TEUQ); | 50 | char *aplic_name; |
112 | } | 51 | uint32_t *aplic_cells; |
113 | 52 | MachineState *ms = MACHINE(s); | |
114 | static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index) | 53 | |
115 | @@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index) | 54 | - aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); |
116 | 55 | + aplic_cells = g_new0(uint32_t, num_harts * 2); | |
117 | static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) | 56 | |
57 | - for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
58 | + for (cpu = 0; cpu < num_harts; cpu++) { | ||
59 | aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
60 | aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT); | ||
61 | } | ||
62 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket, | ||
63 | |||
64 | if (s->aia_type == VIRT_AIA_TYPE_APLIC) { | ||
65 | qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended", | ||
66 | - aplic_cells, | ||
67 | - s->soc[socket].num_harts * sizeof(uint32_t) * 2); | ||
68 | + aplic_cells, num_harts * sizeof(uint32_t) * 2); | ||
69 | } else { | ||
70 | qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle); | ||
71 | } | ||
72 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
73 | uint32_t msi_s_phandle, | ||
74 | uint32_t *phandle, | ||
75 | uint32_t *intc_phandles, | ||
76 | - uint32_t *aplic_phandles) | ||
77 | + uint32_t *aplic_phandles, | ||
78 | + int num_harts) | ||
118 | { | 79 | { |
119 | - tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEQ); | 80 | char *aplic_name; |
120 | + tcg_gen_qemu_st_i64(arg, addr, mem_index, MO_TEUQ); | 81 | unsigned long aplic_addr; |
121 | } | 82 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, |
122 | 83 | create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size, | |
123 | void tcg_gen_atomic_cmpxchg_i32(TCGv_i32, TCGv, TCGv_i32, TCGv_i32, | 84 | msi_m_phandle, intc_phandles, |
124 | diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h | 85 | aplic_m_phandle, aplic_s_phandle, |
125 | index XXXXXXX..XXXXXXX 100644 | 86 | - true); |
126 | --- a/target/arm/translate-a32.h | 87 | + true, num_harts); |
127 | +++ b/target/arm/translate-a32.h | 88 | } |
128 | @@ -XXX,XX +XXX,XX @@ void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32, | 89 | |
129 | static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, | 90 | /* S-level APLIC node */ |
130 | TCGv_i32 a32, int index) | 91 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, |
131 | { | 92 | create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size, |
132 | - gen_aa32_ld_i64(s, val, a32, index, MO_Q); | 93 | msi_s_phandle, intc_phandles, |
133 | + gen_aa32_ld_i64(s, val, a32, index, MO_UQ); | 94 | aplic_s_phandle, 0, |
134 | } | 95 | - false); |
135 | 96 | + false, num_harts); | |
136 | static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, | 97 | |
137 | TCGv_i32 a32, int index) | 98 | aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr); |
138 | { | 99 | |
139 | - gen_aa32_st_i64(s, val, a32, index, MO_Q); | 100 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
140 | + gen_aa32_st_i64(s, val, a32, index, MO_UQ); | 101 | *msi_pcie_phandle = msi_s_phandle; |
141 | } | 102 | } |
142 | 103 | ||
143 | DO_GEN_LD(8u, MO_UB) | 104 | - phandle_pos = ms->smp.cpus; |
144 | diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c | 105 | - for (socket = (socket_count - 1); socket >= 0; socket--) { |
145 | index XXXXXXX..XXXXXXX 100644 | 106 | - phandle_pos -= s->soc[socket].num_harts; |
146 | --- a/accel/tcg/cputlb.c | 107 | - |
147 | +++ b/accel/tcg/cputlb.c | 108 | - if (s->aia_type == VIRT_AIA_TYPE_NONE) { |
148 | @@ -XXX,XX +XXX,XX @@ load_memop(const void *haddr, MemOp op) | 109 | - create_fdt_socket_plic(s, memmap, socket, phandle, |
149 | return (uint32_t)ldl_be_p(haddr); | 110 | - &intc_phandles[phandle_pos], xplic_phandles); |
150 | case MO_LEUL: | 111 | - } else { |
151 | return (uint32_t)ldl_le_p(haddr); | 112 | - create_fdt_socket_aplic(s, memmap, socket, |
152 | - case MO_BEQ: | 113 | - msi_m_phandle, msi_s_phandle, phandle, |
153 | + case MO_BEUQ: | 114 | - &intc_phandles[phandle_pos], xplic_phandles); |
154 | return ldq_be_p(haddr); | 115 | + /* KVM AIA only has one APLIC instance */ |
155 | - case MO_LEQ: | 116 | + if (virt_use_kvm_aia(s)) { |
156 | + case MO_LEUQ: | 117 | + create_fdt_socket_aplic(s, memmap, 0, |
157 | return ldq_le_p(haddr); | 118 | + msi_m_phandle, msi_s_phandle, phandle, |
158 | default: | 119 | + &intc_phandles[0], xplic_phandles, |
159 | qemu_build_not_reached(); | 120 | + ms->smp.cpus); |
160 | @@ -XXX,XX +XXX,XX @@ tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr, | 121 | + } else { |
161 | uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr, | 122 | + phandle_pos = ms->smp.cpus; |
162 | MemOpIdx oi, uintptr_t retaddr) | 123 | + for (socket = (socket_count - 1); socket >= 0; socket--) { |
163 | { | 124 | + phandle_pos -= s->soc[socket].num_harts; |
164 | - validate_memop(oi, MO_LEQ); | 125 | + |
165 | - return load_helper(env, addr, oi, retaddr, MO_LEQ, false, | 126 | + if (s->aia_type == VIRT_AIA_TYPE_NONE) { |
166 | + validate_memop(oi, MO_LEUQ); | 127 | + create_fdt_socket_plic(s, memmap, socket, phandle, |
167 | + return load_helper(env, addr, oi, retaddr, MO_LEUQ, false, | 128 | + &intc_phandles[phandle_pos], |
168 | helper_le_ldq_mmu); | 129 | + xplic_phandles); |
169 | } | 130 | + } else { |
170 | 131 | + create_fdt_socket_aplic(s, memmap, socket, | |
171 | uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr, | 132 | + msi_m_phandle, msi_s_phandle, phandle, |
172 | MemOpIdx oi, uintptr_t retaddr) | 133 | + &intc_phandles[phandle_pos], |
173 | { | 134 | + xplic_phandles, |
174 | - validate_memop(oi, MO_BEQ); | 135 | + s->soc[socket].num_harts); |
175 | - return load_helper(env, addr, oi, retaddr, MO_BEQ, false, | 136 | + } |
176 | + validate_memop(oi, MO_BEUQ); | ||
177 | + return load_helper(env, addr, oi, retaddr, MO_BEUQ, false, | ||
178 | helper_be_ldq_mmu); | ||
179 | } | ||
180 | |||
181 | @@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_be_mmu(CPUArchState *env, abi_ptr addr, | ||
182 | uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr, | ||
183 | MemOpIdx oi, uintptr_t ra) | ||
184 | { | ||
185 | - return cpu_load_helper(env, addr, oi, MO_BEQ, helper_be_ldq_mmu); | ||
186 | + return cpu_load_helper(env, addr, oi, MO_BEUQ, helper_be_ldq_mmu); | ||
187 | } | ||
188 | |||
189 | uint16_t cpu_ldw_le_mmu(CPUArchState *env, abi_ptr addr, | ||
190 | @@ -XXX,XX +XXX,XX @@ store_memop(void *haddr, uint64_t val, MemOp op) | ||
191 | case MO_LEUL: | ||
192 | stl_le_p(haddr, val); | ||
193 | break; | ||
194 | - case MO_BEQ: | ||
195 | + case MO_BEUQ: | ||
196 | stq_be_p(haddr, val); | ||
197 | break; | ||
198 | - case MO_LEQ: | ||
199 | + case MO_LEUQ: | ||
200 | stq_le_p(haddr, val); | ||
201 | break; | ||
202 | default: | ||
203 | @@ -XXX,XX +XXX,XX @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, | ||
204 | void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, | ||
205 | MemOpIdx oi, uintptr_t retaddr) | ||
206 | { | ||
207 | - validate_memop(oi, MO_LEQ); | ||
208 | - store_helper(env, addr, val, oi, retaddr, MO_LEQ); | ||
209 | + validate_memop(oi, MO_LEUQ); | ||
210 | + store_helper(env, addr, val, oi, retaddr, MO_LEUQ); | ||
211 | } | ||
212 | |||
213 | void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, | ||
214 | MemOpIdx oi, uintptr_t retaddr) | ||
215 | { | ||
216 | - validate_memop(oi, MO_BEQ); | ||
217 | - store_helper(env, addr, val, oi, retaddr, MO_BEQ); | ||
218 | + validate_memop(oi, MO_BEUQ); | ||
219 | + store_helper(env, addr, val, oi, retaddr, MO_BEUQ); | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | @@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr) | ||
224 | static uint64_t full_ldq_code(CPUArchState *env, target_ulong addr, | ||
225 | MemOpIdx oi, uintptr_t retaddr) | ||
226 | { | ||
227 | - return load_helper(env, addr, oi, retaddr, MO_TEQ, true, full_ldq_code); | ||
228 | + return load_helper(env, addr, oi, retaddr, MO_TEUQ, true, full_ldq_code); | ||
229 | } | ||
230 | |||
231 | uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr) | ||
232 | { | ||
233 | - MemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true)); | ||
234 | + MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true)); | ||
235 | return full_ldq_code(env, addr, oi, 0); | ||
236 | } | ||
237 | diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c | ||
238 | index XXXXXXX..XXXXXXX 100644 | ||
239 | --- a/accel/tcg/user-exec.c | ||
240 | +++ b/accel/tcg/user-exec.c | ||
241 | @@ -XXX,XX +XXX,XX @@ uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr, | ||
242 | void *haddr; | ||
243 | uint64_t ret; | ||
244 | |||
245 | - validate_memop(oi, MO_BEQ); | ||
246 | + validate_memop(oi, MO_BEUQ); | ||
247 | trace_guest_ld_before_exec(env_cpu(env), addr, oi); | ||
248 | haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD); | ||
249 | ret = ldq_be_p(haddr); | ||
250 | @@ -XXX,XX +XXX,XX @@ uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr, | ||
251 | void *haddr; | ||
252 | uint64_t ret; | ||
253 | |||
254 | - validate_memop(oi, MO_LEQ); | ||
255 | + validate_memop(oi, MO_LEUQ); | ||
256 | trace_guest_ld_before_exec(env_cpu(env), addr, oi); | ||
257 | haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD); | ||
258 | ret = ldq_le_p(haddr); | ||
259 | @@ -XXX,XX +XXX,XX @@ void cpu_stq_be_mmu(CPUArchState *env, abi_ptr addr, uint64_t val, | ||
260 | { | ||
261 | void *haddr; | ||
262 | |||
263 | - validate_memop(oi, MO_BEQ); | ||
264 | + validate_memop(oi, MO_BEUQ); | ||
265 | trace_guest_st_before_exec(env_cpu(env), addr, oi); | ||
266 | haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE); | ||
267 | stq_be_p(haddr, val); | ||
268 | @@ -XXX,XX +XXX,XX @@ void cpu_stq_le_mmu(CPUArchState *env, abi_ptr addr, uint64_t val, | ||
269 | { | ||
270 | void *haddr; | ||
271 | |||
272 | - validate_memop(oi, MO_LEQ); | ||
273 | + validate_memop(oi, MO_LEUQ); | ||
274 | trace_guest_st_before_exec(env_cpu(env), addr, oi); | ||
275 | haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE); | ||
276 | stq_le_p(haddr, val); | ||
277 | diff --git a/target/alpha/translate.c b/target/alpha/translate.c | ||
278 | index XXXXXXX..XXXXXXX 100644 | ||
279 | --- a/target/alpha/translate.c | ||
280 | +++ b/target/alpha/translate.c | ||
281 | @@ -XXX,XX +XXX,XX @@ static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr) | ||
282 | static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr) | ||
283 | { | ||
284 | TCGv tmp = tcg_temp_new(); | ||
285 | - tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEQ | UNALIGN(ctx)); | ||
286 | + tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); | ||
287 | gen_helper_memory_to_g(dest, tmp); | ||
288 | tcg_temp_free(tmp); | ||
289 | } | ||
290 | @@ -XXX,XX +XXX,XX @@ static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr) | ||
291 | |||
292 | static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr) | ||
293 | { | ||
294 | - tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEQ | UNALIGN(ctx)); | ||
295 | + tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); | ||
296 | } | ||
297 | |||
298 | static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, | ||
299 | @@ -XXX,XX +XXX,XX @@ static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr) | ||
300 | { | ||
301 | TCGv tmp = tcg_temp_new(); | ||
302 | gen_helper_g_to_memory(tmp, src); | ||
303 | - tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEQ | UNALIGN(ctx)); | ||
304 | + tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); | ||
305 | tcg_temp_free(tmp); | ||
306 | } | ||
307 | |||
308 | @@ -XXX,XX +XXX,XX @@ static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr) | ||
309 | |||
310 | static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr) | ||
311 | { | ||
312 | - tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEQ | UNALIGN(ctx)); | ||
313 | + tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); | ||
314 | } | ||
315 | |||
316 | static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, | ||
317 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
318 | break; | ||
319 | case 0x0B: | ||
320 | /* LDQ_U */ | ||
321 | - gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 1, 0); | ||
322 | + gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 1, 0); | ||
323 | break; | ||
324 | case 0x0C: | ||
325 | /* LDWU */ | ||
326 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
327 | break; | ||
328 | case 0x0F: | ||
329 | /* STQ_U */ | ||
330 | - gen_store_int(ctx, ra, rb, disp16, MO_LEQ, 1); | ||
331 | + gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 1); | ||
332 | break; | ||
333 | |||
334 | case 0x10: | ||
335 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
336 | break; | ||
337 | case 0x1: | ||
338 | /* Quadword physical access (hw_ldq/p) */ | ||
339 | - tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ); | ||
340 | + tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ); | ||
341 | break; | ||
342 | case 0x2: | ||
343 | /* Longword physical access with lock (hw_ldl_l/p) */ | ||
344 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
345 | break; | ||
346 | case 0x3: | ||
347 | /* Quadword physical access with lock (hw_ldq_l/p) */ | ||
348 | - tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ); | ||
349 | + tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ); | ||
350 | tcg_gen_mov_i64(cpu_lock_addr, addr); | ||
351 | tcg_gen_mov_i64(cpu_lock_value, va); | ||
352 | break; | ||
353 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
354 | break; | ||
355 | case 0xB: | ||
356 | /* Quadword virtual access with protection check (hw_ldq/w) */ | ||
357 | - tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEQ); | ||
358 | + tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEUQ); | ||
359 | break; | ||
360 | case 0xC: | ||
361 | /* Longword virtual access with alt access mode (hw_ldl/a)*/ | ||
362 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
363 | case 0xF: | ||
364 | /* Quadword virtual access with alternate access mode and | ||
365 | protection checks (hw_ldq/wa) */ | ||
366 | - tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEQ); | ||
367 | + tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEUQ); | ||
368 | break; | ||
369 | } | ||
370 | tcg_temp_free(addr); | ||
371 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
372 | vb = load_gpr(ctx, rb); | ||
373 | tmp = tcg_temp_new(); | ||
374 | tcg_gen_addi_i64(tmp, vb, disp12); | ||
375 | - tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEQ); | ||
376 | + tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEUQ); | ||
377 | tcg_temp_free(tmp); | ||
378 | break; | ||
379 | case 0x2: | ||
380 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
381 | case 0x3: | ||
382 | /* Quadword physical access with lock */ | ||
383 | ret = gen_store_conditional(ctx, ra, rb, disp12, | ||
384 | - MMU_PHYS_IDX, MO_LEQ); | ||
385 | + MMU_PHYS_IDX, MO_LEUQ); | ||
386 | break; | ||
387 | case 0x4: | ||
388 | /* Longword virtual access */ | ||
389 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
390 | break; | ||
391 | case 0x29: | ||
392 | /* LDQ */ | ||
393 | - gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 0, 0); | ||
394 | + gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 0); | ||
395 | break; | ||
396 | case 0x2A: | ||
397 | /* LDL_L */ | ||
398 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
399 | break; | ||
400 | case 0x2B: | ||
401 | /* LDQ_L */ | ||
402 | - gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 0, 1); | ||
403 | + gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 1); | ||
404 | break; | ||
405 | case 0x2C: | ||
406 | /* STL */ | ||
407 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
408 | break; | ||
409 | case 0x2D: | ||
410 | /* STQ */ | ||
411 | - gen_store_int(ctx, ra, rb, disp16, MO_LEQ, 0); | ||
412 | + gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 0); | ||
413 | break; | ||
414 | case 0x2E: | ||
415 | /* STL_C */ | ||
416 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) | ||
417 | case 0x2F: | ||
418 | /* STQ_C */ | ||
419 | ret = gen_store_conditional(ctx, ra, rb, disp16, | ||
420 | - ctx->mem_idx, MO_LEQ); | ||
421 | + ctx->mem_idx, MO_LEUQ); | ||
422 | break; | ||
423 | case 0x30: | ||
424 | /* BR */ | ||
425 | diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c | ||
426 | index XXXXXXX..XXXXXXX 100644 | ||
427 | --- a/target/arm/helper-a64.c | ||
428 | +++ b/target/arm/helper-a64.c | ||
429 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr, | ||
430 | uint64_t o0, o1; | ||
431 | bool success; | ||
432 | int mem_idx = cpu_mmu_index(env, false); | ||
433 | - MemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx); | ||
434 | - MemOpIdx oi1 = make_memop_idx(MO_LEQ, mem_idx); | ||
435 | + MemOpIdx oi0 = make_memop_idx(MO_LEUQ | MO_ALIGN_16, mem_idx); | ||
436 | + MemOpIdx oi1 = make_memop_idx(MO_LEUQ, mem_idx); | ||
437 | |||
438 | o0 = cpu_ldq_le_mmu(env, addr + 0, oi0, ra); | ||
439 | o1 = cpu_ldq_le_mmu(env, addr + 8, oi1, ra); | ||
440 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr, | ||
441 | uint64_t o0, o1; | ||
442 | bool success; | ||
443 | int mem_idx = cpu_mmu_index(env, false); | ||
444 | - MemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx); | ||
445 | - MemOpIdx oi1 = make_memop_idx(MO_BEQ, mem_idx); | ||
446 | + MemOpIdx oi0 = make_memop_idx(MO_BEUQ | MO_ALIGN_16, mem_idx); | ||
447 | + MemOpIdx oi1 = make_memop_idx(MO_BEUQ, mem_idx); | ||
448 | |||
449 | o1 = cpu_ldq_be_mmu(env, addr + 0, oi0, ra); | ||
450 | o0 = cpu_ldq_be_mmu(env, addr + 8, oi1, ra); | ||
451 | diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c | ||
452 | index XXXXXXX..XXXXXXX 100644 | ||
453 | --- a/target/arm/translate-a64.c | ||
454 | +++ b/target/arm/translate-a64.c | ||
455 | @@ -XXX,XX +XXX,XX @@ static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size) | ||
456 | |||
457 | tcg_gen_ld_i64(tmphi, cpu_env, fp_reg_hi_offset(s, srcidx)); | ||
458 | |||
459 | - mop = s->be_data | MO_Q; | ||
460 | + mop = s->be_data | MO_UQ; | ||
461 | tcg_gen_qemu_st_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s), | ||
462 | mop | (s->align_mem ? MO_ALIGN_16 : 0)); | ||
463 | tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8); | ||
464 | @@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) | ||
465 | tmphi = tcg_temp_new_i64(); | ||
466 | tcg_hiaddr = tcg_temp_new_i64(); | ||
467 | |||
468 | - mop = s->be_data | MO_Q; | ||
469 | + mop = s->be_data | MO_UQ; | ||
470 | tcg_gen_qemu_ld_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s), | ||
471 | mop | (s->align_mem ? MO_ALIGN_16 : 0)); | ||
472 | tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8); | ||
473 | @@ -XXX,XX +XXX,XX @@ static void disas_ldst_tag(DisasContext *s, uint32_t insn) | ||
474 | int i, n = (1 + is_pair) << LOG2_TAG_GRANULE; | ||
475 | |||
476 | tcg_gen_qemu_st_i64(tcg_zero, clean_addr, mem_index, | ||
477 | - MO_Q | MO_ALIGN_16); | ||
478 | + MO_UQ | MO_ALIGN_16); | ||
479 | for (i = 8; i < n; i += 8) { | ||
480 | tcg_gen_addi_i64(clean_addr, clean_addr, 8); | ||
481 | - tcg_gen_qemu_st_i64(tcg_zero, clean_addr, mem_index, MO_Q); | ||
482 | + tcg_gen_qemu_st_i64(tcg_zero, clean_addr, mem_index, MO_UQ); | ||
483 | } | 137 | } |
484 | tcg_temp_free_i64(tcg_zero); | ||
485 | } | 138 | } |
486 | diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c | 139 | |
487 | index XXXXXXX..XXXXXXX 100644 | 140 | g_free(intc_phandles); |
488 | --- a/target/arm/translate-neon.c | 141 | |
489 | +++ b/target/arm/translate-neon.c | 142 | - for (socket = 0; socket < socket_count; socket++) { |
490 | @@ -XXX,XX +XXX,XX @@ static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop) | 143 | - if (socket == 0) { |
491 | case MO_UL: | 144 | - *irq_mmio_phandle = xplic_phandles[socket]; |
492 | tcg_gen_ld32u_i64(var, cpu_env, offset); | 145 | - *irq_virtio_phandle = xplic_phandles[socket]; |
493 | break; | 146 | - *irq_pcie_phandle = xplic_phandles[socket]; |
494 | - case MO_Q: | 147 | - } |
495 | + case MO_UQ: | 148 | - if (socket == 1) { |
496 | tcg_gen_ld_i64(var, cpu_env, offset); | 149 | - *irq_virtio_phandle = xplic_phandles[socket]; |
497 | break; | 150 | - *irq_pcie_phandle = xplic_phandles[socket]; |
498 | default: | 151 | - } |
499 | @@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a, | 152 | - if (socket == 2) { |
500 | return false; | 153 | - *irq_pcie_phandle = xplic_phandles[socket]; |
154 | + if (virt_use_kvm_aia(s)) { | ||
155 | + *irq_mmio_phandle = xplic_phandles[0]; | ||
156 | + *irq_virtio_phandle = xplic_phandles[0]; | ||
157 | + *irq_pcie_phandle = xplic_phandles[0]; | ||
158 | + } else { | ||
159 | + for (socket = 0; socket < socket_count; socket++) { | ||
160 | + if (socket == 0) { | ||
161 | + *irq_mmio_phandle = xplic_phandles[socket]; | ||
162 | + *irq_virtio_phandle = xplic_phandles[socket]; | ||
163 | + *irq_pcie_phandle = xplic_phandles[socket]; | ||
164 | + } | ||
165 | + if (socket == 1) { | ||
166 | + *irq_virtio_phandle = xplic_phandles[socket]; | ||
167 | + *irq_pcie_phandle = xplic_phandles[socket]; | ||
168 | + } | ||
169 | + if (socket == 2) { | ||
170 | + *irq_pcie_phandle = xplic_phandles[socket]; | ||
171 | + } | ||
172 | } | ||
501 | } | 173 | } |
502 | 174 | ||
503 | - if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) { | 175 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) |
504 | + if ((a->vd & 1) || (src1_mop == MO_UQ && (a->vn & 1))) { | 176 | } |
505 | return false; | ||
506 | } | 177 | } |
507 | 178 | ||
508 | @@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a, | 179 | + if (virt_use_kvm_aia(s)) { |
509 | }; \ | 180 | + kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT, |
510 | int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \ | 181 | + VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS, |
511 | return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \ | 182 | + memmap[VIRT_APLIC_S].base, |
512 | - SRC1WIDE ? MO_Q : narrow_mop, \ | 183 | + memmap[VIRT_IMSIC_S].base, |
513 | + SRC1WIDE ? MO_UQ : narrow_mop, \ | 184 | + s->aia_guests); |
514 | narrow_mop); \ | 185 | + } |
515 | } | 186 | + |
516 | 187 | if (riscv_is_32bit(&s->soc[0])) { | |
517 | diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c | 188 | #if HOST_LONG_BITS == 64 |
518 | index XXXXXXX..XXXXXXX 100644 | 189 | /* limit RAM size in a 32-bit system */ |
519 | --- a/target/arm/translate-sve.c | ||
520 | +++ b/target/arm/translate-sve.c | ||
521 | @@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm) | ||
522 | |||
523 | t0 = tcg_temp_new_i64(); | ||
524 | for (i = 0; i < len_align; i += 8) { | ||
525 | - tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEQ); | ||
526 | + tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ); | ||
527 | tcg_gen_st_i64(t0, cpu_env, vofs + i); | ||
528 | tcg_gen_addi_i64(clean_addr, clean_addr, 8); | ||
529 | } | ||
530 | @@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm) | ||
531 | gen_set_label(loop); | ||
532 | |||
533 | t0 = tcg_temp_new_i64(); | ||
534 | - tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEQ); | ||
535 | + tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ); | ||
536 | tcg_gen_addi_i64(clean_addr, clean_addr, 8); | ||
537 | |||
538 | tp = tcg_temp_new_ptr(); | ||
539 | @@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm) | ||
540 | t0 = tcg_temp_new_i64(); | ||
541 | for (i = 0; i < len_align; i += 8) { | ||
542 | tcg_gen_ld_i64(t0, cpu_env, vofs + i); | ||
543 | - tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEQ); | ||
544 | + tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ); | ||
545 | tcg_gen_addi_i64(clean_addr, clean_addr, 8); | ||
546 | } | ||
547 | tcg_temp_free_i64(t0); | ||
548 | @@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm) | ||
549 | tcg_gen_addi_ptr(i, i, 8); | ||
550 | tcg_temp_free_ptr(tp); | ||
551 | |||
552 | - tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEQ); | ||
553 | + tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ); | ||
554 | tcg_gen_addi_i64(clean_addr, clean_addr, 8); | ||
555 | tcg_temp_free_i64(t0); | ||
556 | |||
557 | @@ -XXX,XX +XXX,XX @@ static const MemOp dtype_mop[16] = { | ||
558 | MO_UB, MO_UB, MO_UB, MO_UB, | ||
559 | MO_SL, MO_UW, MO_UW, MO_UW, | ||
560 | MO_SW, MO_SW, MO_UL, MO_UL, | ||
561 | - MO_SB, MO_SB, MO_SB, MO_Q | ||
562 | + MO_SB, MO_SB, MO_SB, MO_UQ | ||
563 | }; | ||
564 | |||
565 | #define dtype_msz(x) (dtype_mop[x] & MO_SIZE) | ||
566 | diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c | ||
567 | index XXXXXXX..XXXXXXX 100644 | ||
568 | --- a/target/arm/translate-vfp.c | ||
569 | +++ b/target/arm/translate-vfp.c | ||
570 | @@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a) | ||
571 | addr = add_reg_for_lit(s, a->rn, offset); | ||
572 | tmp = tcg_temp_new_i64(); | ||
573 | if (a->l) { | ||
574 | - gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4); | ||
575 | + gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_UQ | MO_ALIGN_4); | ||
576 | vfp_store_reg64(tmp, a->vd); | ||
577 | } else { | ||
578 | vfp_load_reg64(tmp, a->vd); | ||
579 | - gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4); | ||
580 | + gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_UQ | MO_ALIGN_4); | ||
581 | } | ||
582 | tcg_temp_free_i64(tmp); | ||
583 | tcg_temp_free_i32(addr); | ||
584 | @@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a) | ||
585 | for (i = 0; i < n; i++) { | ||
586 | if (a->l) { | ||
587 | /* load */ | ||
588 | - gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4); | ||
589 | + gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_UQ | MO_ALIGN_4); | ||
590 | vfp_store_reg64(tmp, a->vd + i); | ||
591 | } else { | ||
592 | /* store */ | ||
593 | vfp_load_reg64(tmp, a->vd + i); | ||
594 | - gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4); | ||
595 | + gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_UQ | MO_ALIGN_4); | ||
596 | } | ||
597 | tcg_gen_addi_i32(addr, addr, offset); | ||
598 | } | ||
599 | diff --git a/target/arm/translate.c b/target/arm/translate.c | ||
600 | index XXXXXXX..XXXXXXX 100644 | ||
601 | --- a/target/arm/translate.c | ||
602 | +++ b/target/arm/translate.c | ||
603 | @@ -XXX,XX +XXX,XX @@ void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop) | ||
604 | case MO_UL: | ||
605 | tcg_gen_ld32u_i64(dest, cpu_env, off); | ||
606 | break; | ||
607 | - case MO_Q: | ||
608 | + case MO_UQ: | ||
609 | tcg_gen_ld_i64(dest, cpu_env, off); | ||
610 | break; | ||
611 | default: | ||
612 | diff --git a/target/cris/translate.c b/target/cris/translate.c | ||
613 | index XXXXXXX..XXXXXXX 100644 | ||
614 | --- a/target/cris/translate.c | ||
615 | +++ b/target/cris/translate.c | ||
616 | @@ -XXX,XX +XXX,XX @@ static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) | ||
617 | cris_store_direct_jmp(dc); | ||
618 | } | ||
619 | |||
620 | - tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEQ); | ||
621 | + tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEUQ); | ||
622 | } | ||
623 | |||
624 | static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, | ||
625 | diff --git a/target/hppa/translate.c b/target/hppa/translate.c | ||
626 | index XXXXXXX..XXXXXXX 100644 | ||
627 | --- a/target/hppa/translate.c | ||
628 | +++ b/target/hppa/translate.c | ||
629 | @@ -XXX,XX +XXX,XX @@ static bool do_floadd(DisasContext *ctx, unsigned rt, unsigned rb, | ||
630 | nullify_over(ctx); | ||
631 | |||
632 | tmp = tcg_temp_new_i64(); | ||
633 | - do_load_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ); | ||
634 | + do_load_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUQ); | ||
635 | save_frd(rt, tmp); | ||
636 | tcg_temp_free_i64(tmp); | ||
637 | |||
638 | @@ -XXX,XX +XXX,XX @@ static bool do_fstored(DisasContext *ctx, unsigned rt, unsigned rb, | ||
639 | nullify_over(ctx); | ||
640 | |||
641 | tmp = load_frd(rt); | ||
642 | - do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ); | ||
643 | + do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUQ); | ||
644 | tcg_temp_free_i64(tmp); | ||
645 | |||
646 | return nullify_end(ctx); | ||
647 | diff --git a/target/i386/tcg/mem_helper.c b/target/i386/tcg/mem_helper.c | ||
648 | index XXXXXXX..XXXXXXX 100644 | ||
649 | --- a/target/i386/tcg/mem_helper.c | ||
650 | +++ b/target/i386/tcg/mem_helper.c | ||
651 | @@ -XXX,XX +XXX,XX @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0) | ||
652 | { | ||
653 | uintptr_t ra = GETPC(); | ||
654 | int mem_idx = cpu_mmu_index(env, false); | ||
655 | - MemOpIdx oi = make_memop_idx(MO_TEQ, mem_idx); | ||
656 | + MemOpIdx oi = make_memop_idx(MO_TEUQ, mem_idx); | ||
657 | oldv = cpu_atomic_cmpxchgq_le_mmu(env, a0, cmpv, newv, oi, ra); | ||
658 | } | ||
659 | |||
660 | diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c | ||
661 | index XXXXXXX..XXXXXXX 100644 | ||
662 | --- a/target/i386/tcg/translate.c | ||
663 | +++ b/target/i386/tcg/translate.c | ||
664 | @@ -XXX,XX +XXX,XX @@ static void gen_jmp(DisasContext *s, target_ulong eip) | ||
665 | |||
666 | static inline void gen_ldq_env_A0(DisasContext *s, int offset) | ||
667 | { | ||
668 | - tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ); | ||
669 | + tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); | ||
670 | tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset); | ||
671 | } | ||
672 | |||
673 | static inline void gen_stq_env_A0(DisasContext *s, int offset) | ||
674 | { | ||
675 | tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset); | ||
676 | - tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ); | ||
677 | + tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); | ||
678 | } | ||
679 | |||
680 | static inline void gen_ldo_env_A0(DisasContext *s, int offset) | ||
681 | { | ||
682 | int mem_index = s->mem_index; | ||
683 | - tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, MO_LEQ); | ||
684 | + tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, MO_LEUQ); | ||
685 | tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0))); | ||
686 | tcg_gen_addi_tl(s->tmp0, s->A0, 8); | ||
687 | - tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEQ); | ||
688 | + tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); | ||
689 | tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1))); | ||
690 | } | ||
691 | |||
692 | @@ -XXX,XX +XXX,XX @@ static inline void gen_sto_env_A0(DisasContext *s, int offset) | ||
693 | { | ||
694 | int mem_index = s->mem_index; | ||
695 | tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0))); | ||
696 | - tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, MO_LEQ); | ||
697 | + tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, MO_LEUQ); | ||
698 | tcg_gen_addi_tl(s->tmp0, s->A0, 8); | ||
699 | tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1))); | ||
700 | - tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEQ); | ||
701 | + tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); | ||
702 | } | ||
703 | |||
704 | static inline void gen_op_movo(DisasContext *s, int d_offset, int s_offset) | ||
705 | @@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, | ||
706 | tcg_gen_mov_i64(cpu_regs[rm], s->tmp1_i64); | ||
707 | } else { | ||
708 | tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, | ||
709 | - s->mem_index, MO_LEQ); | ||
710 | + s->mem_index, MO_LEUQ); | ||
711 | } | ||
712 | #else | ||
713 | goto illegal_op; | ||
714 | @@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, | ||
715 | gen_op_mov_v_reg(s, ot, s->tmp1_i64, rm); | ||
716 | } else { | ||
717 | tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, | ||
718 | - s->mem_index, MO_LEQ); | ||
719 | + s->mem_index, MO_LEUQ); | ||
720 | } | ||
721 | tcg_gen_st_i64(s->tmp1_i64, cpu_env, | ||
722 | offsetof(CPUX86State, | ||
723 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
724 | break; | ||
725 | case 2: | ||
726 | tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, | ||
727 | - s->mem_index, MO_LEQ); | ||
728 | + s->mem_index, MO_LEUQ); | ||
729 | gen_helper_fldl_FT0(cpu_env, s->tmp1_i64); | ||
730 | break; | ||
731 | case 3: | ||
732 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
733 | break; | ||
734 | case 2: | ||
735 | tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, | ||
736 | - s->mem_index, MO_LEQ); | ||
737 | + s->mem_index, MO_LEUQ); | ||
738 | gen_helper_fldl_ST0(cpu_env, s->tmp1_i64); | ||
739 | break; | ||
740 | case 3: | ||
741 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
742 | case 2: | ||
743 | gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env); | ||
744 | tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, | ||
745 | - s->mem_index, MO_LEQ); | ||
746 | + s->mem_index, MO_LEUQ); | ||
747 | break; | ||
748 | case 3: | ||
749 | default: | ||
750 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
751 | case 2: | ||
752 | gen_helper_fstl_ST0(s->tmp1_i64, cpu_env); | ||
753 | tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, | ||
754 | - s->mem_index, MO_LEQ); | ||
755 | + s->mem_index, MO_LEUQ); | ||
756 | break; | ||
757 | case 3: | ||
758 | default: | ||
759 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
760 | break; | ||
761 | case 0x3d: /* fildll */ | ||
762 | tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, | ||
763 | - s->mem_index, MO_LEQ); | ||
764 | + s->mem_index, MO_LEUQ); | ||
765 | gen_helper_fildll_ST0(cpu_env, s->tmp1_i64); | ||
766 | break; | ||
767 | case 0x3f: /* fistpll */ | ||
768 | gen_helper_fistll_ST0(s->tmp1_i64, cpu_env); | ||
769 | tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, | ||
770 | - s->mem_index, MO_LEQ); | ||
771 | + s->mem_index, MO_LEUQ); | ||
772 | gen_helper_fpop(cpu_env); | ||
773 | break; | ||
774 | default: | ||
775 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
776 | gen_lea_modrm(env, s, modrm); | ||
777 | if (CODE64(s)) { | ||
778 | tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, | ||
779 | - s->mem_index, MO_LEQ); | ||
780 | + s->mem_index, MO_LEUQ); | ||
781 | tcg_gen_addi_tl(s->A0, s->A0, 8); | ||
782 | tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0, | ||
783 | - s->mem_index, MO_LEQ); | ||
784 | + s->mem_index, MO_LEUQ); | ||
785 | } else { | ||
786 | tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0, | ||
787 | s->mem_index, MO_LEUL); | ||
788 | @@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) | ||
789 | gen_lea_modrm(env, s, modrm); | ||
790 | if (CODE64(s)) { | ||
791 | tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, | ||
792 | - s->mem_index, MO_LEQ); | ||
793 | + s->mem_index, MO_LEUQ); | ||
794 | tcg_gen_addi_tl(s->A0, s->A0, 8); | ||
795 | tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0, | ||
796 | - s->mem_index, MO_LEQ); | ||
797 | + s->mem_index, MO_LEUQ); | ||
798 | } else { | ||
799 | tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0, | ||
800 | s->mem_index, MO_LEUL); | ||
801 | diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c | ||
802 | index XXXXXXX..XXXXXXX 100644 | ||
803 | --- a/target/m68k/op_helper.c | ||
804 | +++ b/target/m68k/op_helper.c | ||
805 | @@ -XXX,XX +XXX,XX @@ static void do_cas2l(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2, | ||
806 | uintptr_t ra = GETPC(); | ||
807 | #if defined(CONFIG_ATOMIC64) | ||
808 | int mmu_idx = cpu_mmu_index(env, 0); | ||
809 | - MemOpIdx oi = make_memop_idx(MO_BEQ, mmu_idx); | ||
810 | + MemOpIdx oi = make_memop_idx(MO_BEUQ, mmu_idx); | ||
811 | #endif | ||
812 | |||
813 | if (parallel) { | ||
814 | diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c | ||
815 | index XXXXXXX..XXXXXXX 100644 | ||
816 | --- a/target/mips/tcg/translate.c | ||
817 | +++ b/target/mips/tcg/translate.c | ||
818 | @@ -XXX,XX +XXX,XX @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
819 | gen_store_gpr(t0, rt); | ||
820 | break; | ||
821 | case OPC_LD: | ||
822 | - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | | ||
823 | + tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ | | ||
824 | ctx->default_tcg_memop_mask); | ||
825 | gen_store_gpr(t0, rt); | ||
826 | break; | ||
827 | @@ -XXX,XX +XXX,XX @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
828 | } | ||
829 | tcg_gen_shli_tl(t1, t1, 3); | ||
830 | tcg_gen_andi_tl(t0, t0, ~7); | ||
831 | - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); | ||
832 | + tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); | ||
833 | tcg_gen_shl_tl(t0, t0, t1); | ||
834 | t2 = tcg_const_tl(-1); | ||
835 | tcg_gen_shl_tl(t2, t2, t1); | ||
836 | @@ -XXX,XX +XXX,XX @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
837 | } | ||
838 | tcg_gen_shli_tl(t1, t1, 3); | ||
839 | tcg_gen_andi_tl(t0, t0, ~7); | ||
840 | - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); | ||
841 | + tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); | ||
842 | tcg_gen_shr_tl(t0, t0, t1); | ||
843 | tcg_gen_xori_tl(t1, t1, 63); | ||
844 | t2 = tcg_const_tl(0xfffffffffffffffeull); | ||
845 | @@ -XXX,XX +XXX,XX @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
846 | t1 = tcg_const_tl(pc_relative_pc(ctx)); | ||
847 | gen_op_addr_add(ctx, t0, t0, t1); | ||
848 | tcg_temp_free(t1); | ||
849 | - tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); | ||
850 | + tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); | ||
851 | gen_store_gpr(t0, rt); | ||
852 | break; | ||
853 | #endif | ||
854 | @@ -XXX,XX +XXX,XX @@ static void gen_st(DisasContext *ctx, uint32_t opc, int rt, | ||
855 | switch (opc) { | ||
856 | #if defined(TARGET_MIPS64) | ||
857 | case OPC_SD: | ||
858 | - tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | | ||
859 | + tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ | | ||
860 | ctx->default_tcg_memop_mask); | ||
861 | break; | ||
862 | case OPC_SDL: | ||
863 | @@ -XXX,XX +XXX,XX @@ static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, | ||
864 | case OPC_LDC1: | ||
865 | { | ||
866 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
867 | - tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | | ||
868 | + tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | | ||
869 | ctx->default_tcg_memop_mask); | ||
870 | gen_store_fpr64(ctx, fp0, ft); | ||
871 | tcg_temp_free_i64(fp0); | ||
872 | @@ -XXX,XX +XXX,XX @@ static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, | ||
873 | { | ||
874 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
875 | gen_load_fpr64(ctx, fp0, ft); | ||
876 | - tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | | ||
877 | + tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | | ||
878 | ctx->default_tcg_memop_mask); | ||
879 | tcg_temp_free_i64(fp0); | ||
880 | } | ||
881 | @@ -XXX,XX +XXX,XX @@ static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, | ||
882 | check_mips_64(ctx); | ||
883 | offset = sextract32(ctx->opcode << 3, 0, 21); | ||
884 | addr = addr_add(ctx, (pc & ~0x7), offset); | ||
885 | - gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ); | ||
886 | + gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ); | ||
887 | break; | ||
888 | #endif | ||
889 | default: | ||
890 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
891 | case OPC_GSLQ: | ||
892 | t1 = tcg_temp_new(); | ||
893 | gen_base_offset_addr(ctx, t0, rs, lsq_offset); | ||
894 | - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
895 | + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
896 | ctx->default_tcg_memop_mask); | ||
897 | gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); | ||
898 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | | ||
899 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | | ||
900 | ctx->default_tcg_memop_mask); | ||
901 | gen_store_gpr(t1, rt); | ||
902 | gen_store_gpr(t0, lsq_rt1); | ||
903 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
904 | check_cp1_enabled(ctx); | ||
905 | t1 = tcg_temp_new(); | ||
906 | gen_base_offset_addr(ctx, t0, rs, lsq_offset); | ||
907 | - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
908 | + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
909 | ctx->default_tcg_memop_mask); | ||
910 | gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); | ||
911 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | | ||
912 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | | ||
913 | ctx->default_tcg_memop_mask); | ||
914 | gen_store_fpr64(ctx, t1, rt); | ||
915 | gen_store_fpr64(ctx, t0, lsq_rt1); | ||
916 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
917 | t1 = tcg_temp_new(); | ||
918 | gen_base_offset_addr(ctx, t0, rs, lsq_offset); | ||
919 | gen_load_gpr(t1, rt); | ||
920 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
921 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
922 | ctx->default_tcg_memop_mask); | ||
923 | gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); | ||
924 | gen_load_gpr(t1, lsq_rt1); | ||
925 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
926 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
927 | ctx->default_tcg_memop_mask); | ||
928 | tcg_temp_free(t1); | ||
929 | break; | ||
930 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
931 | t1 = tcg_temp_new(); | ||
932 | gen_base_offset_addr(ctx, t0, rs, lsq_offset); | ||
933 | gen_load_fpr64(ctx, t1, rt); | ||
934 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
935 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
936 | ctx->default_tcg_memop_mask); | ||
937 | gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); | ||
938 | gen_load_fpr64(ctx, t1, lsq_rt1); | ||
939 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
940 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
941 | ctx->default_tcg_memop_mask); | ||
942 | tcg_temp_free(t1); | ||
943 | break; | ||
944 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
945 | } | ||
946 | tcg_gen_shli_tl(t1, t1, 3); | ||
947 | tcg_gen_andi_tl(t0, t0, ~7); | ||
948 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); | ||
949 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); | ||
950 | tcg_gen_shl_tl(t0, t0, t1); | ||
951 | t2 = tcg_const_tl(-1); | ||
952 | tcg_gen_shl_tl(t2, t2, t1); | ||
953 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
954 | } | ||
955 | tcg_gen_shli_tl(t1, t1, 3); | ||
956 | tcg_gen_andi_tl(t0, t0, ~7); | ||
957 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); | ||
958 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); | ||
959 | tcg_gen_shr_tl(t0, t0, t1); | ||
960 | tcg_gen_xori_tl(t1, t1, 63); | ||
961 | t2 = tcg_const_tl(0xfffffffffffffffeull); | ||
962 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
963 | if (rd) { | ||
964 | gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); | ||
965 | } | ||
966 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | | ||
967 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | | ||
968 | ctx->default_tcg_memop_mask); | ||
969 | gen_store_gpr(t0, rt); | ||
970 | break; | ||
971 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
972 | if (rd) { | ||
973 | gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); | ||
974 | } | ||
975 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | | ||
976 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | | ||
977 | ctx->default_tcg_memop_mask); | ||
978 | gen_store_fpr64(ctx, t0, rt); | ||
979 | break; | ||
980 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
981 | case OPC_GSSDX: | ||
982 | t1 = tcg_temp_new(); | ||
983 | gen_load_gpr(t1, rt); | ||
984 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | | ||
985 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
986 | ctx->default_tcg_memop_mask); | ||
987 | tcg_temp_free(t1); | ||
988 | break; | ||
989 | @@ -XXX,XX +XXX,XX @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
990 | case OPC_GSSDXC1: | ||
991 | t1 = tcg_temp_new(); | ||
992 | gen_load_fpr64(ctx, t1, rt); | ||
993 | - tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | | ||
994 | + tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ | | ||
995 | ctx->default_tcg_memop_mask); | ||
996 | tcg_temp_free(t1); | ||
997 | break; | ||
998 | @@ -XXX,XX +XXX,XX @@ static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, | ||
999 | check_cp1_registers(ctx, fd); | ||
1000 | { | ||
1001 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
1002 | - tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); | ||
1003 | + tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); | ||
1004 | gen_store_fpr64(ctx, fp0, fd); | ||
1005 | tcg_temp_free_i64(fp0); | ||
1006 | } | ||
1007 | @@ -XXX,XX +XXX,XX @@ static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, | ||
1008 | { | ||
1009 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
1010 | |||
1011 | - tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); | ||
1012 | + tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); | ||
1013 | gen_store_fpr64(ctx, fp0, fd); | ||
1014 | tcg_temp_free_i64(fp0); | ||
1015 | } | ||
1016 | @@ -XXX,XX +XXX,XX @@ static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, | ||
1017 | { | ||
1018 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
1019 | gen_load_fpr64(ctx, fp0, fs); | ||
1020 | - tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); | ||
1021 | + tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); | ||
1022 | tcg_temp_free_i64(fp0); | ||
1023 | } | ||
1024 | break; | ||
1025 | @@ -XXX,XX +XXX,XX @@ static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, | ||
1026 | { | ||
1027 | TCGv_i64 fp0 = tcg_temp_new_i64(); | ||
1028 | gen_load_fpr64(ctx, fp0, fs); | ||
1029 | - tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); | ||
1030 | + tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); | ||
1031 | tcg_temp_free_i64(fp0); | ||
1032 | } | ||
1033 | break; | ||
1034 | @@ -XXX,XX +XXX,XX @@ static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, | ||
1035 | break; | ||
1036 | #if defined(TARGET_MIPS64) | ||
1037 | case OPC_LDX: | ||
1038 | - tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); | ||
1039 | + tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); | ||
1040 | gen_store_gpr(t0, rd); | ||
1041 | break; | ||
1042 | #endif | ||
1043 | @@ -XXX,XX +XXX,XX @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) | ||
1044 | #endif | ||
1045 | #if defined(TARGET_MIPS64) | ||
1046 | case R6_OPC_SCD: | ||
1047 | - gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); | ||
1048 | + gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); | ||
1049 | break; | ||
1050 | case R6_OPC_LLD: | ||
1051 | gen_ld(ctx, op1, rt, rs, imm); | ||
1052 | @@ -XXX,XX +XXX,XX @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) | ||
1053 | check_insn_opc_user_only(ctx, INSN_R5900); | ||
1054 | } | ||
1055 | check_mips_64(ctx); | ||
1056 | - gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); | ||
1057 | + gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); | ||
1058 | break; | ||
1059 | case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ | ||
1060 | if (ctx->insn_flags & ISA_MIPS_R6) { | ||
1061 | diff --git a/target/mips/tcg/tx79_translate.c b/target/mips/tcg/tx79_translate.c | ||
1062 | index XXXXXXX..XXXXXXX 100644 | ||
1063 | --- a/target/mips/tcg/tx79_translate.c | ||
1064 | +++ b/target/mips/tcg/tx79_translate.c | ||
1065 | @@ -XXX,XX +XXX,XX @@ static bool trans_LQ(DisasContext *ctx, arg_i *a) | ||
1066 | tcg_gen_andi_tl(addr, addr, ~0xf); | ||
1067 | |||
1068 | /* Lower half */ | ||
1069 | - tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEQ); | ||
1070 | + tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEUQ); | ||
1071 | gen_store_gpr(t0, a->rt); | ||
1072 | |||
1073 | /* Upper half */ | ||
1074 | tcg_gen_addi_i64(addr, addr, 8); | ||
1075 | - tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEQ); | ||
1076 | + tcg_gen_qemu_ld_i64(t0, addr, ctx->mem_idx, MO_TEUQ); | ||
1077 | gen_store_gpr_hi(t0, a->rt); | ||
1078 | |||
1079 | tcg_temp_free(t0); | ||
1080 | @@ -XXX,XX +XXX,XX @@ static bool trans_SQ(DisasContext *ctx, arg_i *a) | ||
1081 | |||
1082 | /* Lower half */ | ||
1083 | gen_load_gpr(t0, a->rt); | ||
1084 | - tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEQ); | ||
1085 | + tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEUQ); | ||
1086 | |||
1087 | /* Upper half */ | ||
1088 | tcg_gen_addi_i64(addr, addr, 8); | ||
1089 | gen_load_gpr_hi(t0, a->rt); | ||
1090 | - tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEQ); | ||
1091 | + tcg_gen_qemu_st_i64(t0, addr, ctx->mem_idx, MO_TEUQ); | ||
1092 | |||
1093 | tcg_temp_free(addr); | ||
1094 | tcg_temp_free(t0); | ||
1095 | diff --git a/target/ppc/translate.c b/target/ppc/translate.c | ||
1096 | index XXXXXXX..XXXXXXX 100644 | ||
1097 | --- a/target/ppc/translate.c | ||
1098 | +++ b/target/ppc/translate.c | ||
1099 | @@ -XXX,XX +XXX,XX @@ GEN_QEMU_LOAD_64(ld8u, DEF_MEMOP(MO_UB)) | ||
1100 | GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW)) | ||
1101 | GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL)) | ||
1102 | GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL)) | ||
1103 | -GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_Q)) | ||
1104 | +GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_UQ)) | ||
1105 | |||
1106 | #if defined(TARGET_PPC64) | ||
1107 | -GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_Q)) | ||
1108 | +GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_UQ)) | ||
1109 | #endif | ||
1110 | |||
1111 | #define GEN_QEMU_STORE_TL(stop, op) \ | ||
1112 | @@ -XXX,XX +XXX,XX @@ static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx, \ | ||
1113 | GEN_QEMU_STORE_64(st8, DEF_MEMOP(MO_UB)) | ||
1114 | GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW)) | ||
1115 | GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL)) | ||
1116 | -GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_Q)) | ||
1117 | +GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_UQ)) | ||
1118 | |||
1119 | #if defined(TARGET_PPC64) | ||
1120 | -GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_Q)) | ||
1121 | +GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_UQ)) | ||
1122 | #endif | ||
1123 | |||
1124 | #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \ | ||
1125 | @@ -XXX,XX +XXX,XX @@ GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) | ||
1126 | GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) | ||
1127 | GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) | ||
1128 | #if defined(TARGET_PPC64) | ||
1129 | -GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00) | ||
1130 | +GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00) | ||
1131 | #endif | ||
1132 | |||
1133 | #if defined(TARGET_PPC64) | ||
1134 | @@ -XXX,XX +XXX,XX @@ GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) | ||
1135 | GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) | ||
1136 | GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) | ||
1137 | #if defined(TARGET_PPC64) | ||
1138 | -GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1d, 0x04) | ||
1139 | +GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1d, 0x04) | ||
1140 | #endif | ||
1141 | |||
1142 | #if defined(TARGET_PPC64) | ||
1143 | @@ -XXX,XX +XXX,XX @@ static void gen_lwat(DisasContext *ctx) | ||
1144 | #ifdef TARGET_PPC64 | ||
1145 | static void gen_ldat(DisasContext *ctx) | ||
1146 | { | ||
1147 | - gen_ld_atomic(ctx, DEF_MEMOP(MO_Q)); | ||
1148 | + gen_ld_atomic(ctx, DEF_MEMOP(MO_UQ)); | ||
1149 | } | ||
1150 | #endif | ||
1151 | |||
1152 | @@ -XXX,XX +XXX,XX @@ static void gen_stwat(DisasContext *ctx) | ||
1153 | #ifdef TARGET_PPC64 | ||
1154 | static void gen_stdat(DisasContext *ctx) | ||
1155 | { | ||
1156 | - gen_st_atomic(ctx, DEF_MEMOP(MO_Q)); | ||
1157 | + gen_st_atomic(ctx, DEF_MEMOP(MO_UQ)); | ||
1158 | } | ||
1159 | #endif | ||
1160 | |||
1161 | @@ -XXX,XX +XXX,XX @@ STCX(stwcx_, DEF_MEMOP(MO_UL)) | ||
1162 | |||
1163 | #if defined(TARGET_PPC64) | ||
1164 | /* ldarx */ | ||
1165 | -LARX(ldarx, DEF_MEMOP(MO_Q)) | ||
1166 | +LARX(ldarx, DEF_MEMOP(MO_UQ)) | ||
1167 | /* stdcx. */ | ||
1168 | -STCX(stdcx_, DEF_MEMOP(MO_Q)) | ||
1169 | +STCX(stdcx_, DEF_MEMOP(MO_UQ)) | ||
1170 | |||
1171 | /* lqarx */ | ||
1172 | static void gen_lqarx(DisasContext *ctx) | ||
1173 | @@ -XXX,XX +XXX,XX @@ static void gen_lqarx(DisasContext *ctx) | ||
1174 | return; | ||
1175 | } | ||
1176 | } else if (ctx->le_mode) { | ||
1177 | - tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16); | ||
1178 | + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEUQ | MO_ALIGN_16); | ||
1179 | tcg_gen_mov_tl(cpu_reserve, EA); | ||
1180 | gen_addr_add(ctx, EA, EA, 8); | ||
1181 | - tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ); | ||
1182 | + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEUQ); | ||
1183 | } else { | ||
1184 | - tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ | MO_ALIGN_16); | ||
1185 | + tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEUQ | MO_ALIGN_16); | ||
1186 | tcg_gen_mov_tl(cpu_reserve, EA); | ||
1187 | gen_addr_add(ctx, EA, EA, 8); | ||
1188 | - tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ); | ||
1189 | + tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEUQ); | ||
1190 | } | ||
1191 | tcg_temp_free(EA); | ||
1192 | |||
1193 | @@ -XXX,XX +XXX,XX @@ GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) | ||
1194 | GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) | ||
1195 | GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) | ||
1196 | #if defined(TARGET_PPC64) | ||
1197 | -GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00) | ||
1198 | +GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00) | ||
1199 | #endif | ||
1200 | |||
1201 | #undef GEN_STX_E | ||
1202 | @@ -XXX,XX +XXX,XX @@ GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) | ||
1203 | GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) | ||
1204 | GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) | ||
1205 | #if defined(TARGET_PPC64) | ||
1206 | -GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1D, 0x04) | ||
1207 | +GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1D, 0x04) | ||
1208 | #endif | ||
1209 | |||
1210 | #undef GEN_CRLOGIC | ||
1211 | diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c | ||
1212 | index XXXXXXX..XXXXXXX 100644 | ||
1213 | --- a/target/s390x/tcg/mem_helper.c | ||
1214 | +++ b/target/s390x/tcg/mem_helper.c | ||
1215 | @@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1, | ||
1216 | |||
1217 | if (parallel) { | ||
1218 | #ifdef CONFIG_ATOMIC64 | ||
1219 | - MemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN, mem_idx); | ||
1220 | + MemOpIdx oi = make_memop_idx(MO_TEUQ | MO_ALIGN, mem_idx); | ||
1221 | ov = cpu_atomic_cmpxchgq_be_mmu(env, a1, cv, nv, oi, ra); | ||
1222 | #else | ||
1223 | /* Note that we asserted !parallel above. */ | ||
1224 | @@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1, | ||
1225 | cpu_stq_data_ra(env, a2 + 0, svh, ra); | ||
1226 | cpu_stq_data_ra(env, a2 + 8, svl, ra); | ||
1227 | } else if (HAVE_ATOMIC128) { | ||
1228 | - MemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx); | ||
1229 | + MemOpIdx oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx); | ||
1230 | Int128 sv = int128_make128(svl, svh); | ||
1231 | cpu_atomic_sto_be_mmu(env, a2, sv, oi, ra); | ||
1232 | } else { | ||
1233 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr) | ||
1234 | assert(HAVE_ATOMIC128); | ||
1235 | |||
1236 | mem_idx = cpu_mmu_index(env, false); | ||
1237 | - oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx); | ||
1238 | + oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx); | ||
1239 | v = cpu_atomic_ldo_be_mmu(env, addr, oi, ra); | ||
1240 | hi = int128_gethi(v); | ||
1241 | lo = int128_getlo(v); | ||
1242 | @@ -XXX,XX +XXX,XX @@ void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr, | ||
1243 | assert(HAVE_ATOMIC128); | ||
1244 | |||
1245 | mem_idx = cpu_mmu_index(env, false); | ||
1246 | - oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx); | ||
1247 | + oi = make_memop_idx(MO_TEUQ | MO_ALIGN_16, mem_idx); | ||
1248 | v = int128_make128(low, high); | ||
1249 | cpu_atomic_sto_be_mmu(env, addr, v, oi, ra); | ||
1250 | } | ||
1251 | diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c | ||
1252 | index XXXXXXX..XXXXXXX 100644 | ||
1253 | --- a/target/s390x/tcg/translate.c | ||
1254 | +++ b/target/s390x/tcg/translate.c | ||
1255 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o) | ||
1256 | t1 = tcg_temp_new_i64(); | ||
1257 | t2 = tcg_temp_new_i64(); | ||
1258 | tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), | ||
1259 | - MO_TEQ | MO_ALIGN_8); | ||
1260 | + MO_TEUQ | MO_ALIGN_8); | ||
1261 | tcg_gen_addi_i64(o->in2, o->in2, 8); | ||
1262 | tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s)); | ||
1263 | gen_helper_load_psw(cpu_env, t1, t2); | ||
1264 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_stcke(DisasContext *s, DisasOps *o) | ||
1265 | #ifndef CONFIG_USER_ONLY | ||
1266 | static DisasJumpType op_sck(DisasContext *s, DisasOps *o) | ||
1267 | { | ||
1268 | - tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN); | ||
1269 | + tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEUQ | MO_ALIGN); | ||
1270 | gen_helper_sck(cc_op, cpu_env, o->in1); | ||
1271 | set_cc_static(s); | ||
1272 | return DISAS_NEXT; | ||
1273 | @@ -XXX,XX +XXX,XX @@ static void wout_m1_64(DisasContext *s, DisasOps *o) | ||
1274 | #ifndef CONFIG_USER_ONLY | ||
1275 | static void wout_m1_64a(DisasContext *s, DisasOps *o) | ||
1276 | { | ||
1277 | - tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN); | ||
1278 | + tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUQ | MO_ALIGN); | ||
1279 | } | ||
1280 | #define SPEC_wout_m1_64a 0 | ||
1281 | #endif | ||
1282 | @@ -XXX,XX +XXX,XX @@ static void in2_m2_64w(DisasContext *s, DisasOps *o) | ||
1283 | static void in2_m2_64a(DisasContext *s, DisasOps *o) | ||
1284 | { | ||
1285 | in2_a2(s, o); | ||
1286 | - tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEQ | MO_ALIGN); | ||
1287 | + tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN); | ||
1288 | } | ||
1289 | #define SPEC_in2_m2_64a 0 | ||
1290 | #endif | ||
1291 | diff --git a/target/sh4/translate.c b/target/sh4/translate.c | ||
1292 | index XXXXXXX..XXXXXXX 100644 | ||
1293 | --- a/target/sh4/translate.c | ||
1294 | +++ b/target/sh4/translate.c | ||
1295 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1296 | if (ctx->tbflags & FPSCR_SZ) { | ||
1297 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1298 | gen_load_fpr64(ctx, fp, XHACK(B7_4)); | ||
1299 | - tcg_gen_qemu_st_i64(fp, REG(B11_8), ctx->memidx, MO_TEQ); | ||
1300 | + tcg_gen_qemu_st_i64(fp, REG(B11_8), ctx->memidx, MO_TEUQ); | ||
1301 | tcg_temp_free_i64(fp); | ||
1302 | } else { | ||
1303 | tcg_gen_qemu_st_i32(FREG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL); | ||
1304 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1305 | CHECK_FPU_ENABLED | ||
1306 | if (ctx->tbflags & FPSCR_SZ) { | ||
1307 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1308 | - tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ); | ||
1309 | + tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEUQ); | ||
1310 | gen_store_fpr64(ctx, fp, XHACK(B11_8)); | ||
1311 | tcg_temp_free_i64(fp); | ||
1312 | } else { | ||
1313 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1314 | CHECK_FPU_ENABLED | ||
1315 | if (ctx->tbflags & FPSCR_SZ) { | ||
1316 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1317 | - tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ); | ||
1318 | + tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEUQ); | ||
1319 | gen_store_fpr64(ctx, fp, XHACK(B11_8)); | ||
1320 | tcg_temp_free_i64(fp); | ||
1321 | tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8); | ||
1322 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1323 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1324 | gen_load_fpr64(ctx, fp, XHACK(B7_4)); | ||
1325 | tcg_gen_subi_i32(addr, REG(B11_8), 8); | ||
1326 | - tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ); | ||
1327 | + tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEUQ); | ||
1328 | tcg_temp_free_i64(fp); | ||
1329 | } else { | ||
1330 | tcg_gen_subi_i32(addr, REG(B11_8), 4); | ||
1331 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1332 | tcg_gen_add_i32(addr, REG(B7_4), REG(0)); | ||
1333 | if (ctx->tbflags & FPSCR_SZ) { | ||
1334 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1335 | - tcg_gen_qemu_ld_i64(fp, addr, ctx->memidx, MO_TEQ); | ||
1336 | + tcg_gen_qemu_ld_i64(fp, addr, ctx->memidx, MO_TEUQ); | ||
1337 | gen_store_fpr64(ctx, fp, XHACK(B11_8)); | ||
1338 | tcg_temp_free_i64(fp); | ||
1339 | } else { | ||
1340 | @@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx) | ||
1341 | if (ctx->tbflags & FPSCR_SZ) { | ||
1342 | TCGv_i64 fp = tcg_temp_new_i64(); | ||
1343 | gen_load_fpr64(ctx, fp, XHACK(B7_4)); | ||
1344 | - tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ); | ||
1345 | + tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEUQ); | ||
1346 | tcg_temp_free_i64(fp); | ||
1347 | } else { | ||
1348 | tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL); | ||
1349 | diff --git a/target/sparc/translate.c b/target/sparc/translate.c | ||
1350 | index XXXXXXX..XXXXXXX 100644 | ||
1351 | --- a/target/sparc/translate.c | ||
1352 | +++ b/target/sparc/translate.c | ||
1353 | @@ -XXX,XX +XXX,XX @@ static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn) | ||
1354 | static void gen_ldf_asi(DisasContext *dc, TCGv addr, | ||
1355 | int insn, int size, int rd) | ||
1356 | { | ||
1357 | - DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ)); | ||
1358 | + DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ)); | ||
1359 | TCGv_i32 d32; | ||
1360 | TCGv_i64 d64; | ||
1361 | |||
1362 | @@ -XXX,XX +XXX,XX @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr, | ||
1363 | static void gen_stf_asi(DisasContext *dc, TCGv addr, | ||
1364 | int insn, int size, int rd) | ||
1365 | { | ||
1366 | - DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ)); | ||
1367 | + DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ)); | ||
1368 | TCGv_i32 d32; | ||
1369 | |||
1370 | switch (da.type) { | ||
1371 | @@ -XXX,XX +XXX,XX @@ static void gen_stf_asi(DisasContext *dc, TCGv addr, | ||
1372 | |||
1373 | static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd) | ||
1374 | { | ||
1375 | - DisasASI da = get_asi(dc, insn, MO_TEQ); | ||
1376 | + DisasASI da = get_asi(dc, insn, MO_TEUQ); | ||
1377 | TCGv_i64 hi = gen_dest_gpr(dc, rd); | ||
1378 | TCGv_i64 lo = gen_dest_gpr(dc, rd + 1); | ||
1379 | |||
1380 | @@ -XXX,XX +XXX,XX @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd) | ||
1381 | static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, | ||
1382 | int insn, int rd) | ||
1383 | { | ||
1384 | - DisasASI da = get_asi(dc, insn, MO_TEQ); | ||
1385 | + DisasASI da = get_asi(dc, insn, MO_TEUQ); | ||
1386 | TCGv lo = gen_load_gpr(dc, rd + 1); | ||
1387 | |||
1388 | switch (da.type) { | ||
1389 | @@ -XXX,XX +XXX,XX @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, | ||
1390 | static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, | ||
1391 | int insn, int rd) | ||
1392 | { | ||
1393 | - DisasASI da = get_asi(dc, insn, MO_TEQ); | ||
1394 | + DisasASI da = get_asi(dc, insn, MO_TEUQ); | ||
1395 | TCGv oldv; | ||
1396 | |||
1397 | switch (da.type) { | ||
1398 | @@ -XXX,XX +XXX,XX @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd) | ||
1399 | TCGv lo = gen_dest_gpr(dc, rd | 1); | ||
1400 | TCGv hi = gen_dest_gpr(dc, rd); | ||
1401 | TCGv_i64 t64 = tcg_temp_new_i64(); | ||
1402 | - DisasASI da = get_asi(dc, insn, MO_TEQ); | ||
1403 | + DisasASI da = get_asi(dc, insn, MO_TEUQ); | ||
1404 | |||
1405 | switch (da.type) { | ||
1406 | case GET_ASI_EXCP: | ||
1407 | @@ -XXX,XX +XXX,XX @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd) | ||
1408 | default: | ||
1409 | { | ||
1410 | TCGv_i32 r_asi = tcg_const_i32(da.asi); | ||
1411 | - TCGv_i32 r_mop = tcg_const_i32(MO_Q); | ||
1412 | + TCGv_i32 r_mop = tcg_const_i32(MO_UQ); | ||
1413 | |||
1414 | save_state(dc); | ||
1415 | gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop); | ||
1416 | @@ -XXX,XX +XXX,XX @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd) | ||
1417 | static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, | ||
1418 | int insn, int rd) | ||
1419 | { | ||
1420 | - DisasASI da = get_asi(dc, insn, MO_TEQ); | ||
1421 | + DisasASI da = get_asi(dc, insn, MO_TEUQ); | ||
1422 | TCGv lo = gen_load_gpr(dc, rd + 1); | ||
1423 | TCGv_i64 t64 = tcg_temp_new_i64(); | ||
1424 | |||
1425 | @@ -XXX,XX +XXX,XX @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, | ||
1426 | default: | ||
1427 | { | ||
1428 | TCGv_i32 r_asi = tcg_const_i32(da.asi); | ||
1429 | - TCGv_i32 r_mop = tcg_const_i32(MO_Q); | ||
1430 | + TCGv_i32 r_mop = tcg_const_i32(MO_UQ); | ||
1431 | |||
1432 | save_state(dc); | ||
1433 | gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop); | ||
1434 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1435 | gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL); | ||
1436 | break; | ||
1437 | case 0x1b: /* V9 ldxa */ | ||
1438 | - gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ); | ||
1439 | + gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ); | ||
1440 | break; | ||
1441 | case 0x2d: /* V9 prefetch, no effect */ | ||
1442 | goto skip_move; | ||
1443 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1444 | if (rd == 1) { | ||
1445 | TCGv_i64 t64 = tcg_temp_new_i64(); | ||
1446 | tcg_gen_qemu_ld_i64(t64, cpu_addr, | ||
1447 | - dc->mem_idx, MO_TEQ); | ||
1448 | + dc->mem_idx, MO_TEUQ); | ||
1449 | gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64); | ||
1450 | tcg_temp_free_i64(t64); | ||
1451 | break; | ||
1452 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1453 | gen_address_mask(dc, cpu_addr); | ||
1454 | cpu_src1_64 = tcg_temp_new_i64(); | ||
1455 | tcg_gen_qemu_ld_i64(cpu_src1_64, cpu_addr, dc->mem_idx, | ||
1456 | - MO_TEQ | MO_ALIGN_4); | ||
1457 | + MO_TEUQ | MO_ALIGN_4); | ||
1458 | tcg_gen_addi_tl(cpu_addr, cpu_addr, 8); | ||
1459 | cpu_src2_64 = tcg_temp_new_i64(); | ||
1460 | tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx, | ||
1461 | - MO_TEQ | MO_ALIGN_4); | ||
1462 | + MO_TEUQ | MO_ALIGN_4); | ||
1463 | gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64); | ||
1464 | tcg_temp_free_i64(cpu_src1_64); | ||
1465 | tcg_temp_free_i64(cpu_src2_64); | ||
1466 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1467 | gen_address_mask(dc, cpu_addr); | ||
1468 | cpu_dst_64 = gen_dest_fpr_D(dc, rd); | ||
1469 | tcg_gen_qemu_ld_i64(cpu_dst_64, cpu_addr, dc->mem_idx, | ||
1470 | - MO_TEQ | MO_ALIGN_4); | ||
1471 | + MO_TEUQ | MO_ALIGN_4); | ||
1472 | gen_store_fpr_D(dc, rd, cpu_dst_64); | ||
1473 | break; | ||
1474 | default: | ||
1475 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1476 | tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx); | ||
1477 | break; | ||
1478 | case 0x1e: /* V9 stxa */ | ||
1479 | - gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ); | ||
1480 | + gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ); | ||
1481 | break; | ||
1482 | #endif | ||
1483 | default: | ||
1484 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1485 | before performing the first write. */ | ||
1486 | cpu_src1_64 = gen_load_fpr_Q0(dc, rd); | ||
1487 | tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, | ||
1488 | - dc->mem_idx, MO_TEQ | MO_ALIGN_16); | ||
1489 | + dc->mem_idx, MO_TEUQ | MO_ALIGN_16); | ||
1490 | tcg_gen_addi_tl(cpu_addr, cpu_addr, 8); | ||
1491 | cpu_src2_64 = gen_load_fpr_Q1(dc, rd); | ||
1492 | tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, | ||
1493 | - dc->mem_idx, MO_TEQ); | ||
1494 | + dc->mem_idx, MO_TEUQ); | ||
1495 | break; | ||
1496 | #else /* !TARGET_SPARC64 */ | ||
1497 | /* stdfq, store floating point queue */ | ||
1498 | @@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) | ||
1499 | gen_address_mask(dc, cpu_addr); | ||
1500 | cpu_src1_64 = gen_load_fpr_D(dc, rd); | ||
1501 | tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, dc->mem_idx, | ||
1502 | - MO_TEQ | MO_ALIGN_4); | ||
1503 | + MO_TEUQ | MO_ALIGN_4); | ||
1504 | break; | ||
1505 | default: | ||
1506 | goto illegal_insn; | ||
1507 | diff --git a/target/tricore/translate.c b/target/tricore/translate.c | ||
1508 | index XXXXXXX..XXXXXXX 100644 | ||
1509 | --- a/target/tricore/translate.c | ||
1510 | +++ b/target/tricore/translate.c | ||
1511 | @@ -XXX,XX +XXX,XX @@ static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx) | ||
1512 | TCGv_i64 temp = tcg_temp_new_i64(); | ||
1513 | |||
1514 | tcg_gen_concat_i32_i64(temp, rl, rh); | ||
1515 | - tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ); | ||
1516 | + tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEUQ); | ||
1517 | |||
1518 | tcg_temp_free_i64(temp); | ||
1519 | } | ||
1520 | @@ -XXX,XX +XXX,XX @@ static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx) | ||
1521 | { | ||
1522 | TCGv_i64 temp = tcg_temp_new_i64(); | ||
1523 | |||
1524 | - tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ); | ||
1525 | + tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEUQ); | ||
1526 | /* write back to two 32 bit regs */ | ||
1527 | tcg_gen_extr_i64_i32(rl, rh, temp); | ||
1528 | |||
1529 | diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c | ||
1530 | index XXXXXXX..XXXXXXX 100644 | ||
1531 | --- a/target/xtensa/translate.c | ||
1532 | +++ b/target/xtensa/translate.c | ||
1533 | @@ -XXX,XX +XXX,XX @@ static void translate_ldsti_d(DisasContext *dc, const OpcodeArg arg[], | ||
1534 | } else { | ||
1535 | addr = arg[1].in; | ||
1536 | } | ||
1537 | - mop = gen_load_store_alignment(dc, MO_TEQ, addr); | ||
1538 | + mop = gen_load_store_alignment(dc, MO_TEUQ, addr); | ||
1539 | if (par[0]) { | ||
1540 | tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop); | ||
1541 | } else { | ||
1542 | @@ -XXX,XX +XXX,XX @@ static void translate_ldstx_d(DisasContext *dc, const OpcodeArg arg[], | ||
1543 | } else { | ||
1544 | addr = arg[1].in; | ||
1545 | } | ||
1546 | - mop = gen_load_store_alignment(dc, MO_TEQ, addr); | ||
1547 | + mop = gen_load_store_alignment(dc, MO_TEUQ, addr); | ||
1548 | if (par[0]) { | ||
1549 | tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop); | ||
1550 | } else { | ||
1551 | diff --git a/tcg/tcg.c b/tcg/tcg.c | ||
1552 | index XXXXXXX..XXXXXXX 100644 | ||
1553 | --- a/tcg/tcg.c | ||
1554 | +++ b/tcg/tcg.c | ||
1555 | @@ -XXX,XX +XXX,XX @@ static const char * const ldst_name[] = | ||
1556 | [MO_LESW] = "lesw", | ||
1557 | [MO_LEUL] = "leul", | ||
1558 | [MO_LESL] = "lesl", | ||
1559 | - [MO_LEQ] = "leq", | ||
1560 | + [MO_LEUQ] = "leq", | ||
1561 | [MO_BEUW] = "beuw", | ||
1562 | [MO_BESW] = "besw", | ||
1563 | [MO_BEUL] = "beul", | ||
1564 | [MO_BESL] = "besl", | ||
1565 | - [MO_BEQ] = "beq", | ||
1566 | + [MO_BEUQ] = "beq", | ||
1567 | }; | ||
1568 | |||
1569 | static const char * const alignment_name[(MO_AMASK >> MO_ASHIFT) + 1] = { | ||
1570 | diff --git a/tcg/tci.c b/tcg/tci.c | ||
1571 | index XXXXXXX..XXXXXXX 100644 | ||
1572 | --- a/tcg/tci.c | ||
1573 | +++ b/tcg/tci.c | ||
1574 | @@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr, | ||
1575 | return helper_le_ldul_mmu(env, taddr, oi, ra); | ||
1576 | case MO_LESL: | ||
1577 | return helper_le_ldsl_mmu(env, taddr, oi, ra); | ||
1578 | - case MO_LEQ: | ||
1579 | + case MO_LEUQ: | ||
1580 | return helper_le_ldq_mmu(env, taddr, oi, ra); | ||
1581 | case MO_BEUW: | ||
1582 | return helper_be_lduw_mmu(env, taddr, oi, ra); | ||
1583 | @@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr, | ||
1584 | return helper_be_ldul_mmu(env, taddr, oi, ra); | ||
1585 | case MO_BESL: | ||
1586 | return helper_be_ldsl_mmu(env, taddr, oi, ra); | ||
1587 | - case MO_BEQ: | ||
1588 | + case MO_BEUQ: | ||
1589 | return helper_be_ldq_mmu(env, taddr, oi, ra); | ||
1590 | default: | ||
1591 | g_assert_not_reached(); | ||
1592 | @@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr, | ||
1593 | case MO_LESL: | ||
1594 | ret = (int32_t)ldl_le_p(haddr); | ||
1595 | break; | ||
1596 | - case MO_LEQ: | ||
1597 | + case MO_LEUQ: | ||
1598 | ret = ldq_le_p(haddr); | ||
1599 | break; | ||
1600 | case MO_BEUW: | ||
1601 | @@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr, | ||
1602 | case MO_BESL: | ||
1603 | ret = (int32_t)ldl_be_p(haddr); | ||
1604 | break; | ||
1605 | - case MO_BEQ: | ||
1606 | + case MO_BEUQ: | ||
1607 | ret = ldq_be_p(haddr); | ||
1608 | break; | ||
1609 | default: | ||
1610 | @@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val, | ||
1611 | case MO_LEUL: | ||
1612 | helper_le_stl_mmu(env, taddr, val, oi, ra); | ||
1613 | break; | ||
1614 | - case MO_LEQ: | ||
1615 | + case MO_LEUQ: | ||
1616 | helper_le_stq_mmu(env, taddr, val, oi, ra); | ||
1617 | break; | ||
1618 | case MO_BEUW: | ||
1619 | @@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val, | ||
1620 | case MO_BEUL: | ||
1621 | helper_be_stl_mmu(env, taddr, val, oi, ra); | ||
1622 | break; | ||
1623 | - case MO_BEQ: | ||
1624 | + case MO_BEUQ: | ||
1625 | helper_be_stq_mmu(env, taddr, val, oi, ra); | ||
1626 | break; | ||
1627 | default: | ||
1628 | @@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val, | ||
1629 | case MO_LEUL: | ||
1630 | stl_le_p(haddr, val); | ||
1631 | break; | ||
1632 | - case MO_LEQ: | ||
1633 | + case MO_LEUQ: | ||
1634 | stq_le_p(haddr, val); | ||
1635 | break; | ||
1636 | case MO_BEUW: | ||
1637 | @@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val, | ||
1638 | case MO_BEUL: | ||
1639 | stl_be_p(haddr, val); | ||
1640 | break; | ||
1641 | - case MO_BEQ: | ||
1642 | + case MO_BEUQ: | ||
1643 | stq_be_p(haddr, val); | ||
1644 | break; | ||
1645 | default: | ||
1646 | diff --git a/accel/tcg/ldst_common.c.inc b/accel/tcg/ldst_common.c.inc | ||
1647 | index XXXXXXX..XXXXXXX 100644 | ||
1648 | --- a/accel/tcg/ldst_common.c.inc | ||
1649 | +++ b/accel/tcg/ldst_common.c.inc | ||
1650 | @@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, | ||
1651 | uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, | ||
1652 | int mmu_idx, uintptr_t ra) | ||
1653 | { | ||
1654 | - MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx); | ||
1655 | + MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx); | ||
1656 | return cpu_ldq_be_mmu(env, addr, oi, ra); | ||
1657 | } | ||
1658 | |||
1659 | @@ -XXX,XX +XXX,XX @@ uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, | ||
1660 | uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, | ||
1661 | int mmu_idx, uintptr_t ra) | ||
1662 | { | ||
1663 | - MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx); | ||
1664 | + MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx); | ||
1665 | return cpu_ldq_le_mmu(env, addr, oi, ra); | ||
1666 | } | ||
1667 | |||
1668 | @@ -XXX,XX +XXX,XX @@ void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val, | ||
1669 | void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val, | ||
1670 | int mmu_idx, uintptr_t ra) | ||
1671 | { | ||
1672 | - MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx); | ||
1673 | + MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx); | ||
1674 | cpu_stq_be_mmu(env, addr, val, oi, ra); | ||
1675 | } | ||
1676 | |||
1677 | @@ -XXX,XX +XXX,XX @@ void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val, | ||
1678 | void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val, | ||
1679 | int mmu_idx, uintptr_t ra) | ||
1680 | { | ||
1681 | - MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx); | ||
1682 | + MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx); | ||
1683 | cpu_stq_le_mmu(env, addr, val, oi, ra); | ||
1684 | } | ||
1685 | |||
1686 | diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc | ||
1687 | index XXXXXXX..XXXXXXX 100644 | ||
1688 | --- a/target/mips/tcg/micromips_translate.c.inc | ||
1689 | +++ b/target/mips/tcg/micromips_translate.c.inc | ||
1690 | @@ -XXX,XX +XXX,XX @@ static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, | ||
1691 | gen_reserved_instruction(ctx); | ||
1692 | return; | ||
1693 | } | ||
1694 | - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); | ||
1695 | + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ); | ||
1696 | gen_store_gpr(t1, rd); | ||
1697 | tcg_gen_movi_tl(t1, 8); | ||
1698 | gen_op_addr_add(ctx, t0, t0, t1); | ||
1699 | - tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); | ||
1700 | + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ); | ||
1701 | gen_store_gpr(t1, rd + 1); | ||
1702 | break; | ||
1703 | case SDP: | ||
1704 | gen_load_gpr(t1, rd); | ||
1705 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); | ||
1706 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ); | ||
1707 | tcg_gen_movi_tl(t1, 8); | ||
1708 | gen_op_addr_add(ctx, t0, t0, t1); | ||
1709 | gen_load_gpr(t1, rd + 1); | ||
1710 | - tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); | ||
1711 | + tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ); | ||
1712 | break; | ||
1713 | #endif | ||
1714 | } | ||
1715 | @@ -XXX,XX +XXX,XX @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) | ||
1716 | case SCD: | ||
1717 | check_insn(ctx, ISA_MIPS3); | ||
1718 | check_mips_64(ctx); | ||
1719 | - gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false); | ||
1720 | + gen_st_cond(ctx, rt, rs, offset, MO_TEUQ, false); | ||
1721 | break; | ||
1722 | #endif | ||
1723 | case LD_EVA: | ||
1724 | diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc | ||
1725 | index XXXXXXX..XXXXXXX 100644 | ||
1726 | --- a/target/ppc/translate/fixedpoint-impl.c.inc | ||
1727 | +++ b/target/ppc/translate/fixedpoint-impl.c.inc | ||
1728 | @@ -XXX,XX +XXX,XX @@ static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed) | ||
1729 | ctx->base.is_jmp = DISAS_NORETURN; | ||
1730 | } | ||
1731 | } else { | ||
1732 | - mop = DEF_MEMOP(MO_Q); | ||
1733 | + mop = DEF_MEMOP(MO_UQ); | ||
1734 | if (store) { | ||
1735 | tcg_gen_qemu_st_i64(low_addr_gpr, ea, ctx->mem_idx, mop); | ||
1736 | } else { | ||
1737 | @@ -XXX,XX +XXX,XX @@ TRANS64(LWAUX, do_ldst_X, true, false, MO_SL) | ||
1738 | TRANS64(PLWA, do_ldst_PLS_D, false, false, MO_SL) | ||
1739 | |||
1740 | /* Load Doubleword */ | ||
1741 | -TRANS64(LD, do_ldst_D, false, false, MO_Q) | ||
1742 | -TRANS64(LDX, do_ldst_X, false, false, MO_Q) | ||
1743 | -TRANS64(LDU, do_ldst_D, true, false, MO_Q) | ||
1744 | -TRANS64(LDUX, do_ldst_X, true, false, MO_Q) | ||
1745 | -TRANS64(PLD, do_ldst_PLS_D, false, false, MO_Q) | ||
1746 | +TRANS64(LD, do_ldst_D, false, false, MO_UQ) | ||
1747 | +TRANS64(LDX, do_ldst_X, false, false, MO_UQ) | ||
1748 | +TRANS64(LDU, do_ldst_D, true, false, MO_UQ) | ||
1749 | +TRANS64(LDUX, do_ldst_X, true, false, MO_UQ) | ||
1750 | +TRANS64(PLD, do_ldst_PLS_D, false, false, MO_UQ) | ||
1751 | |||
1752 | /* Load Quadword */ | ||
1753 | TRANS64(LQ, do_ldst_quad, false, false); | ||
1754 | @@ -XXX,XX +XXX,XX @@ TRANS(STWUX, do_ldst_X, true, true, MO_UL) | ||
1755 | TRANS(PSTW, do_ldst_PLS_D, false, true, MO_UL) | ||
1756 | |||
1757 | /* Store Doubleword */ | ||
1758 | -TRANS64(STD, do_ldst_D, false, true, MO_Q) | ||
1759 | -TRANS64(STDX, do_ldst_X, false, true, MO_Q) | ||
1760 | -TRANS64(STDU, do_ldst_D, true, true, MO_Q) | ||
1761 | -TRANS64(STDUX, do_ldst_X, true, true, MO_Q) | ||
1762 | -TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q) | ||
1763 | +TRANS64(STD, do_ldst_D, false, true, MO_UQ) | ||
1764 | +TRANS64(STDX, do_ldst_X, false, true, MO_UQ) | ||
1765 | +TRANS64(STDU, do_ldst_D, true, true, MO_UQ) | ||
1766 | +TRANS64(STDUX, do_ldst_X, true, true, MO_UQ) | ||
1767 | +TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_UQ) | ||
1768 | |||
1769 | /* Store Quadword */ | ||
1770 | TRANS64(STQ, do_ldst_quad, true, false); | ||
1771 | diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc | ||
1772 | index XXXXXXX..XXXXXXX 100644 | ||
1773 | --- a/target/ppc/translate/fp-impl.c.inc | ||
1774 | +++ b/target/ppc/translate/fp-impl.c.inc | ||
1775 | @@ -XXX,XX +XXX,XX @@ static void gen_lfdepx(DisasContext *ctx) | ||
1776 | EA = tcg_temp_new(); | ||
1777 | t0 = tcg_temp_new_i64(); | ||
1778 | gen_addr_reg_index(ctx, EA); | ||
1779 | - tcg_gen_qemu_ld_i64(t0, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_Q)); | ||
1780 | + tcg_gen_qemu_ld_i64(t0, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UQ)); | ||
1781 | set_fpr(rD(ctx->opcode), t0); | ||
1782 | tcg_temp_free(EA); | ||
1783 | tcg_temp_free_i64(t0); | ||
1784 | @@ -XXX,XX +XXX,XX @@ static void gen_stfdepx(DisasContext *ctx) | ||
1785 | t0 = tcg_temp_new_i64(); | ||
1786 | gen_addr_reg_index(ctx, EA); | ||
1787 | get_fpr(t0, rD(ctx->opcode)); | ||
1788 | - tcg_gen_qemu_st_i64(t0, EA, PPC_TLB_EPID_STORE, DEF_MEMOP(MO_Q)); | ||
1789 | + tcg_gen_qemu_st_i64(t0, EA, PPC_TLB_EPID_STORE, DEF_MEMOP(MO_UQ)); | ||
1790 | tcg_temp_free(EA); | ||
1791 | tcg_temp_free_i64(t0); | ||
1792 | } | ||
1793 | diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc | ||
1794 | index XXXXXXX..XXXXXXX 100644 | ||
1795 | --- a/target/ppc/translate/vsx-impl.c.inc | ||
1796 | +++ b/target/ppc/translate/vsx-impl.c.inc | ||
1797 | @@ -XXX,XX +XXX,XX @@ static void gen_lxvw4x(DisasContext *ctx) | ||
1798 | TCGv_i64 t0 = tcg_temp_new_i64(); | ||
1799 | TCGv_i64 t1 = tcg_temp_new_i64(); | ||
1800 | |||
1801 | - tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEQ); | ||
1802 | + tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEUQ); | ||
1803 | tcg_gen_shri_i64(t1, t0, 32); | ||
1804 | tcg_gen_deposit_i64(xth, t1, t0, 32, 32); | ||
1805 | tcg_gen_addi_tl(EA, EA, 8); | ||
1806 | - tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEQ); | ||
1807 | + tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEUQ); | ||
1808 | tcg_gen_shri_i64(t1, t0, 32); | ||
1809 | tcg_gen_deposit_i64(xtl, t1, t0, 32, 32); | ||
1810 | tcg_temp_free_i64(t0); | ||
1811 | tcg_temp_free_i64(t1); | ||
1812 | } else { | ||
1813 | - tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ); | ||
1814 | + tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEUQ); | ||
1815 | tcg_gen_addi_tl(EA, EA, 8); | ||
1816 | - tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ); | ||
1817 | + tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEUQ); | ||
1818 | } | ||
1819 | set_cpu_vsr(xT(ctx->opcode), xth, true); | ||
1820 | set_cpu_vsr(xT(ctx->opcode), xtl, false); | ||
1821 | @@ -XXX,XX +XXX,XX @@ static void gen_lxvdsx(DisasContext *ctx) | ||
1822 | gen_addr_reg_index(ctx, EA); | ||
1823 | |||
1824 | data = tcg_temp_new_i64(); | ||
1825 | - tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, DEF_MEMOP(MO_Q)); | ||
1826 | - tcg_gen_gvec_dup_i64(MO_Q, vsr_full_offset(xT(ctx->opcode)), 16, 16, data); | ||
1827 | + tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, DEF_MEMOP(MO_UQ)); | ||
1828 | + tcg_gen_gvec_dup_i64(MO_UQ, vsr_full_offset(xT(ctx->opcode)), 16, 16, data); | ||
1829 | |||
1830 | tcg_temp_free(EA); | ||
1831 | tcg_temp_free_i64(data); | ||
1832 | @@ -XXX,XX +XXX,XX @@ static void gen_lxvh8x(DisasContext *ctx) | ||
1833 | |||
1834 | EA = tcg_temp_new(); | ||
1835 | gen_addr_reg_index(ctx, EA); | ||
1836 | - tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ); | ||
1837 | + tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEUQ); | ||
1838 | tcg_gen_addi_tl(EA, EA, 8); | ||
1839 | - tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ); | ||
1840 | + tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEUQ); | ||
1841 | if (ctx->le_mode) { | ||
1842 | gen_bswap16x8(xth, xtl, xth, xtl); | ||
1843 | } | ||
1844 | @@ -XXX,XX +XXX,XX @@ static void gen_lxvb16x(DisasContext *ctx) | ||
1845 | gen_set_access_type(ctx, ACCESS_INT); | ||
1846 | EA = tcg_temp_new(); | ||
1847 | gen_addr_reg_index(ctx, EA); | ||
1848 | - tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ); | ||
1849 | + tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEUQ); | ||
1850 | tcg_gen_addi_tl(EA, EA, 8); | ||
1851 | - tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ); | ||
1852 | + tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEUQ); | ||
1853 | set_cpu_vsr(xT(ctx->opcode), xth, true); | ||
1854 | set_cpu_vsr(xT(ctx->opcode), xtl, false); | ||
1855 | tcg_temp_free(EA); | ||
1856 | @@ -XXX,XX +XXX,XX @@ static void gen_stxvw4x(DisasContext *ctx) | ||
1857 | |||
1858 | tcg_gen_shri_i64(t0, xsh, 32); | ||
1859 | tcg_gen_deposit_i64(t1, t0, xsh, 32, 32); | ||
1860 | - tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEQ); | ||
1861 | + tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEUQ); | ||
1862 | tcg_gen_addi_tl(EA, EA, 8); | ||
1863 | tcg_gen_shri_i64(t0, xsl, 32); | ||
1864 | tcg_gen_deposit_i64(t1, t0, xsl, 32, 32); | ||
1865 | - tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEQ); | ||
1866 | + tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEUQ); | ||
1867 | tcg_temp_free_i64(t0); | ||
1868 | tcg_temp_free_i64(t1); | ||
1869 | } else { | ||
1870 | - tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ); | ||
1871 | + tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEUQ); | ||
1872 | tcg_gen_addi_tl(EA, EA, 8); | ||
1873 | - tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ); | ||
1874 | + tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEUQ); | ||
1875 | } | ||
1876 | tcg_temp_free(EA); | ||
1877 | tcg_temp_free_i64(xsh); | ||
1878 | @@ -XXX,XX +XXX,XX @@ static void gen_stxvh8x(DisasContext *ctx) | ||
1879 | TCGv_i64 outl = tcg_temp_new_i64(); | ||
1880 | |||
1881 | gen_bswap16x8(outh, outl, xsh, xsl); | ||
1882 | - tcg_gen_qemu_st_i64(outh, EA, ctx->mem_idx, MO_BEQ); | ||
1883 | + tcg_gen_qemu_st_i64(outh, EA, ctx->mem_idx, MO_BEUQ); | ||
1884 | tcg_gen_addi_tl(EA, EA, 8); | ||
1885 | - tcg_gen_qemu_st_i64(outl, EA, ctx->mem_idx, MO_BEQ); | ||
1886 | + tcg_gen_qemu_st_i64(outl, EA, ctx->mem_idx, MO_BEUQ); | ||
1887 | tcg_temp_free_i64(outh); | ||
1888 | tcg_temp_free_i64(outl); | ||
1889 | } else { | ||
1890 | - tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ); | ||
1891 | + tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEUQ); | ||
1892 | tcg_gen_addi_tl(EA, EA, 8); | ||
1893 | - tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ); | ||
1894 | + tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEUQ); | ||
1895 | } | ||
1896 | tcg_temp_free(EA); | ||
1897 | tcg_temp_free_i64(xsh); | ||
1898 | @@ -XXX,XX +XXX,XX @@ static void gen_stxvb16x(DisasContext *ctx) | ||
1899 | gen_set_access_type(ctx, ACCESS_INT); | ||
1900 | EA = tcg_temp_new(); | ||
1901 | gen_addr_reg_index(ctx, EA); | ||
1902 | - tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ); | ||
1903 | + tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEUQ); | ||
1904 | tcg_gen_addi_tl(EA, EA, 8); | ||
1905 | - tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ); | ||
1906 | + tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEUQ); | ||
1907 | tcg_temp_free(EA); | ||
1908 | tcg_temp_free_i64(xsh); | ||
1909 | tcg_temp_free_i64(xsl); | ||
1910 | @@ -XXX,XX +XXX,XX @@ static bool do_lstxv(DisasContext *ctx, int ra, TCGv displ, | ||
1911 | |||
1912 | xt = tcg_temp_new_i64(); | ||
1913 | |||
1914 | - mop = DEF_MEMOP(MO_Q); | ||
1915 | + mop = DEF_MEMOP(MO_UQ); | ||
1916 | |||
1917 | gen_set_access_type(ctx, ACCESS_INT); | ||
1918 | ea = do_ea_calc(ctx, ra, displ); | ||
1919 | diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc | ||
1920 | index XXXXXXX..XXXXXXX 100644 | ||
1921 | --- a/target/riscv/insn_trans/trans_rva.c.inc | ||
1922 | +++ b/target/riscv/insn_trans/trans_rva.c.inc | ||
1923 | @@ -XXX,XX +XXX,XX @@ static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a) | ||
1924 | static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) | ||
1925 | { | ||
1926 | REQUIRE_64BIT(ctx); | ||
1927 | - return gen_lr(ctx, a, MO_ALIGN | MO_TEQ); | ||
1928 | + return gen_lr(ctx, a, MO_ALIGN | MO_TEUQ); | ||
1929 | } | ||
1930 | |||
1931 | static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) | ||
1932 | { | ||
1933 | REQUIRE_64BIT(ctx); | ||
1934 | - return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ)); | ||
1935 | + return gen_sc(ctx, a, (MO_ALIGN | MO_TEUQ)); | ||
1936 | } | ||
1937 | |||
1938 | static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a) | ||
1939 | { | ||
1940 | REQUIRE_64BIT(ctx); | ||
1941 | - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEQ)); | ||
1942 | + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEUQ)); | ||
1943 | } | ||
1944 | |||
1945 | static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a) | ||
1946 | { | ||
1947 | REQUIRE_64BIT(ctx); | ||
1948 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEQ)); | ||
1949 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEUQ)); | ||
1950 | } | ||
1951 | |||
1952 | static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a) | ||
1953 | { | ||
1954 | REQUIRE_64BIT(ctx); | ||
1955 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEQ)); | ||
1956 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEUQ)); | ||
1957 | } | ||
1958 | |||
1959 | static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a) | ||
1960 | { | ||
1961 | REQUIRE_64BIT(ctx); | ||
1962 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEQ)); | ||
1963 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEUQ)); | ||
1964 | } | ||
1965 | |||
1966 | static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a) | ||
1967 | { | ||
1968 | REQUIRE_64BIT(ctx); | ||
1969 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEQ)); | ||
1970 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEUQ)); | ||
1971 | } | ||
1972 | |||
1973 | static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a) | ||
1974 | { | ||
1975 | REQUIRE_64BIT(ctx); | ||
1976 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEQ)); | ||
1977 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEUQ)); | ||
1978 | } | ||
1979 | |||
1980 | static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a) | ||
1981 | { | ||
1982 | REQUIRE_64BIT(ctx); | ||
1983 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEQ)); | ||
1984 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEUQ)); | ||
1985 | } | ||
1986 | |||
1987 | static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a) | ||
1988 | { | ||
1989 | REQUIRE_64BIT(ctx); | ||
1990 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEQ)); | ||
1991 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEUQ)); | ||
1992 | } | ||
1993 | |||
1994 | static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a) | ||
1995 | { | ||
1996 | REQUIRE_64BIT(ctx); | ||
1997 | - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEQ)); | ||
1998 | + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEUQ)); | ||
1999 | } | ||
2000 | diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc | ||
2001 | index XXXXXXX..XXXXXXX 100644 | ||
2002 | --- a/target/riscv/insn_trans/trans_rvd.c.inc | ||
2003 | +++ b/target/riscv/insn_trans/trans_rvd.c.inc | ||
2004 | @@ -XXX,XX +XXX,XX @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) | ||
2005 | } | ||
2006 | addr = gen_pm_adjust_address(ctx, addr); | ||
2007 | |||
2008 | - tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ); | ||
2009 | + tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ); | ||
2010 | |||
2011 | mark_fs_dirty(ctx); | ||
2012 | return true; | ||
2013 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) | ||
2014 | } | ||
2015 | addr = gen_pm_adjust_address(ctx, addr); | ||
2016 | |||
2017 | - tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ); | ||
2018 | + tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ); | ||
2019 | |||
2020 | return true; | ||
2021 | } | ||
2022 | diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc | ||
2023 | index XXXXXXX..XXXXXXX 100644 | ||
2024 | --- a/target/riscv/insn_trans/trans_rvh.c.inc | ||
2025 | +++ b/target/riscv/insn_trans/trans_rvh.c.inc | ||
2026 | @@ -XXX,XX +XXX,XX @@ static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a) | ||
2027 | { | ||
2028 | REQUIRE_64BIT(ctx); | ||
2029 | REQUIRE_EXT(ctx, RVH); | ||
2030 | - return do_hlv(ctx, a, MO_TEQ); | ||
2031 | + return do_hlv(ctx, a, MO_TEUQ); | ||
2032 | } | ||
2033 | |||
2034 | static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a) | ||
2035 | { | ||
2036 | REQUIRE_64BIT(ctx); | ||
2037 | REQUIRE_EXT(ctx, RVH); | ||
2038 | - return do_hsv(ctx, a, MO_TEQ); | ||
2039 | + return do_hsv(ctx, a, MO_TEUQ); | ||
2040 | } | ||
2041 | |||
2042 | #ifndef CONFIG_USER_ONLY | ||
2043 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
2044 | index XXXXXXX..XXXXXXX 100644 | ||
2045 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
2046 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
2047 | @@ -XXX,XX +XXX,XX @@ static bool trans_lwu(DisasContext *ctx, arg_lwu *a) | ||
2048 | static bool trans_ld(DisasContext *ctx, arg_ld *a) | ||
2049 | { | ||
2050 | REQUIRE_64BIT(ctx); | ||
2051 | - return gen_load(ctx, a, MO_TEQ); | ||
2052 | + return gen_load(ctx, a, MO_TEUQ); | ||
2053 | } | ||
2054 | |||
2055 | static bool trans_sd(DisasContext *ctx, arg_sd *a) | ||
2056 | { | ||
2057 | REQUIRE_64BIT(ctx); | ||
2058 | - return gen_store(ctx, a, MO_TEQ); | ||
2059 | + return gen_store(ctx, a, MO_TEUQ); | ||
2060 | } | ||
2061 | |||
2062 | static bool trans_addi(DisasContext *ctx, arg_addi *a) | ||
2063 | diff --git a/target/s390x/tcg/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc | ||
2064 | index XXXXXXX..XXXXXXX 100644 | ||
2065 | --- a/target/s390x/tcg/translate_vx.c.inc | ||
2066 | +++ b/target/s390x/tcg/translate_vx.c.inc | ||
2067 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_vl(DisasContext *s, DisasOps *o) | ||
2068 | TCGv_i64 t0 = tcg_temp_new_i64(); | ||
2069 | TCGv_i64 t1 = tcg_temp_new_i64(); | ||
2070 | |||
2071 | - tcg_gen_qemu_ld_i64(t0, o->addr1, get_mem_index(s), MO_TEQ); | ||
2072 | + tcg_gen_qemu_ld_i64(t0, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2073 | gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8); | ||
2074 | - tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ); | ||
2075 | + tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2076 | write_vec_element_i64(t0, get_field(s, v1), 0, ES_64); | ||
2077 | write_vec_element_i64(t1, get_field(s, v1), 1, ES_64); | ||
2078 | tcg_temp_free(t0); | ||
2079 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_vlm(DisasContext *s, DisasOps *o) | ||
2080 | t0 = tcg_temp_new_i64(); | ||
2081 | t1 = tcg_temp_new_i64(); | ||
2082 | gen_addi_and_wrap_i64(s, t0, o->addr1, (v3 - v1) * 16 + 8); | ||
2083 | - tcg_gen_qemu_ld_i64(t0, t0, get_mem_index(s), MO_TEQ); | ||
2084 | + tcg_gen_qemu_ld_i64(t0, t0, get_mem_index(s), MO_TEUQ); | ||
2085 | |||
2086 | for (;; v1++) { | ||
2087 | - tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ); | ||
2088 | + tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2089 | write_vec_element_i64(t1, v1, 0, ES_64); | ||
2090 | if (v1 == v3) { | ||
2091 | break; | ||
2092 | } | ||
2093 | gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8); | ||
2094 | - tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEQ); | ||
2095 | + tcg_gen_qemu_ld_i64(t1, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2096 | write_vec_element_i64(t1, v1, 1, ES_64); | ||
2097 | gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8); | ||
2098 | } | ||
2099 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_vst(DisasContext *s, DisasOps *o) | ||
2100 | gen_helper_probe_write_access(cpu_env, o->addr1, tmp); | ||
2101 | |||
2102 | read_vec_element_i64(tmp, get_field(s, v1), 0, ES_64); | ||
2103 | - tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ); | ||
2104 | + tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2105 | gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8); | ||
2106 | read_vec_element_i64(tmp, get_field(s, v1), 1, ES_64); | ||
2107 | - tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ); | ||
2108 | + tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2109 | tcg_temp_free_i64(tmp); | ||
2110 | return DISAS_NEXT; | ||
2111 | } | ||
2112 | @@ -XXX,XX +XXX,XX @@ static DisasJumpType op_vstm(DisasContext *s, DisasOps *o) | ||
2113 | |||
2114 | for (;; v1++) { | ||
2115 | read_vec_element_i64(tmp, v1, 0, ES_64); | ||
2116 | - tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ); | ||
2117 | + tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2118 | gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8); | ||
2119 | read_vec_element_i64(tmp, v1, 1, ES_64); | ||
2120 | - tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEQ); | ||
2121 | + tcg_gen_qemu_st_i64(tmp, o->addr1, get_mem_index(s), MO_TEUQ); | ||
2122 | if (v1 == v3) { | ||
2123 | break; | ||
2124 | } | ||
2125 | diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc | ||
2126 | index XXXXXXX..XXXXXXX 100644 | ||
2127 | --- a/tcg/aarch64/tcg-target.c.inc | ||
2128 | +++ b/tcg/aarch64/tcg-target.c.inc | ||
2129 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp memop, TCGType ext, | ||
2130 | case MO_SL: | ||
2131 | tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, otype, off_r); | ||
2132 | break; | ||
2133 | - case MO_Q: | ||
2134 | + case MO_UQ: | ||
2135 | tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r); | ||
2136 | break; | ||
2137 | default: | ||
2138 | diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc | ||
2139 | index XXXXXXX..XXXXXXX 100644 | ||
2140 | --- a/tcg/arm/tcg-target.c.inc | ||
2141 | +++ b/tcg/arm/tcg-target.c.inc | ||
2142 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[MO_SSIZE + 1] = { | ||
2143 | #ifdef HOST_WORDS_BIGENDIAN | ||
2144 | [MO_UW] = helper_be_lduw_mmu, | ||
2145 | [MO_UL] = helper_be_ldul_mmu, | ||
2146 | - [MO_Q] = helper_be_ldq_mmu, | ||
2147 | + [MO_UQ] = helper_be_ldq_mmu, | ||
2148 | [MO_SW] = helper_be_ldsw_mmu, | ||
2149 | [MO_SL] = helper_be_ldul_mmu, | ||
2150 | #else | ||
2151 | [MO_UW] = helper_le_lduw_mmu, | ||
2152 | [MO_UL] = helper_le_ldul_mmu, | ||
2153 | - [MO_Q] = helper_le_ldq_mmu, | ||
2154 | + [MO_UQ] = helper_le_ldq_mmu, | ||
2155 | [MO_SW] = helper_le_ldsw_mmu, | ||
2156 | [MO_SL] = helper_le_ldul_mmu, | ||
2157 | #endif | ||
2158 | @@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) | ||
2159 | default: | ||
2160 | tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0); | ||
2161 | break; | ||
2162 | - case MO_Q: | ||
2163 | + case MO_UQ: | ||
2164 | if (datalo != TCG_REG_R1) { | ||
2165 | tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0); | ||
2166 | tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1); | ||
2167 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_index(TCGContext *s, MemOp opc, | ||
2168 | case MO_UL: | ||
2169 | tcg_out_ld32_r(s, COND_AL, datalo, addrlo, addend); | ||
2170 | break; | ||
2171 | - case MO_Q: | ||
2172 | + case MO_UQ: | ||
2173 | /* Avoid ldrd for user-only emulation, to handle unaligned. */ | ||
2174 | if (USING_SOFTMMU && use_armv6_instructions | ||
2175 | && (datalo & 1) == 0 && datahi == datalo + 1) { | ||
2176 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg datalo, | ||
2177 | case MO_UL: | ||
2178 | tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0); | ||
2179 | break; | ||
2180 | - case MO_Q: | ||
2181 | + case MO_UQ: | ||
2182 | /* Avoid ldrd for user-only emulation, to handle unaligned. */ | ||
2183 | if (USING_SOFTMMU && use_armv6_instructions | ||
2184 | && (datalo & 1) == 0 && datahi == datalo + 1) { | ||
2185 | diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc | ||
2186 | index XXXXXXX..XXXXXXX 100644 | ||
2187 | --- a/tcg/i386/tcg-target.c.inc | ||
2188 | +++ b/tcg/i386/tcg-target.c.inc | ||
2189 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2190 | [MO_UB] = helper_ret_ldub_mmu, | ||
2191 | [MO_LEUW] = helper_le_lduw_mmu, | ||
2192 | [MO_LEUL] = helper_le_ldul_mmu, | ||
2193 | - [MO_LEQ] = helper_le_ldq_mmu, | ||
2194 | + [MO_LEUQ] = helper_le_ldq_mmu, | ||
2195 | [MO_BEUW] = helper_be_lduw_mmu, | ||
2196 | [MO_BEUL] = helper_be_ldul_mmu, | ||
2197 | - [MO_BEQ] = helper_be_ldq_mmu, | ||
2198 | + [MO_BEUQ] = helper_be_ldq_mmu, | ||
2199 | }; | ||
2200 | |||
2201 | /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, | ||
2202 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2203 | [MO_UB] = helper_ret_stb_mmu, | ||
2204 | [MO_LEUW] = helper_le_stw_mmu, | ||
2205 | [MO_LEUL] = helper_le_stl_mmu, | ||
2206 | - [MO_LEQ] = helper_le_stq_mmu, | ||
2207 | + [MO_LEUQ] = helper_le_stq_mmu, | ||
2208 | [MO_BEUW] = helper_be_stw_mmu, | ||
2209 | [MO_BEUL] = helper_be_stl_mmu, | ||
2210 | - [MO_BEQ] = helper_be_stq_mmu, | ||
2211 | + [MO_BEUQ] = helper_be_stq_mmu, | ||
2212 | }; | ||
2213 | |||
2214 | /* Perform the TLB load and compare. | ||
2215 | @@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) | ||
2216 | case MO_UL: | ||
2217 | tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); | ||
2218 | break; | ||
2219 | - case MO_Q: | ||
2220 | + case MO_UQ: | ||
2221 | if (TCG_TARGET_REG_BITS == 64) { | ||
2222 | tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX); | ||
2223 | } else if (data_reg == TCG_REG_EDX) { | ||
2224 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, | ||
2225 | } | ||
2226 | break; | ||
2227 | #endif | ||
2228 | - case MO_Q: | ||
2229 | + case MO_UQ: | ||
2230 | if (TCG_TARGET_REG_BITS == 64) { | ||
2231 | tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo, | ||
2232 | base, index, 0, ofs); | ||
2233 | diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc | ||
2234 | index XXXXXXX..XXXXXXX 100644 | ||
2235 | --- a/tcg/mips/tcg-target.c.inc | ||
2236 | +++ b/tcg/mips/tcg-target.c.inc | ||
2237 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[(MO_SSIZE | MO_BSWAP) + 1] = { | ||
2238 | [MO_LEUW] = helper_le_lduw_mmu, | ||
2239 | [MO_LESW] = helper_le_ldsw_mmu, | ||
2240 | [MO_LEUL] = helper_le_ldul_mmu, | ||
2241 | - [MO_LEQ] = helper_le_ldq_mmu, | ||
2242 | + [MO_LEUQ] = helper_le_ldq_mmu, | ||
2243 | [MO_BEUW] = helper_be_lduw_mmu, | ||
2244 | [MO_BESW] = helper_be_ldsw_mmu, | ||
2245 | [MO_BEUL] = helper_be_ldul_mmu, | ||
2246 | - [MO_BEQ] = helper_be_ldq_mmu, | ||
2247 | + [MO_BEUQ] = helper_be_ldq_mmu, | ||
2248 | #if TCG_TARGET_REG_BITS == 64 | ||
2249 | [MO_LESL] = helper_le_ldsl_mmu, | ||
2250 | [MO_BESL] = helper_be_ldsl_mmu, | ||
2251 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2252 | [MO_UB] = helper_ret_stb_mmu, | ||
2253 | [MO_LEUW] = helper_le_stw_mmu, | ||
2254 | [MO_LEUL] = helper_le_stl_mmu, | ||
2255 | - [MO_LEQ] = helper_le_stq_mmu, | ||
2256 | + [MO_LEUQ] = helper_le_stq_mmu, | ||
2257 | [MO_BEUW] = helper_be_stw_mmu, | ||
2258 | [MO_BEUL] = helper_be_stl_mmu, | ||
2259 | - [MO_BEQ] = helper_be_stq_mmu, | ||
2260 | + [MO_BEUQ] = helper_be_stq_mmu, | ||
2261 | }; | ||
2262 | |||
2263 | /* Helper routines for marshalling helper function arguments into | ||
2264 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, | ||
2265 | case MO_SL: | ||
2266 | tcg_out_opc_imm(s, OPC_LW, lo, base, 0); | ||
2267 | break; | ||
2268 | - case MO_Q | MO_BSWAP: | ||
2269 | + case MO_UQ | MO_BSWAP: | ||
2270 | if (TCG_TARGET_REG_BITS == 64) { | ||
2271 | if (use_mips32r2_instructions) { | ||
2272 | tcg_out_opc_imm(s, OPC_LD, lo, base, 0); | ||
2273 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, | ||
2274 | tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? hi : lo, TCG_TMP3); | ||
2275 | } | ||
2276 | break; | ||
2277 | - case MO_Q: | ||
2278 | + case MO_UQ: | ||
2279 | /* Prefer to load from offset 0 first, but allow for overlap. */ | ||
2280 | if (TCG_TARGET_REG_BITS == 64) { | ||
2281 | tcg_out_opc_imm(s, OPC_LD, lo, base, 0); | ||
2282 | diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc | ||
2283 | index XXXXXXX..XXXXXXX 100644 | ||
2284 | --- a/tcg/ppc/tcg-target.c.inc | ||
2285 | +++ b/tcg/ppc/tcg-target.c.inc | ||
2286 | @@ -XXX,XX +XXX,XX @@ static const uint32_t qemu_ldx_opc[(MO_SSIZE + MO_BSWAP) + 1] = { | ||
2287 | [MO_UB] = LBZX, | ||
2288 | [MO_UW] = LHZX, | ||
2289 | [MO_UL] = LWZX, | ||
2290 | - [MO_Q] = LDX, | ||
2291 | + [MO_UQ] = LDX, | ||
2292 | [MO_SW] = LHAX, | ||
2293 | [MO_SL] = LWAX, | ||
2294 | [MO_BSWAP | MO_UB] = LBZX, | ||
2295 | [MO_BSWAP | MO_UW] = LHBRX, | ||
2296 | [MO_BSWAP | MO_UL] = LWBRX, | ||
2297 | - [MO_BSWAP | MO_Q] = LDBRX, | ||
2298 | + [MO_BSWAP | MO_UQ] = LDBRX, | ||
2299 | }; | ||
2300 | |||
2301 | static const uint32_t qemu_stx_opc[(MO_SIZE + MO_BSWAP) + 1] = { | ||
2302 | [MO_UB] = STBX, | ||
2303 | [MO_UW] = STHX, | ||
2304 | [MO_UL] = STWX, | ||
2305 | - [MO_Q] = STDX, | ||
2306 | + [MO_UQ] = STDX, | ||
2307 | [MO_BSWAP | MO_UB] = STBX, | ||
2308 | [MO_BSWAP | MO_UW] = STHBRX, | ||
2309 | [MO_BSWAP | MO_UL] = STWBRX, | ||
2310 | - [MO_BSWAP | MO_Q] = STDBRX, | ||
2311 | + [MO_BSWAP | MO_UQ] = STDBRX, | ||
2312 | }; | ||
2313 | |||
2314 | static const uint32_t qemu_exts_opc[4] = { | ||
2315 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2316 | [MO_UB] = helper_ret_ldub_mmu, | ||
2317 | [MO_LEUW] = helper_le_lduw_mmu, | ||
2318 | [MO_LEUL] = helper_le_ldul_mmu, | ||
2319 | - [MO_LEQ] = helper_le_ldq_mmu, | ||
2320 | + [MO_LEUQ] = helper_le_ldq_mmu, | ||
2321 | [MO_BEUW] = helper_be_lduw_mmu, | ||
2322 | [MO_BEUL] = helper_be_ldul_mmu, | ||
2323 | - [MO_BEQ] = helper_be_ldq_mmu, | ||
2324 | + [MO_BEUQ] = helper_be_ldq_mmu, | ||
2325 | }; | ||
2326 | |||
2327 | /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr, | ||
2328 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2329 | [MO_UB] = helper_ret_stb_mmu, | ||
2330 | [MO_LEUW] = helper_le_stw_mmu, | ||
2331 | [MO_LEUL] = helper_le_stl_mmu, | ||
2332 | - [MO_LEQ] = helper_le_stq_mmu, | ||
2333 | + [MO_LEUQ] = helper_le_stq_mmu, | ||
2334 | [MO_BEUW] = helper_be_stw_mmu, | ||
2335 | [MO_BEUL] = helper_be_stl_mmu, | ||
2336 | - [MO_BEQ] = helper_be_stq_mmu, | ||
2337 | + [MO_BEUQ] = helper_be_stq_mmu, | ||
2338 | }; | ||
2339 | |||
2340 | /* We expect to use a 16-bit negative offset from ENV. */ | ||
2341 | diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc | ||
2342 | index XXXXXXX..XXXXXXX 100644 | ||
2343 | --- a/tcg/riscv/tcg-target.c.inc | ||
2344 | +++ b/tcg/riscv/tcg-target.c.inc | ||
2345 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[MO_SSIZE + 1] = { | ||
2346 | #if TCG_TARGET_REG_BITS == 64 | ||
2347 | [MO_SL] = helper_be_ldsl_mmu, | ||
2348 | #endif | ||
2349 | - [MO_Q] = helper_be_ldq_mmu, | ||
2350 | + [MO_UQ] = helper_be_ldq_mmu, | ||
2351 | #else | ||
2352 | [MO_UW] = helper_le_lduw_mmu, | ||
2353 | [MO_SW] = helper_le_ldsw_mmu, | ||
2354 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[MO_SSIZE + 1] = { | ||
2355 | #if TCG_TARGET_REG_BITS == 64 | ||
2356 | [MO_SL] = helper_le_ldsl_mmu, | ||
2357 | #endif | ||
2358 | - [MO_Q] = helper_le_ldq_mmu, | ||
2359 | + [MO_UQ] = helper_le_ldq_mmu, | ||
2360 | #endif | ||
2361 | }; | ||
2362 | |||
2363 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, | ||
2364 | case MO_SL: | ||
2365 | tcg_out_opc_imm(s, OPC_LW, lo, base, 0); | ||
2366 | break; | ||
2367 | - case MO_Q: | ||
2368 | + case MO_UQ: | ||
2369 | /* Prefer to load from offset 0 first, but allow for overlap. */ | ||
2370 | if (TCG_TARGET_REG_BITS == 64) { | ||
2371 | tcg_out_opc_imm(s, OPC_LD, lo, base, 0); | ||
2372 | diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc | ||
2373 | index XXXXXXX..XXXXXXX 100644 | ||
2374 | --- a/tcg/s390x/tcg-target.c.inc | ||
2375 | +++ b/tcg/s390x/tcg-target.c.inc | ||
2376 | @@ -XXX,XX +XXX,XX @@ static void * const qemu_ld_helpers[(MO_SSIZE | MO_BSWAP) + 1] = { | ||
2377 | [MO_LESW] = helper_le_ldsw_mmu, | ||
2378 | [MO_LEUL] = helper_le_ldul_mmu, | ||
2379 | [MO_LESL] = helper_le_ldsl_mmu, | ||
2380 | - [MO_LEQ] = helper_le_ldq_mmu, | ||
2381 | + [MO_LEUQ] = helper_le_ldq_mmu, | ||
2382 | [MO_BEUW] = helper_be_lduw_mmu, | ||
2383 | [MO_BESW] = helper_be_ldsw_mmu, | ||
2384 | [MO_BEUL] = helper_be_ldul_mmu, | ||
2385 | [MO_BESL] = helper_be_ldsl_mmu, | ||
2386 | - [MO_BEQ] = helper_be_ldq_mmu, | ||
2387 | + [MO_BEUQ] = helper_be_ldq_mmu, | ||
2388 | }; | ||
2389 | |||
2390 | static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2391 | [MO_UB] = helper_ret_stb_mmu, | ||
2392 | [MO_LEUW] = helper_le_stw_mmu, | ||
2393 | [MO_LEUL] = helper_le_stl_mmu, | ||
2394 | - [MO_LEQ] = helper_le_stq_mmu, | ||
2395 | + [MO_LEUQ] = helper_le_stq_mmu, | ||
2396 | [MO_BEUW] = helper_be_stw_mmu, | ||
2397 | [MO_BEUL] = helper_be_stl_mmu, | ||
2398 | - [MO_BEQ] = helper_be_stq_mmu, | ||
2399 | + [MO_BEUQ] = helper_be_stq_mmu, | ||
2400 | }; | ||
2401 | #endif | ||
2402 | |||
2403 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, | ||
2404 | tcg_out_insn(s, RXY, LGF, data, base, index, disp); | ||
2405 | break; | ||
2406 | |||
2407 | - case MO_Q | MO_BSWAP: | ||
2408 | + case MO_UQ | MO_BSWAP: | ||
2409 | tcg_out_insn(s, RXY, LRVG, data, base, index, disp); | ||
2410 | break; | ||
2411 | - case MO_Q: | ||
2412 | + case MO_UQ: | ||
2413 | tcg_out_insn(s, RXY, LG, data, base, index, disp); | ||
2414 | break; | ||
2415 | |||
2416 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data, | ||
2417 | } | ||
2418 | break; | ||
2419 | |||
2420 | - case MO_Q | MO_BSWAP: | ||
2421 | + case MO_UQ | MO_BSWAP: | ||
2422 | tcg_out_insn(s, RXY, STRVG, data, base, index, disp); | ||
2423 | break; | ||
2424 | - case MO_Q: | ||
2425 | + case MO_UQ: | ||
2426 | tcg_out_insn(s, RXY, STG, data, base, index, disp); | ||
2427 | break; | ||
2428 | |||
2429 | @@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) | ||
2430 | case MO_UL: | ||
2431 | tgen_ext32u(s, TCG_REG_R4, data_reg); | ||
2432 | break; | ||
2433 | - case MO_Q: | ||
2434 | + case MO_UQ: | ||
2435 | tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); | ||
2436 | break; | ||
2437 | default: | ||
2438 | diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc | ||
2439 | index XXXXXXX..XXXXXXX 100644 | ||
2440 | --- a/tcg/sparc/tcg-target.c.inc | ||
2441 | +++ b/tcg/sparc/tcg-target.c.inc | ||
2442 | @@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s) | ||
2443 | [MO_LEUW] = helper_le_lduw_mmu, | ||
2444 | [MO_LESW] = helper_le_ldsw_mmu, | ||
2445 | [MO_LEUL] = helper_le_ldul_mmu, | ||
2446 | - [MO_LEQ] = helper_le_ldq_mmu, | ||
2447 | + [MO_LEUQ] = helper_le_ldq_mmu, | ||
2448 | [MO_BEUW] = helper_be_lduw_mmu, | ||
2449 | [MO_BESW] = helper_be_ldsw_mmu, | ||
2450 | [MO_BEUL] = helper_be_ldul_mmu, | ||
2451 | - [MO_BEQ] = helper_be_ldq_mmu, | ||
2452 | + [MO_BEUQ] = helper_be_ldq_mmu, | ||
2453 | }; | ||
2454 | static void * const qemu_st_helpers[] = { | ||
2455 | [MO_UB] = helper_ret_stb_mmu, | ||
2456 | [MO_LEUW] = helper_le_stw_mmu, | ||
2457 | [MO_LEUL] = helper_le_stl_mmu, | ||
2458 | - [MO_LEQ] = helper_le_stq_mmu, | ||
2459 | + [MO_LEUQ] = helper_le_stq_mmu, | ||
2460 | [MO_BEUW] = helper_be_stw_mmu, | ||
2461 | [MO_BEUL] = helper_be_stl_mmu, | ||
2462 | - [MO_BEQ] = helper_be_stq_mmu, | ||
2463 | + [MO_BEUQ] = helper_be_stq_mmu, | ||
2464 | }; | ||
2465 | |||
2466 | int i; | ||
2467 | @@ -XXX,XX +XXX,XX @@ static const int qemu_ld_opc[(MO_SSIZE | MO_BSWAP) + 1] = { | ||
2468 | [MO_BESW] = LDSH, | ||
2469 | [MO_BEUL] = LDUW, | ||
2470 | [MO_BESL] = LDSW, | ||
2471 | - [MO_BEQ] = LDX, | ||
2472 | + [MO_BEUQ] = LDX, | ||
2473 | |||
2474 | [MO_LEUW] = LDUH_LE, | ||
2475 | [MO_LESW] = LDSH_LE, | ||
2476 | [MO_LEUL] = LDUW_LE, | ||
2477 | [MO_LESL] = LDSW_LE, | ||
2478 | - [MO_LEQ] = LDX_LE, | ||
2479 | + [MO_LEUQ] = LDX_LE, | ||
2480 | }; | ||
2481 | |||
2482 | static const int qemu_st_opc[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2483 | @@ -XXX,XX +XXX,XX @@ static const int qemu_st_opc[(MO_SIZE | MO_BSWAP) + 1] = { | ||
2484 | |||
2485 | [MO_BEUW] = STH, | ||
2486 | [MO_BEUL] = STW, | ||
2487 | - [MO_BEQ] = STX, | ||
2488 | + [MO_BEUQ] = STX, | ||
2489 | |||
2490 | [MO_LEUW] = STH_LE, | ||
2491 | [MO_LEUL] = STW_LE, | ||
2492 | - [MO_LEQ] = STX_LE, | ||
2493 | + [MO_LEUQ] = STX_LE, | ||
2494 | }; | ||
2495 | |||
2496 | static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, | ||
2497 | diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def | ||
2498 | index XXXXXXX..XXXXXXX 100644 | ||
2499 | --- a/target/s390x/tcg/insn-data.def | ||
2500 | +++ b/target/s390x/tcg/insn-data.def | ||
2501 | @@ -XXX,XX +XXX,XX @@ | ||
2502 | D(0xeb6a, ASI, SIY, GIE, la1, i2, new, 0, asi, adds32, MO_TESL) | ||
2503 | C(0xecd8, AHIK, RIE_d, DO, r3, i2, new, r1_32, add, adds32) | ||
2504 | C(0xc208, AGFI, RIL_a, EI, r1, i2, r1, 0, add, adds64) | ||
2505 | - D(0xeb7a, AGSI, SIY, GIE, la1, i2, new, 0, asi, adds64, MO_TEQ) | ||
2506 | + D(0xeb7a, AGSI, SIY, GIE, la1, i2, new, 0, asi, adds64, MO_TEUQ) | ||
2507 | C(0xecd9, AGHIK, RIE_d, DO, r3, i2, r1, 0, add, adds64) | ||
2508 | /* ADD IMMEDIATE HIGH */ | ||
2509 | C(0xcc08, AIH, RIL_a, HW, r1_sr32, i2, new, r1_32h, add, adds32) | ||
2510 | @@ -XXX,XX +XXX,XX @@ | ||
2511 | /* ADD LOGICAL WITH SIGNED IMMEDIATE */ | ||
2512 | D(0xeb6e, ALSI, SIY, GIE, la1, i2_32u, new, 0, asi, addu32, MO_TEUL) | ||
2513 | C(0xecda, ALHSIK, RIE_d, DO, r3_32u, i2_32u, new, r1_32, add, addu32) | ||
2514 | - D(0xeb7e, ALGSI, SIY, GIE, la1, i2, new, 0, asiu64, addu64, MO_TEQ) | ||
2515 | + D(0xeb7e, ALGSI, SIY, GIE, la1, i2, new, 0, asiu64, addu64, MO_TEUQ) | ||
2516 | C(0xecdb, ALGHSIK, RIE_d, DO, r3, i2, r1, 0, addu64, addu64) | ||
2517 | /* ADD LOGICAL WITH SIGNED IMMEDIATE HIGH */ | ||
2518 | C(0xcc0a, ALSIH, RIL_a, HW, r1_sr32, i2_32u, new, r1_32h, add, addu32) | ||
2519 | @@ -XXX,XX +XXX,XX @@ | ||
2520 | /* COMPARE AND SWAP */ | ||
2521 | D(0xba00, CS, RS_a, Z, r3_32u, r1_32u, new, r1_32, cs, 0, MO_TEUL) | ||
2522 | D(0xeb14, CSY, RSY_a, LD, r3_32u, r1_32u, new, r1_32, cs, 0, MO_TEUL) | ||
2523 | - D(0xeb30, CSG, RSY_a, Z, r3_o, r1_o, new, r1, cs, 0, MO_TEQ) | ||
2524 | + D(0xeb30, CSG, RSY_a, Z, r3_o, r1_o, new, r1, cs, 0, MO_TEUQ) | ||
2525 | /* COMPARE DOUBLE AND SWAP */ | ||
2526 | - D(0xbb00, CDS, RS_a, Z, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ) | ||
2527 | - D(0xeb31, CDSY, RSY_a, LD, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ) | ||
2528 | + D(0xbb00, CDS, RS_a, Z, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEUQ) | ||
2529 | + D(0xeb31, CDSY, RSY_a, LD, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEUQ) | ||
2530 | C(0xeb3e, CDSG, RSY_a, Z, 0, 0, 0, 0, cdsg, 0) | ||
2531 | /* COMPARE AND SWAP AND STORE */ | ||
2532 | C(0xc802, CSST, SSF, CASS, la1, a2, 0, 0, csst, 0) | ||
2533 | @@ -XXX,XX +XXX,XX @@ | ||
2534 | C(0xc000, LARL, RIL_b, Z, 0, ri2, 0, r1, mov2, 0) | ||
2535 | /* LOAD AND ADD */ | ||
2536 | D(0xebf8, LAA, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, laa, adds32, MO_TESL) | ||
2537 | - D(0xebe8, LAAG, RSY_a, ILA, r3, a2, new, in2_r1, laa, adds64, MO_TEQ) | ||
2538 | + D(0xebe8, LAAG, RSY_a, ILA, r3, a2, new, in2_r1, laa, adds64, MO_TEUQ) | ||
2539 | /* LOAD AND ADD LOGICAL */ | ||
2540 | D(0xebfa, LAAL, RSY_a, ILA, r3_32u, a2, new, in2_r1_32, laa, addu32, MO_TEUL) | ||
2541 | - D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa, addu64, MO_TEQ) | ||
2542 | + D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa, addu64, MO_TEUQ) | ||
2543 | /* LOAD AND AND */ | ||
2544 | D(0xebf4, LAN, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, lan, nz32, MO_TESL) | ||
2545 | - D(0xebe4, LANG, RSY_a, ILA, r3, a2, new, in2_r1, lan, nz64, MO_TEQ) | ||
2546 | + D(0xebe4, LANG, RSY_a, ILA, r3, a2, new, in2_r1, lan, nz64, MO_TEUQ) | ||
2547 | /* LOAD AND EXCLUSIVE OR */ | ||
2548 | D(0xebf7, LAX, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, lax, nz32, MO_TESL) | ||
2549 | - D(0xebe7, LAXG, RSY_a, ILA, r3, a2, new, in2_r1, lax, nz64, MO_TEQ) | ||
2550 | + D(0xebe7, LAXG, RSY_a, ILA, r3, a2, new, in2_r1, lax, nz64, MO_TEUQ) | ||
2551 | /* LOAD AND OR */ | ||
2552 | D(0xebf6, LAO, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, lao, nz32, MO_TESL) | ||
2553 | - D(0xebe6, LAOG, RSY_a, ILA, r3, a2, new, in2_r1, lao, nz64, MO_TEQ) | ||
2554 | + D(0xebe6, LAOG, RSY_a, ILA, r3, a2, new, in2_r1, lao, nz64, MO_TEUQ) | ||
2555 | /* LOAD AND TEST */ | ||
2556 | C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32) | ||
2557 | C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64) | ||
2558 | @@ -XXX,XX +XXX,XX @@ | ||
2559 | C(0xebe0, LOCFH, RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0) | ||
2560 | /* LOAD PAIR DISJOINT */ | ||
2561 | D(0xc804, LPD, SSF, ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL) | ||
2562 | - D(0xc805, LPDG, SSF, ILA, 0, 0, new_P, r3_P64, lpd, 0, MO_TEQ) | ||
2563 | + D(0xc805, LPDG, SSF, ILA, 0, 0, new_P, r3_P64, lpd, 0, MO_TEUQ) | ||
2564 | /* LOAD PAIR FROM QUADWORD */ | ||
2565 | C(0xe38f, LPQ, RXY_a, Z, 0, a2, r1_P, 0, lpq, 0) | ||
2566 | /* LOAD POSITIVE */ | ||
2567 | @@ -XXX,XX +XXX,XX @@ | ||
2568 | #ifndef CONFIG_USER_ONLY | ||
2569 | /* COMPARE AND SWAP AND PURGE */ | ||
2570 | E(0xb250, CSP, RRE, Z, r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL, IF_PRIV) | ||
2571 | - E(0xb98a, CSPG, RRE, DAT_ENH, r1_o, ra2, r1_P, 0, csp, 0, MO_TEQ, IF_PRIV) | ||
2572 | + E(0xb98a, CSPG, RRE, DAT_ENH, r1_o, ra2, r1_P, 0, csp, 0, MO_TEUQ, IF_PRIV) | ||
2573 | /* DIAGNOSE (KVM hypercall) */ | ||
2574 | F(0x8300, DIAG, RSI, Z, 0, 0, 0, 0, diag, 0, IF_PRIV | IF_IO) | ||
2575 | /* INSERT STORAGE KEY EXTENDED */ | ||
2576 | @@ -XXX,XX +XXX,XX @@ | ||
2577 | F(0xe303, LRAG, RXY_a, Z, 0, a2, r1, 0, lra, 0, IF_PRIV) | ||
2578 | /* LOAD USING REAL ADDRESS */ | ||
2579 | E(0xb24b, LURA, RRE, Z, 0, ra2, new, r1_32, lura, 0, MO_TEUL, IF_PRIV) | ||
2580 | - E(0xb905, LURAG, RRE, Z, 0, ra2, r1, 0, lura, 0, MO_TEQ, IF_PRIV) | ||
2581 | + E(0xb905, LURAG, RRE, Z, 0, ra2, r1, 0, lura, 0, MO_TEUQ, IF_PRIV) | ||
2582 | /* MOVE TO PRIMARY */ | ||
2583 | F(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0, IF_PRIV) | ||
2584 | /* MOVE TO SECONDARY */ | ||
2585 | @@ -XXX,XX +XXX,XX @@ | ||
2586 | F(0xad00, STOSM, SI, Z, la1, 0, 0, 0, stnosm, 0, IF_PRIV) | ||
2587 | /* STORE USING REAL ADDRESS */ | ||
2588 | E(0xb246, STURA, RRE, Z, r1_o, ra2, 0, 0, stura, 0, MO_TEUL, IF_PRIV) | ||
2589 | - E(0xb925, STURG, RRE, Z, r1_o, ra2, 0, 0, stura, 0, MO_TEQ, IF_PRIV) | ||
2590 | + E(0xb925, STURG, RRE, Z, r1_o, ra2, 0, 0, stura, 0, MO_TEUQ, IF_PRIV) | ||
2591 | /* TEST BLOCK */ | ||
2592 | F(0xb22c, TB, RRE, Z, 0, r2_o, 0, 0, testblock, 0, IF_PRIV) | ||
2593 | /* TEST PROTECTION */ | ||
2594 | -- | 190 | -- |
2595 | 2.31.1 | 191 | 2.41.0 |
2596 | |||
2597 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Conor Dooley <conor.dooley@microchip.com> |
---|---|---|---|
2 | 2 | ||
3 | Linux supports up to 32 cores for both 32-bit and 64-bit RISC-V, so | 3 | On a dtb dumped from the virt machine, dt-validate complains: |
4 | let's set that as the maximum for the virt board. | 4 | soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'} |
5 | from schema $id: http://devicetree.org/schemas/simple-bus.yaml# | ||
6 | That's pretty cryptic, but running the dtb back through dtc produces | ||
7 | something a lot more reasonable: | ||
8 | Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property | ||
5 | 9 | ||
6 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/435 | 10 | Moving the riscv,pmu node out of the soc bus solves the problem. |
11 | |||
12 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
15 | Message-ID: <20230727-groom-decline-2c57ce42841c@spud> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Anup Patel <anup.patel@wdc.com> | ||
9 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
10 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
11 | Message-Id: <20220105213937.1113508-9-alistair.francis@opensource.wdc.com> | ||
12 | --- | 17 | --- |
13 | include/hw/riscv/virt.h | 2 +- | 18 | hw/riscv/virt.c | 2 +- |
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | 19 | 1 file changed, 1 insertion(+), 1 deletion(-) |
15 | 20 | ||
16 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | 21 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
17 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/include/hw/riscv/virt.h | 23 | --- a/hw/riscv/virt.c |
19 | +++ b/include/hw/riscv/virt.h | 24 | +++ b/hw/riscv/virt.c |
20 | @@ -XXX,XX +XXX,XX @@ | 25 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s) |
21 | #include "hw/block/flash.h" | 26 | MachineState *ms = MACHINE(s); |
22 | #include "qom/object.h" | 27 | RISCVCPU hart = s->soc[0].harts[0]; |
23 | 28 | ||
24 | -#define VIRT_CPUS_MAX 8 | 29 | - pmu_name = g_strdup_printf("/soc/pmu"); |
25 | +#define VIRT_CPUS_MAX 32 | 30 | + pmu_name = g_strdup_printf("/pmu"); |
26 | #define VIRT_SOCKETS_MAX 8 | 31 | qemu_fdt_add_subnode(ms->fdt, pmu_name); |
27 | 32 | qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu"); | |
28 | #define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt") | 33 | riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name); |
29 | -- | 34 | -- |
30 | 2.31.1 | 35 | 2.41.0 |
31 | |||
32 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Weiwei Li <liweiwei@iscas.ac.cn> |
---|---|---|---|
2 | 2 | ||
3 | The csrs are accessed through function pointers: we add 128-bit read | 3 | The Svadu specification updated the name of the *envcfg bit from |
4 | operations in the table for three csrs (writes fallback to the | 4 | HADE to ADUE. |
5 | 64-bit version as the upper 64-bit information is handled elsewhere): | ||
6 | - misa, as mxl is needed for proper operation, | ||
7 | - mstatus and sstatus, to return sd | ||
8 | In addition, we also add read and write accesses to the machine and | ||
9 | supervisor scratch registers. | ||
10 | 5 | ||
11 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> |
12 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> |
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
14 | Message-id: 20220106210108.138226-19-frederic.petrot@univ-grenoble-alpes.fr | 9 | Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn> |
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 11 | --- |
17 | target/riscv/cpu.h | 7 ++ | 12 | target/riscv/cpu_bits.h | 8 ++++---- |
18 | target/riscv/cpu_bits.h | 3 + | 13 | target/riscv/cpu.c | 4 ++-- |
19 | target/riscv/csr.c | 195 +++++++++++++++++++++++++++++++++------- | 14 | target/riscv/cpu_helper.c | 6 +++--- |
20 | 3 files changed, 175 insertions(+), 30 deletions(-) | 15 | target/riscv/csr.c | 12 ++++++------ |
16 | 4 files changed, 15 insertions(+), 15 deletions(-) | ||
21 | 17 | ||
22 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/target/riscv/cpu.h | ||
25 | +++ b/target/riscv/cpu.h | ||
26 | @@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, | ||
27 | Int128 *ret_value, | ||
28 | Int128 new_value, Int128 write_mask); | ||
29 | |||
30 | +typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno, | ||
31 | + Int128 *ret_value); | ||
32 | +typedef RISCVException (*riscv_csr_write128_fn)(CPURISCVState *env, int csrno, | ||
33 | + Int128 new_value); | ||
34 | + | ||
35 | typedef struct { | ||
36 | const char *name; | ||
37 | riscv_csr_predicate_fn predicate; | ||
38 | riscv_csr_read_fn read; | ||
39 | riscv_csr_write_fn write; | ||
40 | riscv_csr_op_fn op; | ||
41 | + riscv_csr_read128_fn read128; | ||
42 | + riscv_csr_write128_fn write128; | ||
43 | } riscv_csr_operations; | ||
44 | |||
45 | /* CSR function table constants */ | ||
46 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | 18 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h |
47 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/target/riscv/cpu_bits.h | 20 | --- a/target/riscv/cpu_bits.h |
49 | +++ b/target/riscv/cpu_bits.h | 21 | +++ b/target/riscv/cpu_bits.h |
50 | @@ -XXX,XX +XXX,XX @@ | 22 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { |
51 | 23 | #define MENVCFG_CBIE (3UL << 4) | |
52 | #define MSTATUS32_SD 0x80000000 | 24 | #define MENVCFG_CBCFE BIT(6) |
53 | #define MSTATUS64_SD 0x8000000000000000ULL | 25 | #define MENVCFG_CBZE BIT(7) |
54 | +#define MSTATUSH128_SD 0x8000000000000000ULL | 26 | -#define MENVCFG_HADE (1ULL << 61) |
55 | 27 | +#define MENVCFG_ADUE (1ULL << 61) | |
56 | #define MISA32_MXL 0xC0000000 | 28 | #define MENVCFG_PBMTE (1ULL << 62) |
57 | #define MISA64_MXL 0xC000000000000000ULL | 29 | #define MENVCFG_STCE (1ULL << 63) |
58 | @@ -XXX,XX +XXX,XX @@ typedef enum { | 30 | |
59 | #define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */ | 31 | /* For RV32 */ |
60 | #define SSTATUS_MXR 0x00080000 | 32 | -#define MENVCFGH_HADE BIT(29) |
61 | 33 | +#define MENVCFGH_ADUE BIT(29) | |
62 | +#define SSTATUS64_UXL 0x0000000300000000ULL | 34 | #define MENVCFGH_PBMTE BIT(30) |
63 | + | 35 | #define MENVCFGH_STCE BIT(31) |
64 | #define SSTATUS32_SD 0x80000000 | 36 | |
65 | #define SSTATUS64_SD 0x8000000000000000ULL | 37 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { |
38 | #define HENVCFG_CBIE MENVCFG_CBIE | ||
39 | #define HENVCFG_CBCFE MENVCFG_CBCFE | ||
40 | #define HENVCFG_CBZE MENVCFG_CBZE | ||
41 | -#define HENVCFG_HADE MENVCFG_HADE | ||
42 | +#define HENVCFG_ADUE MENVCFG_ADUE | ||
43 | #define HENVCFG_PBMTE MENVCFG_PBMTE | ||
44 | #define HENVCFG_STCE MENVCFG_STCE | ||
45 | |||
46 | /* For RV32 */ | ||
47 | -#define HENVCFGH_HADE MENVCFGH_HADE | ||
48 | +#define HENVCFGH_ADUE MENVCFGH_ADUE | ||
49 | #define HENVCFGH_PBMTE MENVCFGH_PBMTE | ||
50 | #define HENVCFGH_STCE MENVCFGH_STCE | ||
51 | |||
52 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/cpu.c | ||
55 | +++ b/target/riscv/cpu.c | ||
56 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj) | ||
57 | env->two_stage_lookup = false; | ||
58 | |||
59 | env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) | | ||
60 | - (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0); | ||
61 | + (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0); | ||
62 | env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) | | ||
63 | - (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0); | ||
64 | + (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0); | ||
65 | |||
66 | /* Initialized default priorities of local interrupts. */ | ||
67 | for (i = 0; i < ARRAY_SIZE(env->miprio); i++) { | ||
68 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/cpu_helper.c | ||
71 | +++ b/target/riscv/cpu_helper.c | ||
72 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, | ||
73 | } | ||
74 | |||
75 | bool pbmte = env->menvcfg & MENVCFG_PBMTE; | ||
76 | - bool hade = env->menvcfg & MENVCFG_HADE; | ||
77 | + bool adue = env->menvcfg & MENVCFG_ADUE; | ||
78 | |||
79 | if (first_stage && two_stage && env->virt_enabled) { | ||
80 | pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE); | ||
81 | - hade = hade && (env->henvcfg & HENVCFG_HADE); | ||
82 | + adue = adue && (env->henvcfg & HENVCFG_ADUE); | ||
83 | } | ||
84 | |||
85 | int ptshift = (levels - 1) * ptidxbits; | ||
86 | @@ -XXX,XX +XXX,XX @@ restart: | ||
87 | |||
88 | /* Page table updates need to be atomic with MTTCG enabled */ | ||
89 | if (updated_pte != pte && !is_debug) { | ||
90 | - if (!hade) { | ||
91 | + if (!adue) { | ||
92 | return TRANSLATE_FAIL; | ||
93 | } | ||
66 | 94 | ||
67 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 95 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
68 | index XXXXXXX..XXXXXXX 100644 | 96 | index XXXXXXX..XXXXXXX 100644 |
69 | --- a/target/riscv/csr.c | 97 | --- a/target/riscv/csr.c |
70 | +++ b/target/riscv/csr.c | 98 | +++ b/target/riscv/csr.c |
71 | @@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS & | 99 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, |
72 | (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT))); | 100 | if (riscv_cpu_mxl(env) == MXL_RV64) { |
73 | static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | | 101 | mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | |
74 | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | | 102 | (cfg->ext_sstc ? MENVCFG_STCE : 0) | |
75 | - SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS; | 103 | - (cfg->ext_svadu ? MENVCFG_HADE : 0); |
76 | + SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS | (target_ulong)SSTATUS64_UXL; | 104 | + (cfg->ext_svadu ? MENVCFG_ADUE : 0); |
77 | static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; | ||
78 | static const target_ulong hip_writable_mask = MIP_VSSIP; | ||
79 | static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP; | ||
80 | @@ -XXX,XX +XXX,XX @@ static uint64_t add_status_sd(RISCVMXL xl, uint64_t status) | ||
81 | return status | MSTATUS32_SD; | ||
82 | case MXL_RV64: | ||
83 | return status | MSTATUS64_SD; | ||
84 | + case MXL_RV128: | ||
85 | + return MSTATUSH128_SD; | ||
86 | default: | ||
87 | g_assert_not_reached(); | ||
88 | } | ||
89 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, | ||
90 | |||
91 | mstatus = (mstatus & ~mask) | (val & mask); | ||
92 | |||
93 | - if (riscv_cpu_mxl(env) == MXL_RV64) { | ||
94 | + RISCVMXL xl = riscv_cpu_mxl(env); | ||
95 | + if (xl > MXL_RV32) { | ||
96 | /* SXL and UXL fields are for now read only */ | ||
97 | - mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64); | ||
98 | - mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64); | ||
99 | + mstatus = set_field(mstatus, MSTATUS64_SXL, xl); | ||
100 | + mstatus = set_field(mstatus, MSTATUS64_UXL, xl); | ||
101 | } | 105 | } |
102 | env->mstatus = mstatus; | 106 | env->menvcfg = (env->menvcfg & ~mask) | (val & mask); |
103 | 107 | ||
104 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno, | 108 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno, |
109 | const RISCVCPUConfig *cfg = riscv_cpu_cfg(env); | ||
110 | uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) | | ||
111 | (cfg->ext_sstc ? MENVCFG_STCE : 0) | | ||
112 | - (cfg->ext_svadu ? MENVCFG_HADE : 0); | ||
113 | + (cfg->ext_svadu ? MENVCFG_ADUE : 0); | ||
114 | uint64_t valh = (uint64_t)val << 32; | ||
115 | |||
116 | env->menvcfg = (env->menvcfg & ~mask) | (valh & mask); | ||
117 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno, | ||
118 | * henvcfg.stce is read_only 0 when menvcfg.stce = 0 | ||
119 | * henvcfg.hade is read_only 0 when menvcfg.hade = 0 | ||
120 | */ | ||
121 | - *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) | | ||
122 | + *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) | | ||
123 | env->menvcfg); | ||
105 | return RISCV_EXCP_NONE; | 124 | return RISCV_EXCP_NONE; |
106 | } | 125 | } |
107 | 126 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, | |
108 | +static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno, | ||
109 | + Int128 *val) | ||
110 | +{ | ||
111 | + *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus)); | ||
112 | + return RISCV_EXCP_NONE; | ||
113 | +} | ||
114 | + | ||
115 | +static RISCVException read_misa_i128(CPURISCVState *env, int csrno, | ||
116 | + Int128 *val) | ||
117 | +{ | ||
118 | + *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62); | ||
119 | + return RISCV_EXCP_NONE; | ||
120 | +} | ||
121 | + | ||
122 | static RISCVException read_misa(CPURISCVState *env, int csrno, | ||
123 | target_ulong *val) | ||
124 | { | ||
125 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mcounteren(CPURISCVState *env, int csrno, | ||
126 | } | ||
127 | |||
128 | /* Machine Trap Handling */ | ||
129 | +static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno, | ||
130 | + Int128 *val) | ||
131 | +{ | ||
132 | + *val = int128_make128(env->mscratch, env->mscratchh); | ||
133 | + return RISCV_EXCP_NONE; | ||
134 | +} | ||
135 | + | ||
136 | +static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno, | ||
137 | + Int128 val) | ||
138 | +{ | ||
139 | + env->mscratch = int128_getlo(val); | ||
140 | + env->mscratchh = int128_gethi(val); | ||
141 | + return RISCV_EXCP_NONE; | ||
142 | +} | ||
143 | + | ||
144 | static RISCVException read_mscratch(CPURISCVState *env, int csrno, | ||
145 | target_ulong *val) | ||
146 | { | ||
147 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip(CPURISCVState *env, int csrno, | ||
148 | } | ||
149 | |||
150 | /* Supervisor Trap Setup */ | ||
151 | +static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno, | ||
152 | + Int128 *val) | ||
153 | +{ | ||
154 | + uint64_t mask = sstatus_v1_10_mask; | ||
155 | + uint64_t sstatus = env->mstatus & mask; | ||
156 | + | ||
157 | + *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus)); | ||
158 | + return RISCV_EXCP_NONE; | ||
159 | +} | ||
160 | + | ||
161 | static RISCVException read_sstatus(CPURISCVState *env, int csrno, | ||
162 | target_ulong *val) | ||
163 | { | ||
164 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_scounteren(CPURISCVState *env, int csrno, | ||
165 | } | ||
166 | |||
167 | /* Supervisor Trap Handling */ | ||
168 | +static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno, | ||
169 | + Int128 *val) | ||
170 | +{ | ||
171 | + *val = int128_make128(env->sscratch, env->sscratchh); | ||
172 | + return RISCV_EXCP_NONE; | ||
173 | +} | ||
174 | + | ||
175 | +static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno, | ||
176 | + Int128 val) | ||
177 | +{ | ||
178 | + env->sscratch = int128_getlo(val); | ||
179 | + env->sscratchh = int128_gethi(val); | ||
180 | + return RISCV_EXCP_NONE; | ||
181 | +} | ||
182 | + | ||
183 | static RISCVException read_sscratch(CPURISCVState *env, int csrno, | ||
184 | target_ulong *val) | ||
185 | { | ||
186 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, | ||
187 | * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value); | ||
188 | */ | ||
189 | |||
190 | -RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | ||
191 | - target_ulong *ret_value, | ||
192 | - target_ulong new_value, target_ulong write_mask) | ||
193 | +static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
194 | + int csrno, | ||
195 | + bool write_mask, | ||
196 | + RISCVCPU *cpu) | ||
197 | { | ||
198 | - RISCVException ret; | ||
199 | - target_ulong old_value; | ||
200 | - RISCVCPU *cpu = env_archcpu(env); | ||
201 | - int read_only = get_field(csrno, 0xC00) == 3; | ||
202 | - | ||
203 | /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */ | ||
204 | + int read_only = get_field(csrno, 0xC00) == 3; | ||
205 | #if !defined(CONFIG_USER_ONLY) | ||
206 | int effective_priv = env->priv; | ||
207 | |||
208 | @@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | ||
209 | if (!csr_ops[csrno].predicate) { | ||
210 | return RISCV_EXCP_ILLEGAL_INST; | ||
211 | } | 127 | } |
212 | - ret = csr_ops[csrno].predicate(env, csrno); | 128 | |
213 | - if (ret != RISCV_EXCP_NONE) { | 129 | if (riscv_cpu_mxl(env) == MXL_RV64) { |
214 | - return ret; | 130 | - mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE); |
215 | - } | 131 | + mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE); |
216 | + | 132 | } |
217 | + return csr_ops[csrno].predicate(env, csrno); | 133 | |
218 | +} | 134 | env->henvcfg = (env->henvcfg & ~mask) | (val & mask); |
219 | + | 135 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno, |
220 | +static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno, | 136 | return ret; |
221 | + target_ulong *ret_value, | 137 | } |
222 | + target_ulong new_value, | 138 | |
223 | + target_ulong write_mask) | 139 | - *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) | |
224 | +{ | 140 | + *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) | |
225 | + RISCVException ret; | 141 | env->menvcfg)) >> 32; |
226 | + target_ulong old_value; | ||
227 | |||
228 | /* execute combined read/write operation if it exists */ | ||
229 | if (csr_ops[csrno].op) { | ||
230 | @@ -XXX,XX +XXX,XX @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | ||
231 | return RISCV_EXCP_NONE; | 142 | return RISCV_EXCP_NONE; |
232 | } | 143 | } |
233 | 144 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno, | |
234 | -RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, | 145 | target_ulong val) |
235 | - Int128 *ret_value, | ||
236 | - Int128 new_value, Int128 write_mask) | ||
237 | +RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | ||
238 | + target_ulong *ret_value, | ||
239 | + target_ulong new_value, target_ulong write_mask) | ||
240 | +{ | ||
241 | + RISCVCPU *cpu = env_archcpu(env); | ||
242 | + | ||
243 | + RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu); | ||
244 | + if (ret != RISCV_EXCP_NONE) { | ||
245 | + return ret; | ||
246 | + } | ||
247 | + | ||
248 | + return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask); | ||
249 | +} | ||
250 | + | ||
251 | +static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno, | ||
252 | + Int128 *ret_value, | ||
253 | + Int128 new_value, | ||
254 | + Int128 write_mask) | ||
255 | { | 146 | { |
256 | - /* fall back to 64-bit version for now */ | 147 | uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | |
257 | - target_ulong ret_64; | 148 | - HENVCFG_HADE); |
258 | - RISCVException ret = riscv_csrrw(env, csrno, &ret_64, | 149 | + HENVCFG_ADUE); |
259 | - int128_getlo(new_value), | 150 | uint64_t valh = (uint64_t)val << 32; |
260 | - int128_getlo(write_mask)); | 151 | RISCVException ret; |
261 | + RISCVException ret; | 152 | |
262 | + Int128 old_value; | ||
263 | + | ||
264 | + /* read old value */ | ||
265 | + ret = csr_ops[csrno].read128(env, csrno, &old_value); | ||
266 | + if (ret != RISCV_EXCP_NONE) { | ||
267 | + return ret; | ||
268 | + } | ||
269 | + | ||
270 | + /* write value if writable and write mask set, otherwise drop writes */ | ||
271 | + if (int128_nz(write_mask)) { | ||
272 | + new_value = int128_or(int128_and(old_value, int128_not(write_mask)), | ||
273 | + int128_and(new_value, write_mask)); | ||
274 | + if (csr_ops[csrno].write128) { | ||
275 | + ret = csr_ops[csrno].write128(env, csrno, new_value); | ||
276 | + if (ret != RISCV_EXCP_NONE) { | ||
277 | + return ret; | ||
278 | + } | ||
279 | + } else if (csr_ops[csrno].write) { | ||
280 | + /* avoids having to write wrappers for all registers */ | ||
281 | + ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value)); | ||
282 | + if (ret != RISCV_EXCP_NONE) { | ||
283 | + return ret; | ||
284 | + } | ||
285 | + } | ||
286 | + } | ||
287 | |||
288 | + /* return old value */ | ||
289 | if (ret_value) { | ||
290 | - *ret_value = int128_make64(ret_64); | ||
291 | + *ret_value = old_value; | ||
292 | + } | ||
293 | + | ||
294 | + return RISCV_EXCP_NONE; | ||
295 | +} | ||
296 | + | ||
297 | +RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, | ||
298 | + Int128 *ret_value, | ||
299 | + Int128 new_value, Int128 write_mask) | ||
300 | +{ | ||
301 | + RISCVException ret; | ||
302 | + RISCVCPU *cpu = env_archcpu(env); | ||
303 | + | ||
304 | + ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu); | ||
305 | + if (ret != RISCV_EXCP_NONE) { | ||
306 | + return ret; | ||
307 | } | ||
308 | |||
309 | + if (csr_ops[csrno].read128) { | ||
310 | + return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask); | ||
311 | + } | ||
312 | + | ||
313 | + /* | ||
314 | + * Fall back to 64-bit version for now, if the 128-bit alternative isn't | ||
315 | + * at all defined. | ||
316 | + * Note, some CSRs don't need to extend to MXLEN (64 upper bits non | ||
317 | + * significant), for those, this fallback is correctly handling the accesses | ||
318 | + */ | ||
319 | + target_ulong old_value; | ||
320 | + ret = riscv_csrrw_do64(env, csrno, &old_value, | ||
321 | + int128_getlo(new_value), | ||
322 | + int128_getlo(write_mask)); | ||
323 | + if (ret == RISCV_EXCP_NONE && ret_value) { | ||
324 | + *ret_value = int128_make64(old_value); | ||
325 | + } | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
330 | [CSR_MHARTID] = { "mhartid", any, read_mhartid }, | ||
331 | |||
332 | /* Machine Trap Setup */ | ||
333 | - [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus }, | ||
334 | - [CSR_MISA] = { "misa", any, read_misa, write_misa }, | ||
335 | + [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL, | ||
336 | + read_mstatus_i128 }, | ||
337 | + [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL, | ||
338 | + read_misa_i128 }, | ||
339 | [CSR_MIDELEG] = { "mideleg", any, read_mideleg, write_mideleg }, | ||
340 | [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, | ||
341 | [CSR_MIE] = { "mie", any, read_mie, write_mie }, | ||
342 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
343 | [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush }, | ||
344 | |||
345 | /* Machine Trap Handling */ | ||
346 | - [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch }, | ||
347 | + [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL, | ||
348 | + read_mscratch_i128, write_mscratch_i128 }, | ||
349 | [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc }, | ||
350 | [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause }, | ||
351 | [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, | ||
352 | [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, | ||
353 | |||
354 | /* Supervisor Trap Setup */ | ||
355 | - [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus }, | ||
356 | + [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL, | ||
357 | + read_sstatus_i128 }, | ||
358 | [CSR_SIE] = { "sie", smode, read_sie, write_sie }, | ||
359 | [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec }, | ||
360 | [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren }, | ||
361 | |||
362 | /* Supervisor Trap Handling */ | ||
363 | - [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch }, | ||
364 | + [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL, | ||
365 | + read_sscratch_i128, write_sscratch_i128 }, | ||
366 | [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc }, | ||
367 | [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, | ||
368 | [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, | ||
369 | -- | 153 | -- |
370 | 2.31.1 | 154 | 2.41.0 |
371 | |||
372 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | This patch adds the support of the '-cpu rv128' option to | 3 | In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times |
4 | qemu-system-riscv64 so that we can indicate that we want to run rv128 | 4 | longer to boot than the 'rv64' KVM CPU. |
5 | executables. | ||
6 | Still, there is no support for 128-bit insns at that stage so qemu fails | ||
7 | miserably (as expected) if launched with this option. | ||
8 | 5 | ||
9 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | The reason is an unintended behavior of riscv_cpu_satp_mode_finalize() |
10 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | when satp_mode.supported = 0, i.e. when cpu_init() does not set |
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | satp_mode_max_supported(). satp_mode_max_from_map(map) does: |
12 | Message-id: 20220106210108.138226-8-frederic.petrot@univ-grenoble-alpes.fr | 9 | |
13 | [ Changed by AF | 10 | 31 - __builtin_clz(map) |
14 | - Rename CPU to "x-rv128" | 11 | |
15 | ] | 12 | This means that, if satp_mode.supported = 0, satp_mode_supported_max |
13 | wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly | ||
14 | set it to UINT_MAX (4294967295). After that, if the user didn't set a | ||
15 | satp_mode, set_satp_mode_default_map(cpu) will make | ||
16 | |||
17 | cfg.satp_mode.map = cfg.satp_mode.supported | ||
18 | |||
19 | So satp_mode.map = 0. And then satp_mode_map_max will be set to | ||
20 | satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The | ||
21 | guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us | ||
22 | here since both are UINT_MAX. | ||
23 | |||
24 | And finally we have 2 loops: | ||
25 | |||
26 | for (int i = satp_mode_map_max - 1; i >= 0; --i) { | ||
27 | |||
28 | Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the | ||
29 | extra delay when booting the 'host' CPU is coming from. | ||
30 | |||
31 | Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0 | ||
32 | in a different manner. We're doing the same here. If supported == 0, | ||
33 | interpret as 'the CPU wants the OS to handle satp mode alone' and skip | ||
34 | satp_mode_finalize(). | ||
35 | |||
36 | We'll also put a guard in satp_mode_max_from_map() to assert out if map | ||
37 | is 0 since the function is not ready to deal with it. | ||
38 | |||
39 | Cc: Alexandre Ghiti <alexghiti@rivosinc.com> | ||
40 | Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode") | ||
41 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
42 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
43 | Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 44 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
17 | --- | 45 | --- |
18 | include/disas/dis-asm.h | 1 + | 46 | target/riscv/cpu.c | 23 ++++++++++++++++++++--- |
19 | target/riscv/cpu.h | 1 + | 47 | 1 file changed, 20 insertions(+), 3 deletions(-) |
20 | disas/riscv.c | 5 +++++ | ||
21 | target/riscv/cpu.c | 20 ++++++++++++++++++++ | ||
22 | target/riscv/gdbstub.c | 5 +++++ | ||
23 | 5 files changed, 32 insertions(+) | ||
24 | 48 | ||
25 | diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/include/disas/dis-asm.h | ||
28 | +++ b/include/disas/dis-asm.h | ||
29 | @@ -XXX,XX +XXX,XX @@ int print_insn_nios2(bfd_vma, disassemble_info*); | ||
30 | int print_insn_xtensa (bfd_vma, disassemble_info*); | ||
31 | int print_insn_riscv32 (bfd_vma, disassemble_info*); | ||
32 | int print_insn_riscv64 (bfd_vma, disassemble_info*); | ||
33 | +int print_insn_riscv128 (bfd_vma, disassemble_info*); | ||
34 | int print_insn_rx(bfd_vma, disassemble_info *); | ||
35 | int print_insn_hexagon(bfd_vma, disassemble_info *); | ||
36 | |||
37 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/target/riscv/cpu.h | ||
40 | +++ b/target/riscv/cpu.h | ||
41 | @@ -XXX,XX +XXX,XX @@ | ||
42 | #define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any") | ||
43 | #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32") | ||
44 | #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64") | ||
45 | +#define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128") | ||
46 | #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex") | ||
47 | #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c") | ||
48 | #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31") | ||
49 | diff --git a/disas/riscv.c b/disas/riscv.c | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/disas/riscv.c | ||
52 | +++ b/disas/riscv.c | ||
53 | @@ -XXX,XX +XXX,XX @@ int print_insn_riscv64(bfd_vma memaddr, struct disassemble_info *info) | ||
54 | { | ||
55 | return print_insn_riscv(memaddr, info, rv64); | ||
56 | } | ||
57 | + | ||
58 | +int print_insn_riscv128(bfd_vma memaddr, struct disassemble_info *info) | ||
59 | +{ | ||
60 | + return print_insn_riscv(memaddr, info, rv128); | ||
61 | +} | ||
62 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 49 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
63 | index XXXXXXX..XXXXXXX 100644 | 50 | index XXXXXXX..XXXXXXX 100644 |
64 | --- a/target/riscv/cpu.c | 51 | --- a/target/riscv/cpu.c |
65 | +++ b/target/riscv/cpu.c | 52 | +++ b/target/riscv/cpu.c |
66 | @@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj) | 53 | @@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str) |
67 | set_priv_version(env, PRIV_VERSION_1_10_0); | 54 | |
68 | qdev_prop_set_bit(DEVICE(obj), "mmu", false); | 55 | uint8_t satp_mode_max_from_map(uint32_t map) |
56 | { | ||
57 | + /* | ||
58 | + * 'map = 0' will make us return (31 - 32), which C will | ||
59 | + * happily overflow to UINT_MAX. There's no good result to | ||
60 | + * return if 'map = 0' (e.g. returning 0 will be ambiguous | ||
61 | + * with the result for 'map = 1'). | ||
62 | + * | ||
63 | + * Assert out if map = 0. Callers will have to deal with | ||
64 | + * it outside of this function. | ||
65 | + */ | ||
66 | + g_assert(map > 0); | ||
67 | + | ||
68 | /* map here has at least one bit set, so no problem with clz */ | ||
69 | return 31 - __builtin_clz(map); | ||
69 | } | 70 | } |
71 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
72 | static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp) | ||
73 | { | ||
74 | bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32; | ||
75 | - uint8_t satp_mode_map_max; | ||
76 | - uint8_t satp_mode_supported_max = | ||
77 | - satp_mode_max_from_map(cpu->cfg.satp_mode.supported); | ||
78 | + uint8_t satp_mode_map_max, satp_mode_supported_max; | ||
70 | + | 79 | + |
71 | +static void rv128_base_cpu_init(Object *obj) | 80 | + /* The CPU wants the OS to decide which satp mode to use */ |
72 | +{ | 81 | + if (cpu->cfg.satp_mode.supported == 0) { |
73 | + if (qemu_tcg_mttcg_enabled()) { | 82 | + return; |
74 | + /* Missing 128-bit aligned atomics */ | ||
75 | + error_report("128-bit RISC-V currently does not work with Multi " | ||
76 | + "Threaded TCG. Please use: -accel tcg,thread=single"); | ||
77 | + exit(EXIT_FAILURE); | ||
78 | + } | ||
79 | + CPURISCVState *env = &RISCV_CPU(obj)->env; | ||
80 | + /* We set this in the realise function */ | ||
81 | + set_misa(env, MXL_RV128, 0); | ||
82 | +} | ||
83 | #else | ||
84 | static void rv32_base_cpu_init(Object *obj) | ||
85 | { | ||
86 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) | ||
87 | case MXL_RV64: | ||
88 | info->print_insn = print_insn_riscv64; | ||
89 | break; | ||
90 | + case MXL_RV128: | ||
91 | + info->print_insn = print_insn_riscv128; | ||
92 | + break; | ||
93 | default: | ||
94 | g_assert_not_reached(); | ||
95 | } | ||
96 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
97 | #ifdef TARGET_RISCV64 | ||
98 | case MXL_RV64: | ||
99 | break; | ||
100 | + case MXL_RV128: | ||
101 | + break; | ||
102 | #endif | ||
103 | case MXL_RV32: | ||
104 | break; | ||
105 | @@ -XXX,XX +XXX,XX @@ static gchar *riscv_gdb_arch_name(CPUState *cs) | ||
106 | case MXL_RV32: | ||
107 | return g_strdup("riscv:rv32"); | ||
108 | case MXL_RV64: | ||
109 | + case MXL_RV128: | ||
110 | return g_strdup("riscv:rv64"); | ||
111 | default: | ||
112 | g_assert_not_reached(); | ||
113 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | ||
114 | DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init), | ||
115 | DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init), | ||
116 | DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init), | ||
117 | + DEFINE_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), | ||
118 | #endif | ||
119 | }; | ||
120 | |||
121 | diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c | ||
122 | index XXXXXXX..XXXXXXX 100644 | ||
123 | --- a/target/riscv/gdbstub.c | ||
124 | +++ b/target/riscv/gdbstub.c | ||
125 | @@ -XXX,XX +XXX,XX @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg) | ||
126 | int bitsize = 16 << env->misa_mxl_max; | ||
127 | int i; | ||
128 | |||
129 | + /* Until gdb knows about 128-bit registers */ | ||
130 | + if (bitsize > 64) { | ||
131 | + bitsize = 64; | ||
132 | + } | 83 | + } |
133 | + | 84 | + |
134 | g_string_printf(s, "<?xml version=\"1.0\"?>"); | 85 | + satp_mode_supported_max = |
135 | g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">"); | 86 | + satp_mode_max_from_map(cpu->cfg.satp_mode.supported); |
136 | g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">"); | 87 | |
88 | if (cpu->cfg.satp_mode.map == 0) { | ||
89 | if (cpu->cfg.satp_mode.init == 0) { | ||
137 | -- | 90 | -- |
138 | 2.31.1 | 91 | 2.41.0 |
139 | |||
140 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Vineet Gupta <vineetg@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | The Hypervisor spec is now frozen, so remove the experimental tag. | 3 | zicond is now codegen supported in both llvm and gcc. |
4 | 4 | ||
5 | This change allows seamless enabling/testing of zicond in downstream | ||
6 | projects. e.g. currently riscv-gnu-toolchain parses elf attributes | ||
7 | to create a cmdline for qemu but fails short of enabling it because of | ||
8 | the "x-" prefix. | ||
9 | |||
10 | Signed-off-by: Vineet Gupta <vineetg@rivosinc.com> | ||
11 | Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
6 | Reviewed-by: Anup Patel <anup.patel@wdc.com> | ||
7 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
8 | Message-Id: <20220105213937.1113508-6-alistair.francis@opensource.wdc.com> | ||
9 | --- | 14 | --- |
10 | target/riscv/cpu.c | 2 +- | 15 | target/riscv/cpu.c | 2 +- |
11 | 1 file changed, 1 insertion(+), 1 deletion(-) | 16 | 1 file changed, 1 insertion(+), 1 deletion(-) |
12 | 17 | ||
13 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 18 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
14 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/riscv/cpu.c | 20 | --- a/target/riscv/cpu.c |
16 | +++ b/target/riscv/cpu.c | 21 | +++ b/target/riscv/cpu.c |
17 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 22 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { |
18 | DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true), | 23 | DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false), |
19 | DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true), | 24 | DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false), |
20 | DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), | 25 | DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false), |
21 | + DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, false), | 26 | + DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false), |
22 | DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true), | 27 | |
23 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | 28 | /* Vendor-specific custom extensions */ |
24 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | 29 | DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false), |
25 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 30 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { |
26 | DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true), | 31 | DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false), |
27 | DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true), | 32 | |
28 | DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true), | 33 | /* These are experimental so mark with 'x-' */ |
29 | - DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), | 34 | - DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false), |
30 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | 35 | |
31 | /* ePMP 0.9.3 */ | 36 | /* ePMP 0.9.3 */ |
32 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | 37 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), |
33 | -- | 38 | -- |
34 | 2.31.1 | 39 | 2.41.0 |
35 | |||
36 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | A build with --enable-debug and without KVM will fail as follows: | ||
4 | |||
5 | /usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init': | ||
6 | ./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create' | ||
7 | |||
8 | This happens because the code block with "if virt_use_kvm_aia(s)" isn't | ||
9 | being ignored by the debug build, resulting in an undefined reference to | ||
10 | a KVM only function. | ||
11 | |||
12 | Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will | ||
13 | make the compiler crop the kvm_riscv_aia_create() call entirely from a | ||
14 | non-KVM build. Note that adding the 'kvm_enabled()' conditional inside | ||
15 | virt_use_kvm_aia() won't fix the build because this function would need | ||
16 | to be inlined multiple times to make the compiler zero out the entire | ||
17 | block. | ||
18 | |||
19 | While we're at it, use kvm_enabled() in all instances where | ||
20 | virt_use_kvm_aia() is checked to allow the compiler to elide these other | ||
21 | kvm-only instances as well. | ||
22 | |||
23 | Suggested-by: Richard Henderson <richard.henderson@linaro.org> | ||
24 | Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine") | ||
25 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
26 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
27 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
28 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
29 | Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com> | ||
3 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 30 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
4 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
5 | Message-Id: <20220105213937.1113508-4-alistair.francis@opensource.wdc.com> | ||
6 | --- | 31 | --- |
7 | hw/intc/sifive_plic.c | 55 +++++++++---------------------------------- | 32 | hw/riscv/virt.c | 6 +++--- |
8 | 1 file changed, 11 insertions(+), 44 deletions(-) | 33 | 1 file changed, 3 insertions(+), 3 deletions(-) |
9 | 34 | ||
10 | diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c | 35 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
11 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/hw/intc/sifive_plic.c | 37 | --- a/hw/riscv/virt.c |
13 | +++ b/hw/intc/sifive_plic.c | 38 | +++ b/hw/riscv/virt.c |
14 | @@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size) | 39 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
15 | { | 40 | } |
16 | SiFivePLICState *plic = opaque; | 41 | |
17 | 42 | /* KVM AIA only has one APLIC instance */ | |
18 | - /* writes must be 4 byte words */ | 43 | - if (virt_use_kvm_aia(s)) { |
19 | - if ((addr & 0x3) != 0) { | 44 | + if (kvm_enabled() && virt_use_kvm_aia(s)) { |
20 | - goto err; | 45 | create_fdt_socket_aplic(s, memmap, 0, |
21 | - } | 46 | msi_m_phandle, msi_s_phandle, phandle, |
22 | - | 47 | &intc_phandles[0], xplic_phandles, |
23 | - if (addr >= plic->priority_base && /* 4 bytes per source */ | 48 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
24 | - addr < plic->priority_base + (plic->num_sources << 2)) | 49 | |
25 | - { | 50 | g_free(intc_phandles); |
26 | + if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) { | 51 | |
27 | uint32_t irq = ((addr - plic->priority_base) >> 2) + 1; | 52 | - if (virt_use_kvm_aia(s)) { |
28 | - if (RISCV_DEBUG_PLIC) { | 53 | + if (kvm_enabled() && virt_use_kvm_aia(s)) { |
29 | - qemu_log("plic: read priority: irq=%d priority=%d\n", | 54 | *irq_mmio_phandle = xplic_phandles[0]; |
30 | - irq, plic->source_priority[irq]); | 55 | *irq_virtio_phandle = xplic_phandles[0]; |
31 | - } | 56 | *irq_pcie_phandle = xplic_phandles[0]; |
32 | + | 57 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) |
33 | return plic->source_priority[irq]; | ||
34 | - } else if (addr >= plic->pending_base && /* 1 bit per source */ | ||
35 | - addr < plic->pending_base + (plic->num_sources >> 3)) | ||
36 | - { | ||
37 | + } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) { | ||
38 | uint32_t word = (addr - plic->pending_base) >> 2; | ||
39 | - if (RISCV_DEBUG_PLIC) { | ||
40 | - qemu_log("plic: read pending: word=%d value=%d\n", | ||
41 | - word, plic->pending[word]); | ||
42 | - } | ||
43 | + | ||
44 | return plic->pending[word]; | ||
45 | - } else if (addr >= plic->enable_base && /* 1 bit per source */ | ||
46 | - addr < plic->enable_base + plic->num_addrs * plic->enable_stride) | ||
47 | - { | ||
48 | + } else if (addr_between(addr, plic->enable_base, | ||
49 | + plic->num_addrs * plic->enable_stride)) { | ||
50 | uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride; | ||
51 | uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2; | ||
52 | + | ||
53 | if (wordid < plic->bitfield_words) { | ||
54 | - if (RISCV_DEBUG_PLIC) { | ||
55 | - qemu_log("plic: read enable: hart%d-%c word=%d value=%x\n", | ||
56 | - plic->addr_config[addrid].hartid, | ||
57 | - mode_to_char(plic->addr_config[addrid].mode), wordid, | ||
58 | - plic->enable[addrid * plic->bitfield_words + wordid]); | ||
59 | - } | ||
60 | return plic->enable[addrid * plic->bitfield_words + wordid]; | ||
61 | } | ||
62 | - } else if (addr >= plic->context_base && /* 1 bit per source */ | ||
63 | - addr < plic->context_base + plic->num_addrs * plic->context_stride) | ||
64 | - { | ||
65 | + } else if (addr_between(addr, plic->context_base, | ||
66 | + plic->num_addrs * plic->context_stride)) { | ||
67 | uint32_t addrid = (addr - plic->context_base) / plic->context_stride; | ||
68 | uint32_t contextid = (addr & (plic->context_stride - 1)); | ||
69 | + | ||
70 | if (contextid == 0) { | ||
71 | - if (RISCV_DEBUG_PLIC) { | ||
72 | - qemu_log("plic: read priority: hart%d-%c priority=%x\n", | ||
73 | - plic->addr_config[addrid].hartid, | ||
74 | - mode_to_char(plic->addr_config[addrid].mode), | ||
75 | - plic->target_priority[addrid]); | ||
76 | - } | ||
77 | return plic->target_priority[addrid]; | ||
78 | } else if (contextid == 4) { | ||
79 | uint32_t value = sifive_plic_claim(plic, addrid); | ||
80 | - if (RISCV_DEBUG_PLIC) { | ||
81 | - qemu_log("plic: read claim: hart%d-%c irq=%x\n", | ||
82 | - plic->addr_config[addrid].hartid, | ||
83 | - mode_to_char(plic->addr_config[addrid].mode), | ||
84 | - value); | ||
85 | - } | ||
86 | + | ||
87 | sifive_plic_update(plic); | ||
88 | return value; | ||
89 | } | 58 | } |
90 | } | 59 | } |
91 | 60 | ||
92 | -err: | 61 | - if (virt_use_kvm_aia(s)) { |
93 | qemu_log_mask(LOG_GUEST_ERROR, | 62 | + if (kvm_enabled() && virt_use_kvm_aia(s)) { |
94 | "%s: Invalid register read 0x%" HWADDR_PRIx "\n", | 63 | kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT, |
95 | __func__, addr); | 64 | VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS, |
65 | memmap[VIRT_APLIC_S].base, | ||
96 | -- | 66 | -- |
97 | 2.31.1 | 67 | 2.41.0 |
98 | 68 | ||
99 | 69 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Adding the 128-bit version of lui and auipc, and introducing to that end | 3 | Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM |
4 | a "set register with immediat" function to handle extension on 128 bits. | 4 | environment with the following error: |
5 | 5 | ||
6 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | /usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request': |
7 | Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> | 7 | ./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq' |
8 | collect2: error: ld returned 1 exit status | ||
9 | |||
10 | This happens because the debug build will poke into the | ||
11 | 'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to | ||
12 | the KVM only function riscv_kvm_aplic_request(). | ||
13 | |||
14 | There are multiple solutions to fix this. We'll go with the same | ||
15 | solution from the previous patch, i.e. add a kvm_enabled() conditional | ||
16 | to filter out the block. But there's a catch: riscv_kvm_aplic_request() | ||
17 | is a local function that would end up being used if the compiler crops | ||
18 | the block, and this won't work. Quoting Richard Henderson's explanation | ||
19 | in [1]: | ||
20 | |||
21 | "(...) the compiler won't eliminate entire unused functions with -O0" | ||
22 | |||
23 | We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its | ||
24 | declaration in kvm_riscv.h, where all other KVM specific public | ||
25 | functions are already declared. Other archs handles KVM specific code in | ||
26 | this manner and we expect to do the same from now on. | ||
27 | |||
28 | [1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/ | ||
29 | |||
30 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
31 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
32 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 33 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 34 | Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com> |
10 | Message-id: 20220106210108.138226-12-frederic.petrot@univ-grenoble-alpes.fr | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 35 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 36 | --- |
13 | target/riscv/translate.c | 21 +++++++++++++++++++++ | 37 | target/riscv/kvm_riscv.h | 1 + |
14 | target/riscv/insn_trans/trans_rvi.c.inc | 8 ++++---- | 38 | hw/intc/riscv_aplic.c | 8 ++------ |
15 | 2 files changed, 25 insertions(+), 4 deletions(-) | 39 | target/riscv/kvm.c | 5 +++++ |
40 | 3 files changed, 8 insertions(+), 6 deletions(-) | ||
16 | 41 | ||
17 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 42 | diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h |
18 | index XXXXXXX..XXXXXXX 100644 | 43 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/translate.c | 44 | --- a/target/riscv/kvm_riscv.h |
20 | +++ b/target/riscv/translate.c | 45 | +++ b/target/riscv/kvm_riscv.h |
21 | @@ -XXX,XX +XXX,XX @@ static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t) | 46 | @@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, |
22 | } | 47 | uint64_t aia_irq_num, uint64_t aia_msi_num, |
48 | uint64_t aplic_base, uint64_t imsic_base, | ||
49 | uint64_t guest_num); | ||
50 | +void riscv_kvm_aplic_request(void *opaque, int irq, int level); | ||
51 | |||
52 | #endif | ||
53 | diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/hw/intc/riscv_aplic.c | ||
56 | +++ b/hw/intc/riscv_aplic.c | ||
57 | @@ -XXX,XX +XXX,XX @@ | ||
58 | #include "target/riscv/cpu.h" | ||
59 | #include "sysemu/sysemu.h" | ||
60 | #include "sysemu/kvm.h" | ||
61 | +#include "kvm_riscv.h" | ||
62 | #include "migration/vmstate.h" | ||
63 | |||
64 | #define APLIC_MAX_IDC (1UL << 14) | ||
65 | @@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc) | ||
66 | return topi; | ||
23 | } | 67 | } |
24 | 68 | ||
25 | +static void gen_set_gpri(DisasContext *ctx, int reg_num, target_long imm) | 69 | -static void riscv_kvm_aplic_request(void *opaque, int irq, int level) |
70 | -{ | ||
71 | - kvm_set_irq(kvm_state, irq, !!level); | ||
72 | -} | ||
73 | - | ||
74 | static void riscv_aplic_request(void *opaque, int irq, int level) | ||
75 | { | ||
76 | bool update = false; | ||
77 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) | ||
78 | * have IRQ lines delegated by their parent APLIC. | ||
79 | */ | ||
80 | if (!aplic->parent) { | ||
81 | - if (is_kvm_aia(aplic->msimode)) { | ||
82 | + if (kvm_enabled() && is_kvm_aia(aplic->msimode)) { | ||
83 | qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs); | ||
84 | } else { | ||
85 | qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs); | ||
86 | diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c | ||
87 | index XXXXXXX..XXXXXXX 100644 | ||
88 | --- a/target/riscv/kvm.c | ||
89 | +++ b/target/riscv/kvm.c | ||
90 | @@ -XXX,XX +XXX,XX @@ | ||
91 | #include "sysemu/runstate.h" | ||
92 | #include "hw/riscv/numa.h" | ||
93 | |||
94 | +void riscv_kvm_aplic_request(void *opaque, int irq, int level) | ||
26 | +{ | 95 | +{ |
27 | + if (reg_num != 0) { | 96 | + kvm_set_irq(kvm_state, irq, !!level); |
28 | + switch (get_ol(ctx)) { | ||
29 | + case MXL_RV32: | ||
30 | + tcg_gen_movi_tl(cpu_gpr[reg_num], (int32_t)imm); | ||
31 | + break; | ||
32 | + case MXL_RV64: | ||
33 | + case MXL_RV128: | ||
34 | + tcg_gen_movi_tl(cpu_gpr[reg_num], imm); | ||
35 | + break; | ||
36 | + default: | ||
37 | + g_assert_not_reached(); | ||
38 | + } | ||
39 | + | ||
40 | + if (get_xl_max(ctx) == MXL_RV128) { | ||
41 | + tcg_gen_movi_tl(cpu_gprh[reg_num], -(imm < 0)); | ||
42 | + } | ||
43 | + } | ||
44 | +} | 97 | +} |
45 | + | 98 | + |
46 | static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh) | 99 | static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, |
100 | uint64_t idx) | ||
47 | { | 101 | { |
48 | assert(get_ol(ctx) == MXL_RV128); | ||
49 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
52 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
53 | @@ -XXX,XX +XXX,XX @@ static bool trans_illegal(DisasContext *ctx, arg_empty *a) | ||
54 | |||
55 | static bool trans_c64_illegal(DisasContext *ctx, arg_empty *a) | ||
56 | { | ||
57 | - REQUIRE_64BIT(ctx); | ||
58 | - return trans_illegal(ctx, a); | ||
59 | + REQUIRE_64_OR_128BIT(ctx); | ||
60 | + return trans_illegal(ctx, a); | ||
61 | } | ||
62 | |||
63 | static bool trans_lui(DisasContext *ctx, arg_lui *a) | ||
64 | { | ||
65 | if (a->rd != 0) { | ||
66 | - tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm); | ||
67 | + gen_set_gpri(ctx, a->rd, a->imm); | ||
68 | } | ||
69 | return true; | ||
70 | } | ||
71 | @@ -XXX,XX +XXX,XX @@ static bool trans_lui(DisasContext *ctx, arg_lui *a) | ||
72 | static bool trans_auipc(DisasContext *ctx, arg_auipc *a) | ||
73 | { | ||
74 | if (a->rd != 0) { | ||
75 | - tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next); | ||
76 | + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next); | ||
77 | } | ||
78 | return true; | ||
79 | } | ||
80 | -- | 102 | -- |
81 | 2.31.1 | 103 | 2.41.0 |
82 | 104 | ||
83 | 105 | diff view generated by jsdifflib |
1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 1 | From: Robbin Ehn <rehn@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | Adding defines to handle signed 64-bit and unsigned 128-bit quantities in | 3 | This patch adds the new extensions in |
4 | memory accesses. | 4 | linux 6.5 to the hwprobe syscall. |
5 | 5 | ||
6 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> | 6 | And fixes RVC check to OR with correct value. |
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 7 | The previous variable contains 0 therefore it |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | did work. |
9 | Message-id: 20220106210108.138226-3-frederic.petrot@univ-grenoble-alpes.fr | 9 | |
10 | Signed-off-by: Robbin Ehn <rehn@rivosinc.com> | ||
11 | Acked-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 15 | --- |
12 | include/exec/memop.h | 7 +++++++ | 16 | linux-user/syscall.c | 14 +++++++++++++- |
13 | 1 file changed, 7 insertions(+) | 17 | 1 file changed, 13 insertions(+), 1 deletion(-) |
14 | 18 | ||
15 | diff --git a/include/exec/memop.h b/include/exec/memop.h | 19 | diff --git a/linux-user/syscall.c b/linux-user/syscall.c |
16 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/include/exec/memop.h | 21 | --- a/linux-user/syscall.c |
18 | +++ b/include/exec/memop.h | 22 | +++ b/linux-user/syscall.c |
19 | @@ -XXX,XX +XXX,XX @@ typedef enum MemOp { | 23 | @@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count) |
20 | MO_UW = MO_16, | 24 | #define RISCV_HWPROBE_KEY_IMA_EXT_0 4 |
21 | MO_UL = MO_32, | 25 | #define RISCV_HWPROBE_IMA_FD (1 << 0) |
22 | MO_UQ = MO_64, | 26 | #define RISCV_HWPROBE_IMA_C (1 << 1) |
23 | + MO_UO = MO_128, | 27 | +#define RISCV_HWPROBE_IMA_V (1 << 2) |
24 | MO_SB = MO_SIGN | MO_8, | 28 | +#define RISCV_HWPROBE_EXT_ZBA (1 << 3) |
25 | MO_SW = MO_SIGN | MO_16, | 29 | +#define RISCV_HWPROBE_EXT_ZBB (1 << 4) |
26 | MO_SL = MO_SIGN | MO_32, | 30 | +#define RISCV_HWPROBE_EXT_ZBS (1 << 5) |
27 | + MO_SQ = MO_SIGN | MO_64, | 31 | |
28 | + MO_SO = MO_SIGN | MO_128, | 32 | #define RISCV_HWPROBE_KEY_CPUPERF_0 5 |
29 | 33 | #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) | |
30 | MO_LEUW = MO_LE | MO_UW, | 34 | @@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env, |
31 | MO_LEUL = MO_LE | MO_UL, | 35 | riscv_has_ext(env, RVD) ? |
32 | MO_LEUQ = MO_LE | MO_UQ, | 36 | RISCV_HWPROBE_IMA_FD : 0; |
33 | MO_LESW = MO_LE | MO_SW, | 37 | value |= riscv_has_ext(env, RVC) ? |
34 | MO_LESL = MO_LE | MO_SL, | 38 | - RISCV_HWPROBE_IMA_C : pair->value; |
35 | + MO_LESQ = MO_LE | MO_SQ, | 39 | + RISCV_HWPROBE_IMA_C : 0; |
36 | 40 | + value |= riscv_has_ext(env, RVV) ? | |
37 | MO_BEUW = MO_BE | MO_UW, | 41 | + RISCV_HWPROBE_IMA_V : 0; |
38 | MO_BEUL = MO_BE | MO_UL, | 42 | + value |= cfg->ext_zba ? |
39 | MO_BEUQ = MO_BE | MO_UQ, | 43 | + RISCV_HWPROBE_EXT_ZBA : 0; |
40 | MO_BESW = MO_BE | MO_SW, | 44 | + value |= cfg->ext_zbb ? |
41 | MO_BESL = MO_BE | MO_SL, | 45 | + RISCV_HWPROBE_EXT_ZBB : 0; |
42 | + MO_BESQ = MO_BE | MO_SQ, | 46 | + value |= cfg->ext_zbs ? |
43 | 47 | + RISCV_HWPROBE_EXT_ZBS : 0; | |
44 | #ifdef NEED_CPU_H | 48 | __put_user(value, &pair->value); |
45 | MO_TEUW = MO_TE | MO_UW, | 49 | break; |
46 | MO_TEUL = MO_TE | MO_UL, | 50 | case RISCV_HWPROBE_KEY_CPUPERF_0: |
47 | MO_TEUQ = MO_TE | MO_UQ, | ||
48 | + MO_TEUO = MO_TE | MO_UO, | ||
49 | MO_TESW = MO_TE | MO_SW, | ||
50 | MO_TESL = MO_TE | MO_SL, | ||
51 | + MO_TESQ = MO_TE | MO_SQ, | ||
52 | #endif | ||
53 | |||
54 | MO_SSIZE = MO_SIZE | MO_SIGN, | ||
55 | -- | 51 | -- |
56 | 2.31.1 | 52 | 2.41.0 |
57 | |||
58 | diff view generated by jsdifflib |
1 | From: Bin Meng <bmeng.cn@gmail.com> | 1 | From: Ard Biesheuvel <ardb@kernel.org> |
---|---|---|---|
2 | 2 | ||
3 | Upgrade OpenSBI from v0.9 to v1.0 and the pre-built bios images. | 3 | Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to |
4 | implement the first half of the key schedule derivation. This does not | ||
5 | actually involve shifting rows, so clone the same value into all four | ||
6 | columns of the AES vector to counter that operation. | ||
4 | 7 | ||
5 | The v1.0 release includes the following commits: | 8 | Cc: Richard Henderson <richard.henderson@linaro.org> |
6 | 9 | Cc: Philippe Mathieu-Daudé <philmd@linaro.org> | |
7 | ec5274b platform: implement K210 system reset | 10 | Cc: Palmer Dabbelt <palmer@dabbelt.com> |
8 | 5487cf0 include: sbi: Simplify HSM state define names | 11 | Cc: Alistair Francis <alistair.francis@wdc.com> |
9 | 8df1f9a lib: sbi: Use SBI_HSM_STATE_xyz defines instead of SBI_STATE_xyz defines | 12 | Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
10 | 7c867fd lib: sbi: Rename sbi_hsm_hart_started_mask() function | 13 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
11 | 638c948 lib: sbi: Remove redundant sbi_hsm_hart_started() function | 14 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
12 | ca864a9 lib: sbi: Fix error codes returned by HSM start() and stop() functions | 15 | Message-ID: <20230831154118.138727-1-ardb@kernel.org> |
13 | 6290a22 include: sbi: Add HSM suspend related defines | ||
14 | 4b05df6 lib: sbi: Add sbi_hart_reinit() function | ||
15 | 807d71c include: sbi: Add hart_suspend() platform callback | ||
16 | 7475689 lib: sbi: Implement SBI HSM suspend function | ||
17 | b9cf617 include: sbi: Upgrade SBI implementation version to v0.3 | ||
18 | 50d4fde lib: Remove redundant sbi_platform_ipi_clear() calls | ||
19 | ff5bd94 include: sbi: SBI function IDs for RFENCE extension | ||
20 | 22d8ee9 firmware: Use lla to access all global symbols | ||
21 | 0f20e8a firmware: Support position independent execution | ||
22 | ddad02d lib: sbi: illegal CSR 0x306 access in hpm_allowed() | ||
23 | bfc85c7 include: headers: Replace __ASSEMBLY__ with __ASSEMBLER__ | ||
24 | 9190ad1 lib/utils: Support the official clint DT bindings | ||
25 | ca3f358 lib/utils: Drop the 'compat' parameter of fdt_plic_fixup() | ||
26 | 4edc822 lib/utils: Support fixing up the official DT bindings of PLIC | ||
27 | 4ef2f5d firware: optimize the exception exit code | ||
28 | 3d8a952 lib: fix csr detect support | ||
29 | e71a7c1 firmware: Remove redundant add instruction from trap restore path | ||
30 | d4a94ea include: types: Add __aligned(x) to define the minimum alignement | ||
31 | d0e406f include: sbi: Allow direct initialization via SPIN_LOCK_INIT() | ||
32 | 4d8e2f1 lib: sbi: Replace test-and-set locks by ticket locks | ||
33 | 70ffc3e lib: sbi: fix atomic_add_return | ||
34 | 27a16b1 docs: fix link to OpenPiton documentation | ||
35 | b1df1ac lib: sbi: Domains can be registered only before finalizing domains | ||
36 | 7495bce lib: sbi: Add sbi_domain_memregion_init() API | ||
37 | 4dc0001 lib: sbi: Add sbi_domain_root_add_memregion() API | ||
38 | 8b56980 lib: utils/sys: Add CLINT memregion in the root domain | ||
39 | fc37c97 lib: sbi: Make the root domain instance global variable | ||
40 | e7e4bcd lib: utils: Copy over restricted root domain memregions to FDT domains | ||
41 | f41196a lib: sbi: Make sbi_domain_memregion_initfw() a local function | ||
42 | c5d0645 lib: utils: Implement "64bit-mmio" property parsing | ||
43 | 49e422c lib: utils: reset: Add T-HEAD sample platform reset driver | ||
44 | 0d56293 lib: sbi: Fix sbi_domain_root_add_memregion() for merging memregions | ||
45 | bf3ef53 firmware: Enable FW_PIC by default | ||
46 | 1db8436 platform: Remove platform/thead | ||
47 | 6d1642f docs: generic: Add T-HEAD C9xx series processors | ||
48 | a3689db lib: sbi: Remove domains_root_regions() platform callback | ||
49 | 068ca08 lib: sbi: Simplify console platform operations | ||
50 | 559a8f1 lib: sbi: Simplify timer platform operations | ||
51 | dc39c7b lib: sbi: Simplify ipi platform operations | ||
52 | 043d088 lib: sbi: Simplify system reset platform operations | ||
53 | a84a1dd lib: sbi: Simplify HSM platform operations | ||
54 | e9a27ab lib: sbi: Show devices provided by platform in boot prints | ||
55 | 632e27b docs/platform: sifive_fu540: Update U-Boot defconfig name | ||
56 | 117fb6d lib: utils/serial: Add support for Gaisler APBUART | ||
57 | 552f53f docs: platform: Sort platform names | ||
58 | d4177e7 docs: platform: Describe sifive_fu540 as supported generic platform | ||
59 | 26998f3 platform: Remove sifive/fu540 platform | ||
60 | f90c4c2 lib: sbi: Have spinlock checks return bool | ||
61 | e822b75 lib: utils/serial: Support Synopsys DesignWare APB UART | ||
62 | 6139ab2 Makefile: unconditionally disable SSP | ||
63 | c9ef2bc lib: utils: Add strncpy macro to libfdt_env.h | ||
64 | ee7c2b2 lib: utils/fdt: Don't use sbi_string functions | ||
65 | fe92347 lib: utils/fdt: Replace strcmp with strncmp | ||
66 | b2dbbc0 lib: Check region base for merging in sbi_domain_root_add_memregion() | ||
67 | 54d7def lib: utils: Try other FDT drivers when we see SBI_ENODEV | ||
68 | d9ba653 docs: debugging OpenSBI | ||
69 | 66c4fca lib: utils: consider ':' in stdout-path | ||
70 | f30b189 lib: sbi_scratch: remove owner from sbi_scratch_alloc_offset | ||
71 | a03ea2e platform: andes/ae350: Cosmetic fixes in plicsw.c | ||
72 | b32fac4 docs/platform: andes-ae350: Fix missing spaces | ||
73 | de446cc platform: andes/ae350: Drop plicsw_get_pending() | ||
74 | 434198e platform: andes/ae350: Drop plicsw_ipi_sync() | ||
75 | 1da3d80 lib: sbi_scratch: zero out scratch memory on all harts | ||
76 | 360ab88 lib: utils: missing initialization in thead_reset_init | ||
77 | 79f9b42 lib: sbi: Fix GET_F64_REG inline assembly | ||
78 | eb90e0a lib: utils/libfdt: Upgrade to v1.6.1 release | ||
79 | cdcf907 lib: sign conflict in sbi_tlb_entry_process() | ||
80 | 9901794 lib: sign conflict in wake_coldboot_harts() | ||
81 | 11c345f lib: simplify sbi_fifo_inplace_update() | ||
82 | 4519e29 lib: utils/timer: Add ACLINT MTIMER library | ||
83 | 5a049fe lib: utils/ipi: Add ACLINT MSWI library | ||
84 | bd5d208 lib: utils: Add FDT parsing API common for both ACLINT and CLINT | ||
85 | 56fc5f7 lib: utils/ipi: Add FDT based ACLINT MSWI IPI driver | ||
86 | 03d6bb5 lib: utils/timer: Add FDT based ACLINT MTIMER driver | ||
87 | a731c7e platform: Replace CLINT library usage with ACLINT library | ||
88 | b7f2cd2 lib: utils: reset: unify naming of 'sifive_test' device | ||
89 | 197e089 docs/platform: thead-c9xx: Remove FW_PIC=y | ||
90 | 17e23b6 platform: generic: Terminate platform.name with null | ||
91 | 3e8b31a docs: Add device tree bindings for SBI PMU extension | ||
92 | fde28fa lib: sbi: Detect mcountinihibit support at runtime | ||
93 | d3a96cc lib: sbi: Remove stray '\' character | ||
94 | 0829f2b lib: sbi: Detect number of bits implemented in mhpmcounter | ||
95 | 9c9b4ad lib: sbi: Disable m/scounteren & enable mcountinhibit | ||
96 | 41ae63c include: Add a list empty check function | ||
97 | fd9116b lib: sbi: Remove redundant boot time print statement | ||
98 | 49966db lib: sbi: Use csr_read/write_num to read/update PMU counters | ||
99 | e7cc7a3 lib: sbi: Add PMU specific platform hooks | ||
100 | 13d40f2 lib: sbi: Add PMU support | ||
101 | ae72ec0 utils: fdt: Add fdt helper functions to parse PMU DT nodes | ||
102 | 37f9b0f lib: sbi: Implement SBI PMU extension | ||
103 | 764a17d lib: sbi: Implement firmware counters | ||
104 | ec1b8bb lib: sbi: Improve TLB function naming | ||
105 | 0e12aa8 platform: generic: Add PMU support | ||
106 | 14c7f71 firmware: Minor optimization in _scratch_init() | ||
107 | dafaa0f docs: Correct a typo in platform_guide.md | ||
108 | abfce9b docs: Make <xyz> visible in the rendered platform guide | ||
109 | dcb756b firmware: Remove the sanity checks in fw_save_info() | ||
110 | b88b366 firmware: Define a macro for version of struct fw_dynamic_info | ||
111 | a76ac44 lib: sbi: Fix sbi_pmu_exit() for systems not having MCOUNTINHIBIT csr | ||
112 | 7f1be8a fw_base: Don't mark fw_platform_init as both global and weak | ||
113 | 397afe5 fw_base: Put data in .data rather than .text | ||
114 | a3d328a firmware: Explicitly pass -pie to the linker, not just the driver | ||
115 | 09ad811 firmware: Only default FW_PIC to y if supported | ||
116 | 2942777 Makefile: Support building with Clang and LLVM binutils | ||
117 | 17729d4 lib: utils: Drop dependency on libgcc by importing part of FreeBSD's libquad | ||
118 | e931f38 lib: utils/fdt: Add fdt_parse_phandle_with_args() API | ||
119 | 36b8eff lib: utils/gpio: Add generic GPIO configuration library | ||
120 | c14f1fe lib: utils/gpio: Add simple FDT based GPIO framework | ||
121 | 4c3df2a lib: utils/gpio: Add minimal SiFive GPIO driver | ||
122 | e3d6919 lib: utils/reset: Add generic GPIO reset driver | ||
123 | 7210e90 firmware: use __SIZEOF_LONG__ for field offsets in fw_dynamic.h | ||
124 | f3a8f60 include: types: Use __builtin_offsetof when supported | ||
125 | 8a1475b firmware: Remove the unhelpful alignment codes before fdt relocation | ||
126 | a4555e5 docs: Document parameters passed to firmware and alignment requirement | ||
127 | 2c74dc3 docs: Document FW_PIC compile time option | ||
128 | 81eb708 README: Update toolchain information | ||
129 | 9890391 Makefile: Manually forward RELAX_FLAG to the assembler when linking with LLD | ||
130 | 74db0ac firmware: use _fw_start for load address | ||
131 | 217d5e4 generic: fu740: add workaround for CIP-1200 errata | ||
132 | ce03c88 lib: utils: remove unused variable in fdt_reset_init | ||
133 | e928472 lib: utils: support both of gpio-poweroff, gpio-reset | ||
134 | d244f3d lib: sbi: Fix bug in strncmp function when count is 0 | ||
135 | 47a4765 lib: utils/fdt: Change addr and size to uint64_t | ||
136 | e0d1b9d lib: utils/timer: Allow separate base addresses for MTIME and MTIMECMP | ||
137 | 7a3a0cc lib: utils: Extend fdt_get_node_addr_size() for multiple register sets | ||
138 | f3a0eb8 lib: utils/fdt: Extend fdt_parse_aclint_node() function | ||
139 | b35f782 lib: utils/timer: Allow ACLINT MTIMER supporting only 32-bit MMIO | ||
140 | 7aa6c9a lib: utils/timer: Simplify MTIMER synchronization | ||
141 | 33eac76 lib: sbi: Fix bug in sbi_ecall_rfence that misses checking | ||
142 | ee27437 lib: sbi_trap: Restore redirect for access faults | ||
143 | b1d3e91 payloads/test: Add support for SBI v0.2 ecalls | ||
144 | bd316e2 lib: sbi: Correct typo in faults delegation CSR name | ||
145 | c262306 lib: sbi: protect dprintf output with spinlock | ||
146 | 1718b16 lib: sbi: Checking fifo validness in sbi_fifo_is_empty and is_full | ||
147 | bd35521 lib: sbi: Refine the way to construct platform features | ||
148 | 0274a96 lib: utils/reset: Sort fdt_reset driver list | ||
149 | 395ff7e lib: utils/reset: Add a sunxi watchdog reset driver | ||
150 | 3477f08 lib: sbi: fix ctz bug | ||
151 | 12753d2 lib: sbi: add some macros to detect BUG at runtime | ||
152 | 51113fe lib: sbi: Add BUG() macro for csr_read/write_num() and misa_string() | ||
153 | 72154f4 lib: utils/fdt: Add fdt_parse_timebase_frequency() function | ||
154 | 12e7af9 lib: sbi: Add timer frequency to struct sbi_timer_device | ||
155 | 6355155 lib: sbi: Print timer frequency at boot time | ||
156 | 9d0ab35 lib: sbi: Add generic timer delay loop function | ||
157 | fa59dd3 lib: utils/reset: use sbi_timer_mdelay() in gpio reset driver | ||
158 | 754d511 lib: utils: identify supported GPIO reset methods | ||
159 | 516161c lib: sbi: convert reset to list | ||
160 | 9283d50 lib: sbi: add priority for reset handler | ||
161 | c38973e lib: sbi: Save context for all non-retentive suspend types | ||
162 | 67cbbcb lib: sbi: system reset with invalid parameters | ||
163 | 422eda4 Makefile: Add build time and compiler info string | ||
164 | 78c2b19 lib: utils/irqchip: Automatically delegate T-HEAD PLIC access | ||
165 | 309e8bd lib: utils/reset: Register separate GPIO system reset devices | ||
166 | 723aa88 lib: sbi: Refine addr format in sbi_printf | ||
167 | c891acc include: sbi_utils: Introduce an helper to get fdt base address | ||
168 | 013ba4e lib: sbi: Fix GPA passed to __sbi_hfence_gvma_xyz() functions | ||
169 | 0979ffd lib: utils/gpio: use list for drivers | ||
170 | 2fe2f55 lib: sbi: move sbi_boot_print_general() | ||
171 | 57f094e platform: generic: move fdt_reset_init to final_init | ||
172 | be245ac lib: sbi: error handling in fdt_reset_init() | ||
173 | a74daf2 riscv: Add new CSRs introduced by Sscofpmf[1] extension | ||
174 | 7084ad9 lib: sbi: Update csr_read/write_num for PMU | ||
175 | 867c653 lib: sbi: Detect Sscofpmf extension at run time | ||
176 | 9134c36 lib: sbi: Delegate PMU counter overflow interrupt to S mode | ||
177 | 730f01b lib: sbi: Support sscofpmf extension in OpenSBI | ||
178 | 2363f95 lib: sbi: Always enable access for all counters | ||
179 | 0c304b6 lib: sbi: Allow programmable counters to monitor cycle/instret events | ||
180 | 1e14732 lib: sbi: Reset the mhpmevent value upon counter reset | ||
181 | b628cfd lib: sbi: Counter info width should be zero indexed | ||
182 | b28f070 lib: sbi: Enable PMU extension for platforms without mcountinhibit | ||
183 | 15906a3 lib: utils: Rename the prefix in PMU DT properties | ||
184 | b8845e4 lib: sbi: Fix initial value mask while updating the counters | ||
185 | 31fe5a7 lib: sbi: Fix PMP address bits detection | ||
186 | 94eba23 lib: utils/reset: add priority to gpio reset | ||
187 | 1d462e0 lib: utils/reset: separate driver init func | ||
188 | 2c964a2 lib: utils/i2c: Add generic I2C configuration library | ||
189 | 6ca6bca lib: utils/i2c: Add simple FDT based I2C framework | ||
190 | 13a1158 lib: utils/i2c: Add minimal SiFive I2C driver | ||
191 | f374496 platform: sifive_fu740: add platform reset driver | ||
192 | d335a17 lib: sbi: clear pmpcfg.A before setting in pmp_set() | ||
193 | 52af6e4 lib: utils: Add LiteX UART support | ||
194 | 22d556d lib: sbi: Fix spelling of "address" in sbi_domain.c | ||
195 | 7a22c78 lib: sbi: Fix missing space | ||
196 | 7e77706 lib: sbi: Resolve the uninitialized complaint in sbi_pmu | ||
197 | 14faee6 lib: sbi: Improve fatal error handling | ||
198 | 2428987 lib: pmu: support the event ID encoded by a bitmap. | ||
199 | 66fbcc0 docs/platform: spike: Enhance Spike examples | ||
200 | 460041c lib: pmu: check SSCOF before masking | ||
201 | 69d7e53 Makefile: Fix -msave-restore compile warning with CLANG-10 (or lower) | ||
202 | d249d65 lib: sbi: Fix compile errors using -Os option | ||
203 | f270359 Makefile: Improve the method to disable -m(no-)save-restore option | ||
204 | 2082153 lib: sbi: simplify pmp_set(), pmp_get() | ||
205 | d30bde3 firmware: Move memcpy/memset mapping to fw_base.S | ||
206 | 48f91ee include: Bump-up version to 1.0 | ||
207 | |||
208 | Signed-off-by: Bin Meng <bmeng.cn@gmail.com> | ||
209 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
210 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
211 | --- | 17 | --- |
212 | .../opensbi-riscv32-generic-fw_dynamic.bin | Bin 78680 -> 108504 bytes | 18 | target/riscv/crypto_helper.c | 17 +++++------------ |
213 | .../opensbi-riscv32-generic-fw_dynamic.elf | Bin 727464 -> 838904 bytes | 19 | 1 file changed, 5 insertions(+), 12 deletions(-) |
214 | .../opensbi-riscv64-generic-fw_dynamic.bin | Bin 75096 -> 105296 bytes | ||
215 | .../opensbi-riscv64-generic-fw_dynamic.elf | Bin 781264 -> 934696 bytes | ||
216 | roms/opensbi | 2 +- | ||
217 | 5 files changed, 1 insertion(+), 1 deletion(-) | ||
218 | 20 | ||
219 | diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | 21 | diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c |
220 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
221 | Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ | 23 | --- a/target/riscv/crypto_helper.c |
222 | diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf b/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | 24 | +++ b/target/riscv/crypto_helper.c |
223 | index XXXXXXX..XXXXXXX 100644 | 25 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum) |
224 | Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf differ | 26 | |
225 | diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | 27 | uint8_t enc_rnum = rnum; |
226 | index XXXXXXX..XXXXXXX 100644 | 28 | uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF; |
227 | Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ | 29 | - uint8_t rcon_ = 0; |
228 | diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf b/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | 30 | - target_ulong result; |
229 | index XXXXXXX..XXXXXXX 100644 | 31 | + AESState t, rc = {}; |
230 | Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf differ | 32 | |
231 | diff --git a/roms/opensbi b/roms/opensbi | 33 | if (enc_rnum != 0xA) { |
232 | index XXXXXXX..XXXXXXX 160000 | 34 | temp = ror32(temp, 8); /* Rotate right by 8 */ |
233 | --- a/roms/opensbi | 35 | - rcon_ = round_consts[enc_rnum]; |
234 | +++ b/roms/opensbi | 36 | + rc.w[0] = rc.w[1] = round_consts[enc_rnum]; |
235 | @@ -1 +1 @@ | 37 | } |
236 | -Subproject commit 234ed8e427f4d92903123199f6590d144e0d9351 | 38 | |
237 | +Subproject commit 48f91ee9c960f048c4a7d1da4447d31e04931e38 | 39 | - temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) | |
40 | - ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) | | ||
41 | - ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) | | ||
42 | - ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0); | ||
43 | + t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp; | ||
44 | + aesenc_SB_SR_AK(&t, &t, &rc, false); | ||
45 | |||
46 | - temp ^= rcon_; | ||
47 | - | ||
48 | - result = ((uint64_t)temp << 32) | temp; | ||
49 | - | ||
50 | - return result; | ||
51 | + return t.d[0]; | ||
52 | } | ||
53 | |||
54 | target_ulong HELPER(aes64im)(target_ulong rs1) | ||
238 | -- | 55 | -- |
239 | 2.31.1 | 56 | 2.41.0 |
240 | 57 | ||
241 | 58 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> |
---|---|---|---|
2 | 2 | ||
3 | riscv_trigger_init() had been called on reset events that can happen | ||
4 | several times for a CPU and it allocated timers for itrigger. If old | ||
5 | timers were present, they were simply overwritten by the new timers, | ||
6 | resulting in a memory leak. | ||
7 | |||
8 | Divide riscv_trigger_init() into two functions, namely | ||
9 | riscv_trigger_realize() and riscv_trigger_reset() and call them in | ||
10 | appropriate timing. The timer allocation will happen only once for a | ||
11 | CPU in riscv_trigger_realize(). | ||
12 | |||
13 | Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled") | ||
14 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
15 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
16 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com> | ||
3 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
4 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
5 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
6 | Message-Id: <20220105213937.1113508-2-alistair.francis@opensource.wdc.com> | ||
7 | --- | 20 | --- |
8 | hw/intc/sifive_plic.c | 18 ++++++++++++++++++ | 21 | target/riscv/debug.h | 3 ++- |
9 | 1 file changed, 18 insertions(+) | 22 | target/riscv/cpu.c | 8 +++++++- |
23 | target/riscv/debug.c | 15 ++++++++++++--- | ||
24 | 3 files changed, 21 insertions(+), 5 deletions(-) | ||
10 | 25 | ||
11 | diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c | 26 | diff --git a/target/riscv/debug.h b/target/riscv/debug.h |
12 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/hw/intc/sifive_plic.c | 28 | --- a/target/riscv/debug.h |
14 | +++ b/hw/intc/sifive_plic.c | 29 | +++ b/target/riscv/debug.h |
15 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sifive_plic_ops = { | 30 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs); |
31 | bool riscv_cpu_debug_check_breakpoint(CPUState *cs); | ||
32 | bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); | ||
33 | |||
34 | -void riscv_trigger_init(CPURISCVState *env); | ||
35 | +void riscv_trigger_realize(CPURISCVState *env); | ||
36 | +void riscv_trigger_reset_hold(CPURISCVState *env); | ||
37 | |||
38 | bool riscv_itrigger_enabled(CPURISCVState *env); | ||
39 | void riscv_itrigger_update_priv(CPURISCVState *env); | ||
40 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/riscv/cpu.c | ||
43 | +++ b/target/riscv/cpu.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj) | ||
45 | |||
46 | #ifndef CONFIG_USER_ONLY | ||
47 | if (cpu->cfg.debug) { | ||
48 | - riscv_trigger_init(env); | ||
49 | + riscv_trigger_reset_hold(env); | ||
16 | } | 50 | } |
17 | }; | 51 | |
18 | 52 | if (kvm_enabled()) { | |
19 | +static void sifive_plic_reset(DeviceState *dev) | 53 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) |
54 | |||
55 | riscv_cpu_register_gdb_regs_for_features(cs); | ||
56 | |||
57 | +#ifndef CONFIG_USER_ONLY | ||
58 | + if (cpu->cfg.debug) { | ||
59 | + riscv_trigger_realize(&cpu->env); | ||
60 | + } | ||
61 | +#endif | ||
62 | + | ||
63 | qemu_init_vcpu(cs); | ||
64 | cpu_reset(cs); | ||
65 | |||
66 | diff --git a/target/riscv/debug.c b/target/riscv/debug.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/target/riscv/debug.c | ||
69 | +++ b/target/riscv/debug.c | ||
70 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) | ||
71 | return false; | ||
72 | } | ||
73 | |||
74 | -void riscv_trigger_init(CPURISCVState *env) | ||
75 | +void riscv_trigger_realize(CPURISCVState *env) | ||
20 | +{ | 76 | +{ |
21 | + SiFivePLICState *s = SIFIVE_PLIC(dev); | ||
22 | + int i; | 77 | + int i; |
23 | + | 78 | + |
24 | + memset(s->source_priority, 0, sizeof(uint32_t) * s->num_sources); | 79 | + for (i = 0; i < RV_MAX_TRIGGERS; i++) { |
25 | + memset(s->target_priority, 0, sizeof(uint32_t) * s->num_addrs); | 80 | + env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, |
26 | + memset(s->pending, 0, sizeof(uint32_t) * s->bitfield_words); | 81 | + riscv_itrigger_timer_cb, env); |
27 | + memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words); | ||
28 | + memset(s->enable, 0, sizeof(uint32_t) * s->num_enables); | ||
29 | + | ||
30 | + for (i = 0; i < s->num_harts; i++) { | ||
31 | + qemu_set_irq(s->m_external_irqs[i], 0); | ||
32 | + qemu_set_irq(s->s_external_irqs[i], 0); | ||
33 | + } | 82 | + } |
34 | +} | 83 | +} |
35 | + | 84 | + |
36 | /* | 85 | +void riscv_trigger_reset_hold(CPURISCVState *env) |
37 | * parse PLIC hart/mode address offset config | ||
38 | * | ||
39 | @@ -XXX,XX +XXX,XX @@ static void sifive_plic_class_init(ObjectClass *klass, void *data) | ||
40 | { | 86 | { |
41 | DeviceClass *dc = DEVICE_CLASS(klass); | 87 | target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0); |
42 | 88 | int i; | |
43 | + dc->reset = sifive_plic_reset; | 89 | @@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env) |
44 | device_class_set_props(dc, sifive_plic_properties); | 90 | env->tdata3[i] = 0; |
45 | dc->realize = sifive_plic_realize; | 91 | env->cpu_breakpoint[i] = NULL; |
46 | dc->vmsd = &vmstate_sifive_plic; | 92 | env->cpu_watchpoint[i] = NULL; |
93 | - env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
94 | - riscv_itrigger_timer_cb, env); | ||
95 | + timer_del(env->itrigger_timer[i]); | ||
96 | } | ||
97 | } | ||
47 | -- | 98 | -- |
48 | 2.31.1 | 99 | 2.41.0 |
49 | 100 | ||
50 | 101 | diff view generated by jsdifflib |
1 | From: Jim Shu <jim.shu@sifive.com> | 1 | From: Leon Schuermann <leons@opentitan.org> |
---|---|---|---|
2 | 2 | ||
3 | It's obvious that PDMA supports 64-bit access of 64-bit registers, and | 3 | When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP |
4 | in previous commit, we confirm that PDMA supports 32-bit access of | 4 | configuration lock bits must not apply. While this behavior is |
5 | both 32/64-bit registers. Thus, we configure 32/64-bit memory access | 5 | implemented for the pmpcfgX CSRs, this bit is not respected for |
6 | of PDMA registers as valid in general. | 6 | changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR |
7 | writes work even on locked regions when the global rule-lock bypass is | ||
8 | enabled. | ||
7 | 9 | ||
8 | Signed-off-by: Jim Shu <jim.shu@sifive.com> | 10 | Signed-off-by: Leon Schuermann <leons@opentitan.org> |
9 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | 11 | Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com> |
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
12 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 13 | Message-ID: <20230829215046.1430463-1-leon@is.currently.online> |
13 | Tested-by: Bin Meng <bmeng.cn@gmail.com> | ||
14 | Message-id: 20220104063408.658169-3-jim.shu@sifive.com | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 15 | --- |
17 | hw/dma/sifive_pdma.c | 4 ++++ | 16 | target/riscv/pmp.c | 4 ++++ |
18 | 1 file changed, 4 insertions(+) | 17 | 1 file changed, 4 insertions(+) |
19 | 18 | ||
20 | diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c | 19 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c |
21 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/hw/dma/sifive_pdma.c | 21 | --- a/target/riscv/pmp.c |
23 | +++ b/hw/dma/sifive_pdma.c | 22 | +++ b/target/riscv/pmp.c |
24 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sifive_pdma_ops = { | 23 | @@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg) |
25 | .impl = { | 24 | */ |
26 | .min_access_size = 4, | 25 | static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index) |
27 | .max_access_size = 8, | 26 | { |
28 | + }, | 27 | + /* mseccfg.RLB is set */ |
29 | + .valid = { | 28 | + if (MSECCFG_RLB_ISSET(env)) { |
30 | + .min_access_size = 4, | 29 | + return 0; |
31 | + .max_access_size = 8, | 30 | + } |
32 | } | 31 | |
33 | }; | 32 | if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) { |
34 | 33 | return 1; | |
35 | -- | 34 | -- |
36 | 2.31.1 | 35 | 2.41.0 |
37 | |||
38 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Tommy Wu <tommy.wu@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | When realising the SoC use error_fatal instead of error_abort as the | 3 | According to the new spec, when vsiselect has a reserved value, attempts |
4 | process can fail and report useful information to the user. | 4 | from M-mode or HS-mode to access vsireg, or from VS-mode to access |
5 | sireg, should preferably raise an illegal instruction exception. | ||
5 | 6 | ||
6 | Currently a user can see this: | 7 | Signed-off-by: Tommy Wu <tommy.wu@sifive.com> |
8 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
9 | Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/csr.c | 7 +++++-- | ||
13 | 1 file changed, 5 insertions(+), 2 deletions(-) | ||
7 | 14 | ||
8 | $ ../qemu/bld/qemu-system-riscv64 -M sifive_u -S -monitor stdio -display none -drive if=pflash | 15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
9 | QEMU 6.1.93 monitor - type 'help' for more information | ||
10 | (qemu) Unexpected error in sifive_u_otp_realize() at ../hw/misc/sifive_u_otp.c:229: | ||
11 | qemu-system-riscv64: OTP drive size < 16K | ||
12 | Aborted (core dumped) | ||
13 | |||
14 | Which this patch addresses | ||
15 | |||
16 | Reported-by: Markus Armbruster <armbru@redhat.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
19 | Reviewed-by: Markus Armbruster <armbru@redhat.com> | ||
20 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
21 | Tested-by: Bin Meng <bmeng.cn@gmail.com> | ||
22 | Message-Id: <20220105213937.1113508-8-alistair.francis@opensource.wdc.com> | ||
23 | --- | ||
24 | hw/riscv/microchip_pfsoc.c | 2 +- | ||
25 | hw/riscv/opentitan.c | 2 +- | ||
26 | hw/riscv/sifive_e.c | 2 +- | ||
27 | hw/riscv/sifive_u.c | 2 +- | ||
28 | 4 files changed, 4 insertions(+), 4 deletions(-) | ||
29 | |||
30 | diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/hw/riscv/microchip_pfsoc.c | 17 | --- a/target/riscv/csr.c |
33 | +++ b/hw/riscv/microchip_pfsoc.c | 18 | +++ b/target/riscv/csr.c |
34 | @@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine) | 19 | @@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen, |
35 | /* Initialize SoC */ | 20 | static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val, |
36 | object_initialize_child(OBJECT(machine), "soc", &s->soc, | 21 | target_ulong new_val, target_ulong wr_mask) |
37 | TYPE_MICROCHIP_PFSOC); | 22 | { |
38 | - qdev_realize(DEVICE(&s->soc), NULL, &error_abort); | 23 | - bool virt; |
39 | + qdev_realize(DEVICE(&s->soc), NULL, &error_fatal); | 24 | + bool virt, isel_reserved; |
40 | 25 | uint8_t *iprio; | |
41 | /* Split RAM into low and high regions using aliases to machine->ram */ | 26 | int ret = -EINVAL; |
42 | mem_low_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size; | 27 | target_ulong priv, isel, vgein; |
43 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | 28 | @@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val, |
44 | index XXXXXXX..XXXXXXX 100644 | 29 | |
45 | --- a/hw/riscv/opentitan.c | 30 | /* Decode register details from CSR number */ |
46 | +++ b/hw/riscv/opentitan.c | 31 | virt = false; |
47 | @@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine) | 32 | + isel_reserved = false; |
48 | /* Initialize SoC */ | 33 | switch (csrno) { |
49 | object_initialize_child(OBJECT(machine), "soc", &s->soc, | 34 | case CSR_MIREG: |
50 | TYPE_RISCV_IBEX_SOC); | 35 | iprio = env->miprio; |
51 | - qdev_realize(DEVICE(&s->soc), NULL, &error_abort); | 36 | @@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val, |
52 | + qdev_realize(DEVICE(&s->soc), NULL, &error_fatal); | 37 | riscv_cpu_mxl_bits(env)), |
53 | 38 | val, new_val, wr_mask); | |
54 | memory_region_add_subregion(sys_mem, | 39 | } |
55 | memmap[IBEX_DEV_RAM].base, machine->ram); | 40 | + } else { |
56 | diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c | 41 | + isel_reserved = true; |
57 | index XXXXXXX..XXXXXXX 100644 | 42 | } |
58 | --- a/hw/riscv/sifive_e.c | 43 | |
59 | +++ b/hw/riscv/sifive_e.c | 44 | done: |
60 | @@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine) | 45 | if (ret) { |
61 | 46 | - return (env->virt_enabled && virt) ? | |
62 | /* Initialize SoC */ | 47 | + return (env->virt_enabled && virt && !isel_reserved) ? |
63 | object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_E_SOC); | 48 | RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; |
64 | - qdev_realize(DEVICE(&s->soc), NULL, &error_abort); | 49 | } |
65 | + qdev_realize(DEVICE(&s->soc), NULL, &error_fatal); | 50 | return RISCV_EXCP_NONE; |
66 | |||
67 | /* Data Tightly Integrated Memory */ | ||
68 | memory_region_add_subregion(sys_mem, | ||
69 | diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c | ||
70 | index XXXXXXX..XXXXXXX 100644 | ||
71 | --- a/hw/riscv/sifive_u.c | ||
72 | +++ b/hw/riscv/sifive_u.c | ||
73 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine) | ||
74 | &error_abort); | ||
75 | object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type, | ||
76 | &error_abort); | ||
77 | - qdev_realize(DEVICE(&s->soc), NULL, &error_abort); | ||
78 | + qdev_realize(DEVICE(&s->soc), NULL, &error_fatal); | ||
79 | |||
80 | /* register RAM */ | ||
81 | memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base, | ||
82 | -- | 51 | -- |
83 | 2.31.1 | 52 | 2.41.0 |
84 | |||
85 | diff view generated by jsdifflib |
1 | From: Nikita Shubin <n.shubin@yadro.com> | 1 | From: Nikita Shubin <n.shubin@yadro.com> |
---|---|---|---|
2 | 2 | ||
3 | As per the privilege specification, any access from S/U mode should fail | 3 | As per ISA: |
4 | if no pmp region is configured and pmp is present, othwerwise access | ||
5 | should succeed. | ||
6 | 4 | ||
7 | Fixes: d102f19a208 (target/riscv/pmp: Raise exception if no PMP entry is configured) | 5 | "For CSRRWI, if rd=x0, then the instruction shall not read the CSR and |
6 | shall not cause any of the side effects that might occur on a CSR read." | ||
7 | |||
8 | trans_csrrwi() and trans_csrrw() call do_csrw() if rd=x0, do_csrw() calls | ||
9 | riscv_csrrw_do64(), via helper_csrw() passing NULL as *ret_value. | ||
10 | |||
8 | Signed-off-by: Nikita Shubin <n.shubin@yadro.com> | 11 | Signed-off-by: Nikita Shubin <n.shubin@yadro.com> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-id: 20211214092659.15709-1-nikita.shubin@maquefel.me | 13 | Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 15 | --- |
13 | target/riscv/op_helper.c | 3 ++- | 16 | target/riscv/csr.c | 24 +++++++++++++++--------- |
14 | 1 file changed, 2 insertions(+), 1 deletion(-) | 17 | 1 file changed, 15 insertions(+), 9 deletions(-) |
15 | 18 | ||
16 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c | 19 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
17 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/op_helper.c | 21 | --- a/target/riscv/csr.c |
19 | +++ b/target/riscv/op_helper.c | 22 | +++ b/target/riscv/csr.c |
20 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb) | 23 | @@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno, |
21 | uint64_t mstatus = env->mstatus; | 24 | target_ulong write_mask) |
22 | target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP); | 25 | { |
23 | 26 | RISCVException ret; | |
24 | - if (!pmp_get_num_rules(env) && (prev_priv != PRV_M)) { | 27 | - target_ulong old_value; |
25 | + if (riscv_feature(env, RISCV_FEATURE_PMP) && | 28 | + target_ulong old_value = 0; |
26 | + !pmp_get_num_rules(env) && (prev_priv != PRV_M)) { | 29 | |
27 | riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); | 30 | /* execute combined read/write operation if it exists */ |
31 | if (csr_ops[csrno].op) { | ||
32 | return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask); | ||
28 | } | 33 | } |
29 | 34 | ||
35 | - /* if no accessor exists then return failure */ | ||
36 | - if (!csr_ops[csrno].read) { | ||
37 | - return RISCV_EXCP_ILLEGAL_INST; | ||
38 | - } | ||
39 | - /* read old value */ | ||
40 | - ret = csr_ops[csrno].read(env, csrno, &old_value); | ||
41 | - if (ret != RISCV_EXCP_NONE) { | ||
42 | - return ret; | ||
43 | + /* | ||
44 | + * ret_value == NULL means that rd=x0 and we're coming from helper_csrw() | ||
45 | + * and we can't throw side effects caused by CSR reads. | ||
46 | + */ | ||
47 | + if (ret_value) { | ||
48 | + /* if no accessor exists then return failure */ | ||
49 | + if (!csr_ops[csrno].read) { | ||
50 | + return RISCV_EXCP_ILLEGAL_INST; | ||
51 | + } | ||
52 | + /* read old value */ | ||
53 | + ret = csr_ops[csrno].read(env, csrno, &old_value); | ||
54 | + if (ret != RISCV_EXCP_NONE) { | ||
55 | + return ret; | ||
56 | + } | ||
57 | } | ||
58 | |||
59 | /* write value if writable and write mask set, otherwise drop writes */ | ||
30 | -- | 60 | -- |
31 | 2.31.1 | 61 | 2.41.0 |
32 | |||
33 | diff view generated by jsdifflib |