1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Alistair Francis <alistair.francis@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1: | 3 | The following changes since commit 212a33d3b0c65ae2583bb1d06cb140cd0890894c: |
4 | 4 | ||
5 | Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100) | 5 | Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2021-12-19 16:36:10 -0800) |
6 | 6 | ||
7 | are available in the Git repository at: | 7 | are available in the Git repository at: |
8 | 8 | ||
9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122 | 9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211220-1 |
10 | 10 | ||
11 | for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3: | 11 | for you to fetch changes up to 7e322a7f23a60b0e181b55ef722fdf390ec4e463: |
12 | 12 | ||
13 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000) | 13 | hw/riscv: Use load address rather than entry point for fw_dynamic next_addr (2021-12-20 14:53:31 +1000) |
14 | 14 | ||
15 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
16 | Seventh RISC-V PR for QEMU 6.2 | 16 | First RISC-V PR for QEMU 7.0 |
17 | 17 | ||
18 | - Deprecate IF_NONE for SiFive OTP | 18 | - Add support for ratified 1.0 Vector extension |
19 | - Don't reset SiFive OTP content | 19 | - Drop support for draft 0.7.1 Vector extension |
20 | - Support Zfhmin and Zfh extensions | ||
21 | - Improve kernel loading for non-Linux platforms | ||
20 | 22 | ||
21 | ---------------------------------------------------------------- | 23 | ---------------------------------------------------------------- |
22 | Philippe Mathieu-Daudé (1): | 24 | Frank Chang (75): |
23 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset | 25 | target/riscv: zfh: add Zfh cpu property |
26 | target/riscv: zfh: implement zfhmin extension | ||
27 | target/riscv: zfh: add Zfhmin cpu property | ||
28 | target/riscv: drop vector 0.7.1 and add 1.0 support | ||
29 | target/riscv: Use FIELD_EX32() to extract wd field | ||
30 | target/riscv: rvv-1.0: set mstatus.SD bit if mstatus.VS is dirty | ||
31 | target/riscv: rvv-1.0: introduce writable misa.v field | ||
32 | target/riscv: rvv-1.0: add translation-time vector context status | ||
33 | target/riscv: rvv-1.0: remove rvv related codes from fcsr registers | ||
34 | target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr registers | ||
35 | target/riscv: rvv-1.0: remove MLEN calculations | ||
36 | target/riscv: rvv-1.0: add fractional LMUL | ||
37 | target/riscv: rvv-1.0: add VMA and VTA | ||
38 | target/riscv: rvv-1.0: update check functions | ||
39 | target/riscv: introduce more imm value modes in translator functions | ||
40 | target/riscv: rvv:1.0: add translation-time nan-box helper function | ||
41 | target/riscv: rvv-1.0: remove amo operations instructions | ||
42 | target/riscv: rvv-1.0: configure instructions | ||
43 | target/riscv: rvv-1.0: stride load and store instructions | ||
44 | target/riscv: rvv-1.0: index load and store instructions | ||
45 | target/riscv: rvv-1.0: fix address index overflow bug of indexed load/store insns | ||
46 | target/riscv: rvv-1.0: fault-only-first unit stride load | ||
47 | target/riscv: rvv-1.0: load/store whole register instructions | ||
48 | target/riscv: rvv-1.0: update vext_max_elems() for load/store insns | ||
49 | target/riscv: rvv-1.0: take fractional LMUL into vector max elements calculation | ||
50 | target/riscv: rvv-1.0: floating-point square-root instruction | ||
51 | target/riscv: rvv-1.0: floating-point classify instructions | ||
52 | target/riscv: rvv-1.0: count population in mask instruction | ||
53 | target/riscv: rvv-1.0: find-first-set mask bit instruction | ||
54 | target/riscv: rvv-1.0: set-X-first mask bit instructions | ||
55 | target/riscv: rvv-1.0: iota instruction | ||
56 | target/riscv: rvv-1.0: element index instruction | ||
57 | target/riscv: rvv-1.0: allow load element with sign-extended | ||
58 | target/riscv: rvv-1.0: register gather instructions | ||
59 | target/riscv: rvv-1.0: integer scalar move instructions | ||
60 | target/riscv: rvv-1.0: floating-point move instruction | ||
61 | target/riscv: rvv-1.0: floating-point scalar move instructions | ||
62 | target/riscv: rvv-1.0: whole register move instructions | ||
63 | target/riscv: rvv-1.0: integer extension instructions | ||
64 | target/riscv: rvv-1.0: single-width averaging add and subtract instructions | ||
65 | target/riscv: rvv-1.0: single-width bit shift instructions | ||
66 | target/riscv: rvv-1.0: integer add-with-carry/subtract-with-borrow | ||
67 | target/riscv: rvv-1.0: narrowing integer right shift instructions | ||
68 | target/riscv: rvv-1.0: widening integer multiply-add instructions | ||
69 | target/riscv: rvv-1.0: single-width saturating add and subtract instructions | ||
70 | target/riscv: rvv-1.0: integer comparison instructions | ||
71 | target/riscv: rvv-1.0: floating-point compare instructions | ||
72 | target/riscv: rvv-1.0: mask-register logical instructions | ||
73 | target/riscv: rvv-1.0: slide instructions | ||
74 | target/riscv: rvv-1.0: floating-point slide instructions | ||
75 | target/riscv: rvv-1.0: narrowing fixed-point clip instructions | ||
76 | target/riscv: rvv-1.0: single-width floating-point reduction | ||
77 | target/riscv: rvv-1.0: widening floating-point reduction instructions | ||
78 | target/riscv: rvv-1.0: single-width scaling shift instructions | ||
79 | target/riscv: rvv-1.0: remove widening saturating scaled multiply-add | ||
80 | target/riscv: rvv-1.0: remove vmford.vv and vmford.vf | ||
81 | target/riscv: rvv-1.0: remove integer extract instruction | ||
82 | target/riscv: rvv-1.0: floating-point min/max instructions | ||
83 | target/riscv: introduce floating-point rounding mode enum | ||
84 | target/riscv: rvv-1.0: floating-point/integer type-convert instructions | ||
85 | target/riscv: rvv-1.0: widening floating-point/integer type-convert | ||
86 | target/riscv: add "set round to odd" rounding mode helper function | ||
87 | target/riscv: rvv-1.0: narrowing floating-point/integer type-convert | ||
88 | target/riscv: rvv-1.0: relax RV_VLEN_MAX to 1024-bits | ||
89 | target/riscv: rvv-1.0: implement vstart CSR | ||
90 | target/riscv: rvv-1.0: trigger illegal instruction exception if frm is not valid | ||
91 | target/riscv: rvv-1.0: floating-point reciprocal square-root estimate instruction | ||
92 | target/riscv: rvv-1.0: floating-point reciprocal estimate instruction | ||
93 | target/riscv: rvv-1.0: rename r2_zimm to r2_zimm11 | ||
94 | target/riscv: rvv-1.0: add vsetivli instruction | ||
95 | target/riscv: rvv-1.0: add evl parameter to vext_ldst_us() | ||
96 | target/riscv: rvv-1.0: add vector unit-stride mask load/store insns | ||
97 | target/riscv: rvv-1.0: rename vmandnot.mm and vmornot.mm to vmandn.mm and vmorn.mm | ||
98 | target/riscv: rvv-1.0: update opivv_vadc_check() comment | ||
99 | target/riscv: rvv-1.0: Add ELEN checks for widening and narrowing instructions | ||
24 | 100 | ||
25 | Thomas Huth (1): | 101 | Greentime Hu (1): |
26 | hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE | 102 | target/riscv: rvv-1.0: add vlenb register |
27 | 103 | ||
28 | docs/about/deprecated.rst | 6 ++++++ | 104 | Hsiangkai Wang (1): |
29 | hw/misc/sifive_u_otp.c | 22 +++++++++++++--------- | 105 | target/riscv: gdb: support vector registers for rv64 & rv32 |
30 | 2 files changed, 19 insertions(+), 9 deletions(-) | ||
31 | 106 | ||
107 | Jessica Clarke (1): | ||
108 | hw/riscv: Use load address rather than entry point for fw_dynamic next_addr | ||
109 | |||
110 | Khem Raj (1): | ||
111 | riscv: Set 5.4 as minimum kernel version for riscv32 | ||
112 | |||
113 | Kito Cheng (5): | ||
114 | target/riscv: zfh: half-precision load and store | ||
115 | target/riscv: zfh: half-precision computational | ||
116 | target/riscv: zfh: half-precision convert and move | ||
117 | target/riscv: zfh: half-precision floating-point compare | ||
118 | target/riscv: zfh: half-precision floating-point classify | ||
119 | |||
120 | LIU Zhiwei (3): | ||
121 | target/riscv: rvv-1.0: add mstatus VS field | ||
122 | target/riscv: rvv-1.0: add sstatus VS field | ||
123 | target/riscv: rvv-1.0: add vcsr register | ||
124 | |||
125 | Vineet Gupta (1): | ||
126 | target/riscv: Enable bitmanip Zb[abcs] instructions | ||
127 | |||
128 | linux-user/riscv/target_syscall.h | 3 +- | ||
129 | target/riscv/cpu.h | 63 +- | ||
130 | target/riscv/cpu_bits.h | 10 + | ||
131 | target/riscv/helper.h | 464 ++-- | ||
132 | target/riscv/internals.h | 40 +- | ||
133 | target/riscv/insn32.decode | 332 +-- | ||
134 | hw/riscv/boot.c | 13 +- | ||
135 | target/riscv/cpu.c | 28 +- | ||
136 | target/riscv/cpu_helper.c | 39 +- | ||
137 | target/riscv/csr.c | 63 +- | ||
138 | target/riscv/fpu_helper.c | 197 +- | ||
139 | target/riscv/gdbstub.c | 184 ++ | ||
140 | target/riscv/translate.c | 93 +- | ||
141 | target/riscv/vector_helper.c | 3601 +++++++++++++++-------------- | ||
142 | target/riscv/insn_trans/trans_rvv.c.inc | 2429 ++++++++++++------- | ||
143 | target/riscv/insn_trans/trans_rvzfh.c.inc | 537 +++++ | ||
144 | 16 files changed, 4997 insertions(+), 3099 deletions(-) | ||
145 | create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc | ||
146 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Kito Cheng <kito.cheng@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Kito Cheng <kito.cheng@sifive.com> | ||
4 | Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Message-id: 20211210074329.5775-2-frank.chang@sifive.com | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 1 + | ||
11 | target/riscv/insn32.decode | 4 ++ | ||
12 | target/riscv/translate.c | 8 +++ | ||
13 | target/riscv/insn_trans/trans_rvzfh.c.inc | 65 +++++++++++++++++++++++ | ||
14 | 4 files changed, 78 insertions(+) | ||
15 | create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc | ||
16 | |||
17 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.h | ||
20 | +++ b/target/riscv/cpu.h | ||
21 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPU { | ||
22 | bool ext_counters; | ||
23 | bool ext_ifencei; | ||
24 | bool ext_icsr; | ||
25 | + bool ext_zfh; | ||
26 | |||
27 | char *priv_spec; | ||
28 | char *user_spec; | ||
29 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/insn32.decode | ||
32 | +++ b/target/riscv/insn32.decode | ||
33 | @@ -XXX,XX +XXX,XX @@ binv 0110100 .......... 001 ..... 0110011 @r | ||
34 | binvi 01101. ........... 001 ..... 0010011 @sh | ||
35 | bset 0010100 .......... 001 ..... 0110011 @r | ||
36 | bseti 00101. ........... 001 ..... 0010011 @sh | ||
37 | + | ||
38 | +# *** RV32 Zfh Extension *** | ||
39 | +flh ............ ..... 001 ..... 0000111 @i | ||
40 | +fsh ....... ..... ..... 001 ..... 0100111 @s | ||
41 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/target/riscv/translate.c | ||
44 | +++ b/target/riscv/translate.c | ||
45 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
46 | RISCVMXL ol; | ||
47 | bool virt_enabled; | ||
48 | bool ext_ifencei; | ||
49 | + bool ext_zfh; | ||
50 | bool hlsx; | ||
51 | /* vector extension */ | ||
52 | bool vill; | ||
53 | @@ -XXX,XX +XXX,XX @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in) | ||
54 | tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32)); | ||
55 | } | ||
56 | |||
57 | +static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in) | ||
58 | +{ | ||
59 | + tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48)); | ||
60 | +} | ||
61 | + | ||
62 | /* | ||
63 | * A narrow n-bit operation, where n < FLEN, checks that input operands | ||
64 | * are correctly Nan-boxed, i.e., all upper FLEN - n bits are 1. | ||
65 | @@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) | ||
66 | #include "insn_trans/trans_rvh.c.inc" | ||
67 | #include "insn_trans/trans_rvv.c.inc" | ||
68 | #include "insn_trans/trans_rvb.c.inc" | ||
69 | +#include "insn_trans/trans_rvzfh.c.inc" | ||
70 | #include "insn_trans/trans_privileged.c.inc" | ||
71 | |||
72 | /* Include the auto-generated decoder for 16 bit insn */ | ||
73 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
74 | ctx->misa_ext = env->misa_ext; | ||
75 | ctx->frm = -1; /* unknown rounding mode */ | ||
76 | ctx->ext_ifencei = cpu->cfg.ext_ifencei; | ||
77 | + ctx->ext_zfh = cpu->cfg.ext_zfh; | ||
78 | ctx->vlen = cpu->cfg.vlen; | ||
79 | ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS); | ||
80 | ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); | ||
81 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
82 | new file mode 100644 | ||
83 | index XXXXXXX..XXXXXXX | ||
84 | --- /dev/null | ||
85 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
86 | @@ -XXX,XX +XXX,XX @@ | ||
87 | +/* | ||
88 | + * RISC-V translation routines for the RV64Zfh Standard Extension. | ||
89 | + * | ||
90 | + * Copyright (c) 2020 Chih-Min Chao, chihmin.chao@sifive.com | ||
91 | + * | ||
92 | + * This program is free software; you can redistribute it and/or modify it | ||
93 | + * under the terms and conditions of the GNU General Public License, | ||
94 | + * version 2 or later, as published by the Free Software Foundation. | ||
95 | + * | ||
96 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
97 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
98 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
99 | + * more details. | ||
100 | + * | ||
101 | + * You should have received a copy of the GNU General Public License along with | ||
102 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
103 | + */ | ||
104 | + | ||
105 | +#define REQUIRE_ZFH(ctx) do { \ | ||
106 | + if (!ctx->ext_zfh) { \ | ||
107 | + return false; \ | ||
108 | + } \ | ||
109 | +} while (0) | ||
110 | + | ||
111 | +static bool trans_flh(DisasContext *ctx, arg_flh *a) | ||
112 | +{ | ||
113 | + TCGv_i64 dest; | ||
114 | + TCGv t0; | ||
115 | + | ||
116 | + REQUIRE_FPU; | ||
117 | + REQUIRE_ZFH(ctx); | ||
118 | + | ||
119 | + t0 = get_gpr(ctx, a->rs1, EXT_NONE); | ||
120 | + if (a->imm) { | ||
121 | + TCGv temp = temp_new(ctx); | ||
122 | + tcg_gen_addi_tl(temp, t0, a->imm); | ||
123 | + t0 = temp; | ||
124 | + } | ||
125 | + | ||
126 | + dest = cpu_fpr[a->rd]; | ||
127 | + tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TEUW); | ||
128 | + gen_nanbox_h(dest, dest); | ||
129 | + | ||
130 | + mark_fs_dirty(ctx); | ||
131 | + return true; | ||
132 | +} | ||
133 | + | ||
134 | +static bool trans_fsh(DisasContext *ctx, arg_fsh *a) | ||
135 | +{ | ||
136 | + TCGv t0; | ||
137 | + | ||
138 | + REQUIRE_FPU; | ||
139 | + REQUIRE_ZFH(ctx); | ||
140 | + | ||
141 | + t0 = get_gpr(ctx, a->rs1, EXT_NONE); | ||
142 | + if (a->imm) { | ||
143 | + TCGv temp = tcg_temp_new(); | ||
144 | + tcg_gen_addi_tl(temp, t0, a->imm); | ||
145 | + t0 = temp; | ||
146 | + } | ||
147 | + | ||
148 | + tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW); | ||
149 | + | ||
150 | + return true; | ||
151 | +} | ||
152 | -- | ||
153 | 2.31.1 | ||
154 | |||
155 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Kito Cheng <kito.cheng@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Kito Cheng <kito.cheng@sifive.com> | ||
4 | Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-id: 20211210074329.5775-3-frank.chang@sifive.com | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/helper.h | 13 +++ | ||
12 | target/riscv/internals.h | 16 +++ | ||
13 | target/riscv/insn32.decode | 11 ++ | ||
14 | target/riscv/fpu_helper.c | 86 +++++++++++++++ | ||
15 | target/riscv/insn_trans/trans_rvzfh.c.inc | 129 ++++++++++++++++++++++ | ||
16 | 5 files changed, 255 insertions(+) | ||
17 | |||
18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/helper.h | ||
21 | +++ b/target/riscv/helper.h | ||
22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32) | ||
23 | /* Floating Point - fused */ | ||
24 | DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
25 | DEF_HELPER_FLAGS_4(fmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
26 | +DEF_HELPER_FLAGS_4(fmadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
27 | DEF_HELPER_FLAGS_4(fmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
28 | DEF_HELPER_FLAGS_4(fmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
29 | +DEF_HELPER_FLAGS_4(fmsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
30 | DEF_HELPER_FLAGS_4(fnmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
31 | DEF_HELPER_FLAGS_4(fnmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
32 | +DEF_HELPER_FLAGS_4(fnmsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
33 | DEF_HELPER_FLAGS_4(fnmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
34 | DEF_HELPER_FLAGS_4(fnmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
35 | +DEF_HELPER_FLAGS_4(fnmadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
36 | |||
37 | /* Floating Point - Single Precision */ | ||
38 | DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
39 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64) | ||
40 | DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
41 | DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
42 | |||
43 | +/* Floating Point - Half Precision */ | ||
44 | +DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
45 | +DEF_HELPER_FLAGS_3(fsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
46 | +DEF_HELPER_FLAGS_3(fmul_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
47 | +DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
48 | +DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
49 | +DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
50 | +DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
51 | + | ||
52 | /* Special functions */ | ||
53 | DEF_HELPER_2(csrr, tl, env, int) | ||
54 | DEF_HELPER_3(csrw, void, env, int, tl) | ||
55 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/target/riscv/internals.h | ||
58 | +++ b/target/riscv/internals.h | ||
59 | @@ -XXX,XX +XXX,XX @@ static inline float32 check_nanbox_s(uint64_t f) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | +static inline uint64_t nanbox_h(float16 f) | ||
64 | +{ | ||
65 | + return f | MAKE_64BIT_MASK(16, 48); | ||
66 | +} | ||
67 | + | ||
68 | +static inline float16 check_nanbox_h(uint64_t f) | ||
69 | +{ | ||
70 | + uint64_t mask = MAKE_64BIT_MASK(16, 48); | ||
71 | + | ||
72 | + if (likely((f & mask) == mask)) { | ||
73 | + return (uint16_t)f; | ||
74 | + } else { | ||
75 | + return 0x7E00u; /* default qnan */ | ||
76 | + } | ||
77 | +} | ||
78 | + | ||
79 | #endif | ||
80 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/target/riscv/insn32.decode | ||
83 | +++ b/target/riscv/insn32.decode | ||
84 | @@ -XXX,XX +XXX,XX @@ bseti 00101. ........... 001 ..... 0010011 @sh | ||
85 | # *** RV32 Zfh Extension *** | ||
86 | flh ............ ..... 001 ..... 0000111 @i | ||
87 | fsh ....... ..... ..... 001 ..... 0100111 @s | ||
88 | +fmadd_h ..... 10 ..... ..... ... ..... 1000011 @r4_rm | ||
89 | +fmsub_h ..... 10 ..... ..... ... ..... 1000111 @r4_rm | ||
90 | +fnmsub_h ..... 10 ..... ..... ... ..... 1001011 @r4_rm | ||
91 | +fnmadd_h ..... 10 ..... ..... ... ..... 1001111 @r4_rm | ||
92 | +fadd_h 0000010 ..... ..... ... ..... 1010011 @r_rm | ||
93 | +fsub_h 0000110 ..... ..... ... ..... 1010011 @r_rm | ||
94 | +fmul_h 0001010 ..... ..... ... ..... 1010011 @r_rm | ||
95 | +fdiv_h 0001110 ..... ..... ... ..... 1010011 @r_rm | ||
96 | +fsqrt_h 0101110 00000 ..... ... ..... 1010011 @r2_rm | ||
97 | +fmin_h 0010110 ..... ..... 000 ..... 1010011 @r | ||
98 | +fmax_h 0010110 ..... ..... 001 ..... 1010011 @r | ||
99 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/target/riscv/fpu_helper.c | ||
102 | +++ b/target/riscv/fpu_helper.c | ||
103 | @@ -XXX,XX +XXX,XX @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) | ||
104 | set_float_rounding_mode(softrm, &env->fp_status); | ||
105 | } | ||
106 | |||
107 | +static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2, | ||
108 | + uint64_t rs3, int flags) | ||
109 | +{ | ||
110 | + float16 frs1 = check_nanbox_h(rs1); | ||
111 | + float16 frs2 = check_nanbox_h(rs2); | ||
112 | + float16 frs3 = check_nanbox_h(rs3); | ||
113 | + return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, &env->fp_status)); | ||
114 | +} | ||
115 | + | ||
116 | static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2, | ||
117 | uint64_t rs3, int flags) | ||
118 | { | ||
119 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
120 | return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status); | ||
121 | } | ||
122 | |||
123 | +uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
124 | + uint64_t frs3) | ||
125 | +{ | ||
126 | + return do_fmadd_h(env, frs1, frs2, frs3, 0); | ||
127 | +} | ||
128 | + | ||
129 | uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
130 | uint64_t frs3) | ||
131 | { | ||
132 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
133 | &env->fp_status); | ||
134 | } | ||
135 | |||
136 | +uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
137 | + uint64_t frs3) | ||
138 | +{ | ||
139 | + return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c); | ||
140 | +} | ||
141 | + | ||
142 | uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
143 | uint64_t frs3) | ||
144 | { | ||
145 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
146 | &env->fp_status); | ||
147 | } | ||
148 | |||
149 | +uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
150 | + uint64_t frs3) | ||
151 | +{ | ||
152 | + return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product); | ||
153 | +} | ||
154 | + | ||
155 | uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
156 | uint64_t frs3) | ||
157 | { | ||
158 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
159 | float_muladd_negate_product, &env->fp_status); | ||
160 | } | ||
161 | |||
162 | +uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2, | ||
163 | + uint64_t frs3) | ||
164 | +{ | ||
165 | + return do_fmadd_h(env, frs1, frs2, frs3, | ||
166 | + float_muladd_negate_c | float_muladd_negate_product); | ||
167 | +} | ||
168 | + | ||
169 | uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
170 | { | ||
171 | float32 frs1 = check_nanbox_s(rs1); | ||
172 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_fclass_d(uint64_t frs1) | ||
173 | { | ||
174 | return fclass_d(frs1); | ||
175 | } | ||
176 | + | ||
177 | +uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
178 | +{ | ||
179 | + float16 frs1 = check_nanbox_h(rs1); | ||
180 | + float16 frs2 = check_nanbox_h(rs2); | ||
181 | + return nanbox_h(float16_add(frs1, frs2, &env->fp_status)); | ||
182 | +} | ||
183 | + | ||
184 | +uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
185 | +{ | ||
186 | + float16 frs1 = check_nanbox_h(rs1); | ||
187 | + float16 frs2 = check_nanbox_h(rs2); | ||
188 | + return nanbox_h(float16_sub(frs1, frs2, &env->fp_status)); | ||
189 | +} | ||
190 | + | ||
191 | +uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
192 | +{ | ||
193 | + float16 frs1 = check_nanbox_h(rs1); | ||
194 | + float16 frs2 = check_nanbox_h(rs2); | ||
195 | + return nanbox_h(float16_mul(frs1, frs2, &env->fp_status)); | ||
196 | +} | ||
197 | + | ||
198 | +uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
199 | +{ | ||
200 | + float16 frs1 = check_nanbox_h(rs1); | ||
201 | + float16 frs2 = check_nanbox_h(rs2); | ||
202 | + return nanbox_h(float16_div(frs1, frs2, &env->fp_status)); | ||
203 | +} | ||
204 | + | ||
205 | +uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
206 | +{ | ||
207 | + float16 frs1 = check_nanbox_h(rs1); | ||
208 | + float16 frs2 = check_nanbox_h(rs2); | ||
209 | + return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ? | ||
210 | + float16_minnum(frs1, frs2, &env->fp_status) : | ||
211 | + float16_minimum_number(frs1, frs2, &env->fp_status)); | ||
212 | +} | ||
213 | + | ||
214 | +uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
215 | +{ | ||
216 | + float16 frs1 = check_nanbox_h(rs1); | ||
217 | + float16 frs2 = check_nanbox_h(rs2); | ||
218 | + return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ? | ||
219 | + float16_maxnum(frs1, frs2, &env->fp_status) : | ||
220 | + float16_maximum_number(frs1, frs2, &env->fp_status)); | ||
221 | +} | ||
222 | + | ||
223 | +uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1) | ||
224 | +{ | ||
225 | + float16 frs1 = check_nanbox_h(rs1); | ||
226 | + return nanbox_h(float16_sqrt(frs1, &env->fp_status)); | ||
227 | +} | ||
228 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
229 | index XXXXXXX..XXXXXXX 100644 | ||
230 | --- a/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
231 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
232 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) | ||
233 | |||
234 | return true; | ||
235 | } | ||
236 | + | ||
237 | +static bool trans_fmadd_h(DisasContext *ctx, arg_fmadd_h *a) | ||
238 | +{ | ||
239 | + REQUIRE_FPU; | ||
240 | + REQUIRE_ZFH(ctx); | ||
241 | + | ||
242 | + gen_set_rm(ctx, a->rm); | ||
243 | + gen_helper_fmadd_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
244 | + cpu_fpr[a->rs2], cpu_fpr[a->rs3]); | ||
245 | + mark_fs_dirty(ctx); | ||
246 | + return true; | ||
247 | +} | ||
248 | + | ||
249 | +static bool trans_fmsub_h(DisasContext *ctx, arg_fmsub_h *a) | ||
250 | +{ | ||
251 | + REQUIRE_FPU; | ||
252 | + REQUIRE_ZFH(ctx); | ||
253 | + | ||
254 | + gen_set_rm(ctx, a->rm); | ||
255 | + gen_helper_fmsub_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
256 | + cpu_fpr[a->rs2], cpu_fpr[a->rs3]); | ||
257 | + mark_fs_dirty(ctx); | ||
258 | + return true; | ||
259 | +} | ||
260 | + | ||
261 | +static bool trans_fnmsub_h(DisasContext *ctx, arg_fnmsub_h *a) | ||
262 | +{ | ||
263 | + REQUIRE_FPU; | ||
264 | + REQUIRE_ZFH(ctx); | ||
265 | + | ||
266 | + gen_set_rm(ctx, a->rm); | ||
267 | + gen_helper_fnmsub_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
268 | + cpu_fpr[a->rs2], cpu_fpr[a->rs3]); | ||
269 | + mark_fs_dirty(ctx); | ||
270 | + return true; | ||
271 | +} | ||
272 | + | ||
273 | +static bool trans_fnmadd_h(DisasContext *ctx, arg_fnmadd_h *a) | ||
274 | +{ | ||
275 | + REQUIRE_FPU; | ||
276 | + REQUIRE_ZFH(ctx); | ||
277 | + | ||
278 | + gen_set_rm(ctx, a->rm); | ||
279 | + gen_helper_fnmadd_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
280 | + cpu_fpr[a->rs2], cpu_fpr[a->rs3]); | ||
281 | + mark_fs_dirty(ctx); | ||
282 | + return true; | ||
283 | +} | ||
284 | + | ||
285 | +static bool trans_fadd_h(DisasContext *ctx, arg_fadd_h *a) | ||
286 | +{ | ||
287 | + REQUIRE_FPU; | ||
288 | + REQUIRE_ZFH(ctx); | ||
289 | + | ||
290 | + gen_set_rm(ctx, a->rm); | ||
291 | + gen_helper_fadd_h(cpu_fpr[a->rd], cpu_env, | ||
292 | + cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
293 | + mark_fs_dirty(ctx); | ||
294 | + return true; | ||
295 | +} | ||
296 | + | ||
297 | +static bool trans_fsub_h(DisasContext *ctx, arg_fsub_h *a) | ||
298 | +{ | ||
299 | + REQUIRE_FPU; | ||
300 | + REQUIRE_ZFH(ctx); | ||
301 | + | ||
302 | + gen_set_rm(ctx, a->rm); | ||
303 | + gen_helper_fsub_h(cpu_fpr[a->rd], cpu_env, | ||
304 | + cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
305 | + mark_fs_dirty(ctx); | ||
306 | + return true; | ||
307 | +} | ||
308 | + | ||
309 | +static bool trans_fmul_h(DisasContext *ctx, arg_fmul_h *a) | ||
310 | +{ | ||
311 | + REQUIRE_FPU; | ||
312 | + REQUIRE_ZFH(ctx); | ||
313 | + | ||
314 | + gen_set_rm(ctx, a->rm); | ||
315 | + gen_helper_fmul_h(cpu_fpr[a->rd], cpu_env, | ||
316 | + cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
317 | + mark_fs_dirty(ctx); | ||
318 | + return true; | ||
319 | +} | ||
320 | + | ||
321 | +static bool trans_fdiv_h(DisasContext *ctx, arg_fdiv_h *a) | ||
322 | +{ | ||
323 | + REQUIRE_FPU; | ||
324 | + REQUIRE_ZFH(ctx); | ||
325 | + | ||
326 | + gen_set_rm(ctx, a->rm); | ||
327 | + gen_helper_fdiv_h(cpu_fpr[a->rd], cpu_env, | ||
328 | + cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
329 | + mark_fs_dirty(ctx); | ||
330 | + return true; | ||
331 | +} | ||
332 | + | ||
333 | +static bool trans_fsqrt_h(DisasContext *ctx, arg_fsqrt_h *a) | ||
334 | +{ | ||
335 | + REQUIRE_FPU; | ||
336 | + REQUIRE_ZFH(ctx); | ||
337 | + | ||
338 | + gen_set_rm(ctx, a->rm); | ||
339 | + gen_helper_fsqrt_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
340 | + mark_fs_dirty(ctx); | ||
341 | + return true; | ||
342 | +} | ||
343 | + | ||
344 | +static bool trans_fmin_h(DisasContext *ctx, arg_fmin_h *a) | ||
345 | +{ | ||
346 | + REQUIRE_FPU; | ||
347 | + REQUIRE_ZFH(ctx); | ||
348 | + | ||
349 | + gen_helper_fmin_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
350 | + cpu_fpr[a->rs2]); | ||
351 | + mark_fs_dirty(ctx); | ||
352 | + return true; | ||
353 | +} | ||
354 | + | ||
355 | +static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a) | ||
356 | +{ | ||
357 | + REQUIRE_FPU; | ||
358 | + REQUIRE_ZFH(ctx); | ||
359 | + | ||
360 | + gen_helper_fmax_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1], | ||
361 | + cpu_fpr[a->rs2]); | ||
362 | + mark_fs_dirty(ctx); | ||
363 | + return true; | ||
364 | +} | ||
365 | -- | ||
366 | 2.31.1 | ||
367 | |||
368 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Kito Cheng <kito.cheng@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Kito Cheng <kito.cheng@sifive.com> | ||
4 | Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-id: 20211210074329.5775-4-frank.chang@sifive.com | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/helper.h | 12 + | ||
12 | target/riscv/insn32.decode | 19 ++ | ||
13 | target/riscv/fpu_helper.c | 67 +++++ | ||
14 | target/riscv/translate.c | 10 + | ||
15 | target/riscv/insn_trans/trans_rvzfh.c.inc | 288 ++++++++++++++++++++++ | ||
16 | 5 files changed, 396 insertions(+) | ||
17 | |||
18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/helper.h | ||
21 | +++ b/target/riscv/helper.h | ||
22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
23 | DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
24 | DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
25 | DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
26 | +DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
27 | +DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64) | ||
28 | +DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
29 | +DEF_HELPER_FLAGS_2(fcvt_h_d, TCG_CALL_NO_RWG, i64, env, i64) | ||
30 | +DEF_HELPER_FLAGS_2(fcvt_w_h, TCG_CALL_NO_RWG, tl, env, i64) | ||
31 | +DEF_HELPER_FLAGS_2(fcvt_wu_h, TCG_CALL_NO_RWG, tl, env, i64) | ||
32 | +DEF_HELPER_FLAGS_2(fcvt_l_h, TCG_CALL_NO_RWG, tl, env, i64) | ||
33 | +DEF_HELPER_FLAGS_2(fcvt_lu_h, TCG_CALL_NO_RWG, tl, env, i64) | ||
34 | +DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl) | ||
35 | +DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl) | ||
36 | +DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl) | ||
37 | +DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl) | ||
38 | |||
39 | /* Special functions */ | ||
40 | DEF_HELPER_2(csrr, tl, env, int) | ||
41 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/target/riscv/insn32.decode | ||
44 | +++ b/target/riscv/insn32.decode | ||
45 | @@ -XXX,XX +XXX,XX @@ fsub_h 0000110 ..... ..... ... ..... 1010011 @r_rm | ||
46 | fmul_h 0001010 ..... ..... ... ..... 1010011 @r_rm | ||
47 | fdiv_h 0001110 ..... ..... ... ..... 1010011 @r_rm | ||
48 | fsqrt_h 0101110 00000 ..... ... ..... 1010011 @r2_rm | ||
49 | +fsgnj_h 0010010 ..... ..... 000 ..... 1010011 @r | ||
50 | +fsgnjn_h 0010010 ..... ..... 001 ..... 1010011 @r | ||
51 | +fsgnjx_h 0010010 ..... ..... 010 ..... 1010011 @r | ||
52 | fmin_h 0010110 ..... ..... 000 ..... 1010011 @r | ||
53 | fmax_h 0010110 ..... ..... 001 ..... 1010011 @r | ||
54 | +fcvt_h_s 0100010 00000 ..... ... ..... 1010011 @r2_rm | ||
55 | +fcvt_s_h 0100000 00010 ..... ... ..... 1010011 @r2_rm | ||
56 | +fcvt_h_d 0100010 00001 ..... ... ..... 1010011 @r2_rm | ||
57 | +fcvt_d_h 0100001 00010 ..... ... ..... 1010011 @r2_rm | ||
58 | +fcvt_w_h 1100010 00000 ..... ... ..... 1010011 @r2_rm | ||
59 | +fcvt_wu_h 1100010 00001 ..... ... ..... 1010011 @r2_rm | ||
60 | +fmv_x_h 1110010 00000 ..... 000 ..... 1010011 @r2 | ||
61 | +fcvt_h_w 1101010 00000 ..... ... ..... 1010011 @r2_rm | ||
62 | +fcvt_h_wu 1101010 00001 ..... ... ..... 1010011 @r2_rm | ||
63 | +fmv_h_x 1111010 00000 ..... 000 ..... 1010011 @r2 | ||
64 | + | ||
65 | +# *** RV64 Zfh Extension (in addition to RV32 Zfh) *** | ||
66 | +fcvt_l_h 1100010 00010 ..... ... ..... 1010011 @r2_rm | ||
67 | +fcvt_lu_h 1100010 00011 ..... ... ..... 1010011 @r2_rm | ||
68 | +fcvt_h_l 1101010 00010 ..... ... ..... 1010011 @r2_rm | ||
69 | +fcvt_h_lu 1101010 00011 ..... ... ..... 1010011 @r2_rm | ||
70 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
71 | index XXXXXXX..XXXXXXX 100644 | ||
72 | --- a/target/riscv/fpu_helper.c | ||
73 | +++ b/target/riscv/fpu_helper.c | ||
74 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1) | ||
75 | float16 frs1 = check_nanbox_h(rs1); | ||
76 | return nanbox_h(float16_sqrt(frs1, &env->fp_status)); | ||
77 | } | ||
78 | + | ||
79 | +target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1) | ||
80 | +{ | ||
81 | + float16 frs1 = check_nanbox_h(rs1); | ||
82 | + return float16_to_int32(frs1, &env->fp_status); | ||
83 | +} | ||
84 | + | ||
85 | +target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1) | ||
86 | +{ | ||
87 | + float16 frs1 = check_nanbox_h(rs1); | ||
88 | + return (int32_t)float16_to_uint32(frs1, &env->fp_status); | ||
89 | +} | ||
90 | + | ||
91 | +target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1) | ||
92 | +{ | ||
93 | + float16 frs1 = check_nanbox_h(rs1); | ||
94 | + return float16_to_int64(frs1, &env->fp_status); | ||
95 | +} | ||
96 | + | ||
97 | +target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1) | ||
98 | +{ | ||
99 | + float16 frs1 = check_nanbox_h(rs1); | ||
100 | + return float16_to_uint64(frs1, &env->fp_status); | ||
101 | +} | ||
102 | + | ||
103 | +uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1) | ||
104 | +{ | ||
105 | + return nanbox_h(int32_to_float16((int32_t)rs1, &env->fp_status)); | ||
106 | +} | ||
107 | + | ||
108 | +uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1) | ||
109 | +{ | ||
110 | + return nanbox_h(uint32_to_float16((uint32_t)rs1, &env->fp_status)); | ||
111 | +} | ||
112 | + | ||
113 | +uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1) | ||
114 | +{ | ||
115 | + return nanbox_h(int64_to_float16(rs1, &env->fp_status)); | ||
116 | +} | ||
117 | + | ||
118 | +uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1) | ||
119 | +{ | ||
120 | + return nanbox_h(uint64_to_float16(rs1, &env->fp_status)); | ||
121 | +} | ||
122 | + | ||
123 | +uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1) | ||
124 | +{ | ||
125 | + float32 frs1 = check_nanbox_s(rs1); | ||
126 | + return nanbox_h(float32_to_float16(frs1, true, &env->fp_status)); | ||
127 | +} | ||
128 | + | ||
129 | +uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1) | ||
130 | +{ | ||
131 | + float16 frs1 = check_nanbox_h(rs1); | ||
132 | + return nanbox_s(float16_to_float32(frs1, true, &env->fp_status)); | ||
133 | +} | ||
134 | + | ||
135 | +uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1) | ||
136 | +{ | ||
137 | + return nanbox_h(float64_to_float16(rs1, true, &env->fp_status)); | ||
138 | +} | ||
139 | + | ||
140 | +uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1) | ||
141 | +{ | ||
142 | + float16 frs1 = check_nanbox_h(rs1); | ||
143 | + return float16_to_float64(frs1, true, &env->fp_status); | ||
144 | +} | ||
145 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
146 | index XXXXXXX..XXXXXXX 100644 | ||
147 | --- a/target/riscv/translate.c | ||
148 | +++ b/target/riscv/translate.c | ||
149 | @@ -XXX,XX +XXX,XX @@ static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in) | ||
150 | * | ||
151 | * Here, the result is always nan-boxed, even the canonical nan. | ||
152 | */ | ||
153 | +static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in) | ||
154 | +{ | ||
155 | + TCGv_i64 t_max = tcg_const_i64(0xffffffffffff0000ull); | ||
156 | + TCGv_i64 t_nan = tcg_const_i64(0xffffffffffff7e00ull); | ||
157 | + | ||
158 | + tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan); | ||
159 | + tcg_temp_free_i64(t_max); | ||
160 | + tcg_temp_free_i64(t_nan); | ||
161 | +} | ||
162 | + | ||
163 | static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in) | ||
164 | { | ||
165 | TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull); | ||
166 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
167 | index XXXXXXX..XXXXXXX 100644 | ||
168 | --- a/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
169 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
170 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsqrt_h(DisasContext *ctx, arg_fsqrt_h *a) | ||
171 | return true; | ||
172 | } | ||
173 | |||
174 | +static bool trans_fsgnj_h(DisasContext *ctx, arg_fsgnj_h *a) | ||
175 | +{ | ||
176 | + REQUIRE_FPU; | ||
177 | + REQUIRE_ZFH(ctx); | ||
178 | + | ||
179 | + if (a->rs1 == a->rs2) { /* FMOV */ | ||
180 | + gen_check_nanbox_h(cpu_fpr[a->rd], cpu_fpr[a->rs1]); | ||
181 | + } else { | ||
182 | + TCGv_i64 rs1 = tcg_temp_new_i64(); | ||
183 | + TCGv_i64 rs2 = tcg_temp_new_i64(); | ||
184 | + | ||
185 | + gen_check_nanbox_h(rs1, cpu_fpr[a->rs1]); | ||
186 | + gen_check_nanbox_h(rs2, cpu_fpr[a->rs2]); | ||
187 | + | ||
188 | + /* This formulation retains the nanboxing of rs2. */ | ||
189 | + tcg_gen_deposit_i64(cpu_fpr[a->rd], rs2, rs1, 0, 15); | ||
190 | + tcg_temp_free_i64(rs1); | ||
191 | + tcg_temp_free_i64(rs2); | ||
192 | + } | ||
193 | + | ||
194 | + mark_fs_dirty(ctx); | ||
195 | + return true; | ||
196 | +} | ||
197 | + | ||
198 | +static bool trans_fsgnjn_h(DisasContext *ctx, arg_fsgnjn_h *a) | ||
199 | +{ | ||
200 | + TCGv_i64 rs1, rs2, mask; | ||
201 | + | ||
202 | + REQUIRE_FPU; | ||
203 | + REQUIRE_ZFH(ctx); | ||
204 | + | ||
205 | + rs1 = tcg_temp_new_i64(); | ||
206 | + gen_check_nanbox_h(rs1, cpu_fpr[a->rs1]); | ||
207 | + | ||
208 | + if (a->rs1 == a->rs2) { /* FNEG */ | ||
209 | + tcg_gen_xori_i64(cpu_fpr[a->rd], rs1, MAKE_64BIT_MASK(15, 1)); | ||
210 | + } else { | ||
211 | + rs2 = tcg_temp_new_i64(); | ||
212 | + gen_check_nanbox_h(rs2, cpu_fpr[a->rs2]); | ||
213 | + | ||
214 | + /* | ||
215 | + * Replace bit 15 in rs1 with inverse in rs2. | ||
216 | + * This formulation retains the nanboxing of rs1. | ||
217 | + */ | ||
218 | + mask = tcg_const_i64(~MAKE_64BIT_MASK(15, 1)); | ||
219 | + tcg_gen_not_i64(rs2, rs2); | ||
220 | + tcg_gen_andc_i64(rs2, rs2, mask); | ||
221 | + tcg_gen_and_i64(rs1, mask, rs1); | ||
222 | + tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2); | ||
223 | + | ||
224 | + tcg_temp_free_i64(mask); | ||
225 | + tcg_temp_free_i64(rs2); | ||
226 | + } | ||
227 | + mark_fs_dirty(ctx); | ||
228 | + return true; | ||
229 | +} | ||
230 | + | ||
231 | +static bool trans_fsgnjx_h(DisasContext *ctx, arg_fsgnjx_h *a) | ||
232 | +{ | ||
233 | + TCGv_i64 rs1, rs2; | ||
234 | + | ||
235 | + REQUIRE_FPU; | ||
236 | + REQUIRE_ZFH(ctx); | ||
237 | + | ||
238 | + rs1 = tcg_temp_new_i64(); | ||
239 | + gen_check_nanbox_s(rs1, cpu_fpr[a->rs1]); | ||
240 | + | ||
241 | + if (a->rs1 == a->rs2) { /* FABS */ | ||
242 | + tcg_gen_andi_i64(cpu_fpr[a->rd], rs1, ~MAKE_64BIT_MASK(15, 1)); | ||
243 | + } else { | ||
244 | + rs2 = tcg_temp_new_i64(); | ||
245 | + gen_check_nanbox_s(rs2, cpu_fpr[a->rs2]); | ||
246 | + | ||
247 | + /* | ||
248 | + * Xor bit 15 in rs1 with that in rs2. | ||
249 | + * This formulation retains the nanboxing of rs1. | ||
250 | + */ | ||
251 | + tcg_gen_andi_i64(rs2, rs2, MAKE_64BIT_MASK(15, 1)); | ||
252 | + tcg_gen_xor_i64(cpu_fpr[a->rd], rs1, rs2); | ||
253 | + | ||
254 | + tcg_temp_free_i64(rs2); | ||
255 | + } | ||
256 | + | ||
257 | + mark_fs_dirty(ctx); | ||
258 | + return true; | ||
259 | +} | ||
260 | + | ||
261 | static bool trans_fmin_h(DisasContext *ctx, arg_fmin_h *a) | ||
262 | { | ||
263 | REQUIRE_FPU; | ||
264 | @@ -XXX,XX +XXX,XX @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a) | ||
265 | mark_fs_dirty(ctx); | ||
266 | return true; | ||
267 | } | ||
268 | + | ||
269 | +static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a) | ||
270 | +{ | ||
271 | + REQUIRE_FPU; | ||
272 | + REQUIRE_ZFH(ctx); | ||
273 | + | ||
274 | + gen_set_rm(ctx, a->rm); | ||
275 | + gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
276 | + | ||
277 | + mark_fs_dirty(ctx); | ||
278 | + | ||
279 | + return true; | ||
280 | +} | ||
281 | + | ||
282 | +static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a) | ||
283 | +{ | ||
284 | + REQUIRE_FPU; | ||
285 | + REQUIRE_ZFH(ctx); | ||
286 | + REQUIRE_EXT(ctx, RVD); | ||
287 | + | ||
288 | + gen_set_rm(ctx, a->rm); | ||
289 | + gen_helper_fcvt_d_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
290 | + | ||
291 | + mark_fs_dirty(ctx); | ||
292 | + | ||
293 | + | ||
294 | + return true; | ||
295 | +} | ||
296 | + | ||
297 | +static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a) | ||
298 | +{ | ||
299 | + REQUIRE_FPU; | ||
300 | + REQUIRE_ZFH(ctx); | ||
301 | + | ||
302 | + gen_set_rm(ctx, a->rm); | ||
303 | + gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
304 | + | ||
305 | + mark_fs_dirty(ctx); | ||
306 | + | ||
307 | + return true; | ||
308 | +} | ||
309 | + | ||
310 | +static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a) | ||
311 | +{ | ||
312 | + REQUIRE_FPU; | ||
313 | + REQUIRE_ZFH(ctx); | ||
314 | + REQUIRE_EXT(ctx, RVD); | ||
315 | + | ||
316 | + gen_set_rm(ctx, a->rm); | ||
317 | + gen_helper_fcvt_h_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
318 | + | ||
319 | + mark_fs_dirty(ctx); | ||
320 | + | ||
321 | + return true; | ||
322 | +} | ||
323 | + | ||
324 | +static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a) | ||
325 | +{ | ||
326 | + REQUIRE_FPU; | ||
327 | + REQUIRE_ZFH(ctx); | ||
328 | + | ||
329 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
330 | + | ||
331 | + gen_set_rm(ctx, a->rm); | ||
332 | + gen_helper_fcvt_w_h(dest, cpu_env, cpu_fpr[a->rs1]); | ||
333 | + gen_set_gpr(ctx, a->rd, dest); | ||
334 | + return true; | ||
335 | +} | ||
336 | + | ||
337 | +static bool trans_fcvt_wu_h(DisasContext *ctx, arg_fcvt_wu_h *a) | ||
338 | +{ | ||
339 | + REQUIRE_FPU; | ||
340 | + REQUIRE_ZFH(ctx); | ||
341 | + | ||
342 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
343 | + | ||
344 | + gen_set_rm(ctx, a->rm); | ||
345 | + gen_helper_fcvt_wu_h(dest, cpu_env, cpu_fpr[a->rs1]); | ||
346 | + gen_set_gpr(ctx, a->rd, dest); | ||
347 | + return true; | ||
348 | +} | ||
349 | + | ||
350 | +static bool trans_fcvt_h_w(DisasContext *ctx, arg_fcvt_h_w *a) | ||
351 | +{ | ||
352 | + REQUIRE_FPU; | ||
353 | + REQUIRE_ZFH(ctx); | ||
354 | + | ||
355 | + TCGv t0 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
356 | + | ||
357 | + gen_set_rm(ctx, a->rm); | ||
358 | + gen_helper_fcvt_h_w(cpu_fpr[a->rd], cpu_env, t0); | ||
359 | + | ||
360 | + mark_fs_dirty(ctx); | ||
361 | + return true; | ||
362 | +} | ||
363 | + | ||
364 | +static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a) | ||
365 | +{ | ||
366 | + REQUIRE_FPU; | ||
367 | + REQUIRE_ZFH(ctx); | ||
368 | + | ||
369 | + TCGv t0 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
370 | + | ||
371 | + gen_set_rm(ctx, a->rm); | ||
372 | + gen_helper_fcvt_h_wu(cpu_fpr[a->rd], cpu_env, t0); | ||
373 | + | ||
374 | + mark_fs_dirty(ctx); | ||
375 | + return true; | ||
376 | +} | ||
377 | + | ||
378 | +static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a) | ||
379 | +{ | ||
380 | + REQUIRE_FPU; | ||
381 | + REQUIRE_ZFH(ctx); | ||
382 | + | ||
383 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
384 | + | ||
385 | +#if defined(TARGET_RISCV64) | ||
386 | + /* 16 bits -> 64 bits */ | ||
387 | + tcg_gen_ext16s_tl(dest, cpu_fpr[a->rs1]); | ||
388 | +#else | ||
389 | + /* 16 bits -> 32 bits */ | ||
390 | + tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]); | ||
391 | + tcg_gen_ext16s_tl(dest, dest); | ||
392 | +#endif | ||
393 | + | ||
394 | + gen_set_gpr(ctx, a->rd, dest); | ||
395 | + return true; | ||
396 | +} | ||
397 | + | ||
398 | +static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a) | ||
399 | +{ | ||
400 | + REQUIRE_FPU; | ||
401 | + REQUIRE_ZFH(ctx); | ||
402 | + | ||
403 | + TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
404 | + | ||
405 | + tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0); | ||
406 | + gen_nanbox_h(cpu_fpr[a->rd], cpu_fpr[a->rd]); | ||
407 | + | ||
408 | + mark_fs_dirty(ctx); | ||
409 | + return true; | ||
410 | +} | ||
411 | + | ||
412 | +static bool trans_fcvt_l_h(DisasContext *ctx, arg_fcvt_l_h *a) | ||
413 | +{ | ||
414 | + REQUIRE_64BIT(ctx); | ||
415 | + REQUIRE_FPU; | ||
416 | + REQUIRE_ZFH(ctx); | ||
417 | + | ||
418 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
419 | + | ||
420 | + gen_set_rm(ctx, a->rm); | ||
421 | + gen_helper_fcvt_l_h(dest, cpu_env, cpu_fpr[a->rs1]); | ||
422 | + gen_set_gpr(ctx, a->rd, dest); | ||
423 | + return true; | ||
424 | +} | ||
425 | + | ||
426 | +static bool trans_fcvt_lu_h(DisasContext *ctx, arg_fcvt_lu_h *a) | ||
427 | +{ | ||
428 | + REQUIRE_64BIT(ctx); | ||
429 | + REQUIRE_FPU; | ||
430 | + REQUIRE_ZFH(ctx); | ||
431 | + | ||
432 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
433 | + | ||
434 | + gen_set_rm(ctx, a->rm); | ||
435 | + gen_helper_fcvt_lu_h(dest, cpu_env, cpu_fpr[a->rs1]); | ||
436 | + gen_set_gpr(ctx, a->rd, dest); | ||
437 | + return true; | ||
438 | +} | ||
439 | + | ||
440 | +static bool trans_fcvt_h_l(DisasContext *ctx, arg_fcvt_h_l *a) | ||
441 | +{ | ||
442 | + REQUIRE_64BIT(ctx); | ||
443 | + REQUIRE_FPU; | ||
444 | + REQUIRE_ZFH(ctx); | ||
445 | + | ||
446 | + TCGv t0 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
447 | + | ||
448 | + gen_set_rm(ctx, a->rm); | ||
449 | + gen_helper_fcvt_h_l(cpu_fpr[a->rd], cpu_env, t0); | ||
450 | + | ||
451 | + mark_fs_dirty(ctx); | ||
452 | + return true; | ||
453 | +} | ||
454 | + | ||
455 | +static bool trans_fcvt_h_lu(DisasContext *ctx, arg_fcvt_h_lu *a) | ||
456 | +{ | ||
457 | + REQUIRE_64BIT(ctx); | ||
458 | + REQUIRE_FPU; | ||
459 | + REQUIRE_ZFH(ctx); | ||
460 | + | ||
461 | + TCGv t0 = get_gpr(ctx, a->rs1, EXT_SIGN); | ||
462 | + | ||
463 | + gen_set_rm(ctx, a->rm); | ||
464 | + gen_helper_fcvt_h_lu(cpu_fpr[a->rd], cpu_env, t0); | ||
465 | + | ||
466 | + mark_fs_dirty(ctx); | ||
467 | + return true; | ||
468 | +} | ||
469 | -- | ||
470 | 2.31.1 | ||
471 | |||
472 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Kito Cheng <kito.cheng@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Kito Cheng <kito.cheng@sifive.com> | ||
4 | Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-id: 20211210074329.5775-5-frank.chang@sifive.com | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/helper.h | 3 ++ | ||
12 | target/riscv/insn32.decode | 3 ++ | ||
13 | target/riscv/fpu_helper.c | 21 +++++++++++++ | ||
14 | target/riscv/insn_trans/trans_rvzfh.c.inc | 37 +++++++++++++++++++++++ | ||
15 | 4 files changed, 64 insertions(+) | ||
16 | |||
17 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/helper.h | ||
20 | +++ b/target/riscv/helper.h | ||
21 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
22 | DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
23 | DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | ||
24 | DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
25 | +DEF_HELPER_FLAGS_3(fle_h, TCG_CALL_NO_RWG, tl, env, i64, i64) | ||
26 | +DEF_HELPER_FLAGS_3(flt_h, TCG_CALL_NO_RWG, tl, env, i64, i64) | ||
27 | +DEF_HELPER_FLAGS_3(feq_h, TCG_CALL_NO_RWG, tl, env, i64, i64) | ||
28 | DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
29 | DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64) | ||
30 | DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64) | ||
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn32.decode | ||
34 | +++ b/target/riscv/insn32.decode | ||
35 | @@ -XXX,XX +XXX,XX @@ fcvt_d_h 0100001 00010 ..... ... ..... 1010011 @r2_rm | ||
36 | fcvt_w_h 1100010 00000 ..... ... ..... 1010011 @r2_rm | ||
37 | fcvt_wu_h 1100010 00001 ..... ... ..... 1010011 @r2_rm | ||
38 | fmv_x_h 1110010 00000 ..... 000 ..... 1010011 @r2 | ||
39 | +feq_h 1010010 ..... ..... 010 ..... 1010011 @r | ||
40 | +flt_h 1010010 ..... ..... 001 ..... 1010011 @r | ||
41 | +fle_h 1010010 ..... ..... 000 ..... 1010011 @r | ||
42 | fcvt_h_w 1101010 00000 ..... ... ..... 1010011 @r2_rm | ||
43 | fcvt_h_wu 1101010 00001 ..... ... ..... 1010011 @r2_rm | ||
44 | fmv_h_x 1111010 00000 ..... 000 ..... 1010011 @r2 | ||
45 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/target/riscv/fpu_helper.c | ||
48 | +++ b/target/riscv/fpu_helper.c | ||
49 | @@ -XXX,XX +XXX,XX @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1) | ||
50 | return nanbox_h(float16_sqrt(frs1, &env->fp_status)); | ||
51 | } | ||
52 | |||
53 | +target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
54 | +{ | ||
55 | + float16 frs1 = check_nanbox_h(rs1); | ||
56 | + float16 frs2 = check_nanbox_h(rs2); | ||
57 | + return float16_le(frs1, frs2, &env->fp_status); | ||
58 | +} | ||
59 | + | ||
60 | +target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
61 | +{ | ||
62 | + float16 frs1 = check_nanbox_h(rs1); | ||
63 | + float16 frs2 = check_nanbox_h(rs2); | ||
64 | + return float16_lt(frs1, frs2, &env->fp_status); | ||
65 | +} | ||
66 | + | ||
67 | +target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
68 | +{ | ||
69 | + float16 frs1 = check_nanbox_h(rs1); | ||
70 | + float16 frs2 = check_nanbox_h(rs2); | ||
71 | + return float16_eq_quiet(frs1, frs2, &env->fp_status); | ||
72 | +} | ||
73 | + | ||
74 | target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1) | ||
75 | { | ||
76 | float16 frs1 = check_nanbox_h(rs1); | ||
77 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
80 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
81 | @@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a) | ||
82 | return true; | ||
83 | } | ||
84 | |||
85 | +static bool trans_feq_h(DisasContext *ctx, arg_feq_h *a) | ||
86 | +{ | ||
87 | + REQUIRE_FPU; | ||
88 | + REQUIRE_ZFH(ctx); | ||
89 | + | ||
90 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
91 | + | ||
92 | + gen_helper_feq_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
93 | + gen_set_gpr(ctx, a->rd, dest); | ||
94 | + return true; | ||
95 | +} | ||
96 | + | ||
97 | +static bool trans_flt_h(DisasContext *ctx, arg_flt_h *a) | ||
98 | +{ | ||
99 | + REQUIRE_FPU; | ||
100 | + REQUIRE_ZFH(ctx); | ||
101 | + | ||
102 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
103 | + | ||
104 | + gen_helper_flt_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
105 | + gen_set_gpr(ctx, a->rd, dest); | ||
106 | + | ||
107 | + return true; | ||
108 | +} | ||
109 | + | ||
110 | +static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a) | ||
111 | +{ | ||
112 | + REQUIRE_FPU; | ||
113 | + REQUIRE_ZFH(ctx); | ||
114 | + | ||
115 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
116 | + | ||
117 | + gen_helper_fle_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]); | ||
118 | + gen_set_gpr(ctx, a->rd, dest); | ||
119 | + return true; | ||
120 | +} | ||
121 | + | ||
122 | static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a) | ||
123 | { | ||
124 | REQUIRE_FPU; | ||
125 | -- | ||
126 | 2.31.1 | ||
127 | |||
128 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Kito Cheng <kito.cheng@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Kito Cheng <kito.cheng@sifive.com> | ||
4 | Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-id: 20211210074329.5775-6-frank.chang@sifive.com | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/helper.h | 1 + | ||
12 | target/riscv/insn32.decode | 1 + | ||
13 | target/riscv/fpu_helper.c | 6 ++++++ | ||
14 | target/riscv/insn_trans/trans_rvzfh.c.inc | 12 ++++++++++++ | ||
15 | 4 files changed, 20 insertions(+) | ||
16 | |||
17 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/helper.h | ||
20 | +++ b/target/riscv/helper.h | ||
21 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl) | ||
22 | DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl) | ||
23 | DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl) | ||
24 | DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl) | ||
25 | +DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64) | ||
26 | |||
27 | /* Special functions */ | ||
28 | DEF_HELPER_2(csrr, tl, env, int) | ||
29 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/insn32.decode | ||
32 | +++ b/target/riscv/insn32.decode | ||
33 | @@ -XXX,XX +XXX,XX @@ fmv_x_h 1110010 00000 ..... 000 ..... 1010011 @r2 | ||
34 | feq_h 1010010 ..... ..... 010 ..... 1010011 @r | ||
35 | flt_h 1010010 ..... ..... 001 ..... 1010011 @r | ||
36 | fle_h 1010010 ..... ..... 000 ..... 1010011 @r | ||
37 | +fclass_h 1110010 00000 ..... 001 ..... 1010011 @r2 | ||
38 | fcvt_h_w 1101010 00000 ..... ... ..... 1010011 @r2_rm | ||
39 | fcvt_h_wu 1101010 00001 ..... ... ..... 1010011 @r2_rm | ||
40 | fmv_h_x 1111010 00000 ..... 000 ..... 1010011 @r2 | ||
41 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/target/riscv/fpu_helper.c | ||
44 | +++ b/target/riscv/fpu_helper.c | ||
45 | @@ -XXX,XX +XXX,XX @@ target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | ||
46 | return float16_eq_quiet(frs1, frs2, &env->fp_status); | ||
47 | } | ||
48 | |||
49 | +target_ulong helper_fclass_h(uint64_t rs1) | ||
50 | +{ | ||
51 | + float16 frs1 = check_nanbox_h(rs1); | ||
52 | + return fclass_h(frs1); | ||
53 | +} | ||
54 | + | ||
55 | target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1) | ||
56 | { | ||
57 | float16 frs1 = check_nanbox_h(rs1); | ||
58 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
61 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
62 | @@ -XXX,XX +XXX,XX @@ static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a) | ||
63 | return true; | ||
64 | } | ||
65 | |||
66 | +static bool trans_fclass_h(DisasContext *ctx, arg_fclass_h *a) | ||
67 | +{ | ||
68 | + REQUIRE_FPU; | ||
69 | + REQUIRE_ZFH(ctx); | ||
70 | + | ||
71 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
72 | + | ||
73 | + gen_helper_fclass_h(dest, cpu_fpr[a->rs1]); | ||
74 | + gen_set_gpr(ctx, a->rd, dest); | ||
75 | + return true; | ||
76 | +} | ||
77 | + | ||
78 | static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a) | ||
79 | { | ||
80 | REQUIRE_FPU; | ||
81 | -- | ||
82 | 2.31.1 | ||
83 | |||
84 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-id: 20211210074329.5775-7-frank.chang@sifive.com | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/cpu.c | 1 + | ||
9 | 1 file changed, 1 insertion(+) | ||
10 | |||
11 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/cpu.c | ||
14 | +++ b/target/riscv/cpu.c | ||
15 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
16 | DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true), | ||
17 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | ||
18 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | ||
19 | + DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), | ||
20 | DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), | ||
21 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), | ||
22 | |||
23 | -- | ||
24 | 2.31.1 | ||
25 | |||
26 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Zfhmin extension is a subset of Zfh extension, consisting only of data | ||
4 | transfer and conversion instructions. | ||
5 | |||
6 | If enabled, only the following instructions from Zfh extension are | ||
7 | included: | ||
8 | * flh, fsh, fmv.x.h, fmv.h.x, fcvt.s.h, fcvt.h.s | ||
9 | * If D extension is present: fcvt.d.h, fcvt.h.d | ||
10 | |||
11 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
12 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Message-id: 20211210074329.5775-8-frank.chang@sifive.com | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | target/riscv/cpu.h | 1 + | ||
18 | target/riscv/translate.c | 2 ++ | ||
19 | target/riscv/insn_trans/trans_rvzfh.c.inc | 22 ++++++++++++++-------- | ||
20 | 3 files changed, 17 insertions(+), 8 deletions(-) | ||
21 | |||
22 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/target/riscv/cpu.h | ||
25 | +++ b/target/riscv/cpu.h | ||
26 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPU { | ||
27 | bool ext_ifencei; | ||
28 | bool ext_icsr; | ||
29 | bool ext_zfh; | ||
30 | + bool ext_zfhmin; | ||
31 | |||
32 | char *priv_spec; | ||
33 | char *user_spec; | ||
34 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/translate.c | ||
37 | +++ b/target/riscv/translate.c | ||
38 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
39 | bool virt_enabled; | ||
40 | bool ext_ifencei; | ||
41 | bool ext_zfh; | ||
42 | + bool ext_zfhmin; | ||
43 | bool hlsx; | ||
44 | /* vector extension */ | ||
45 | bool vill; | ||
46 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
47 | ctx->frm = -1; /* unknown rounding mode */ | ||
48 | ctx->ext_ifencei = cpu->cfg.ext_ifencei; | ||
49 | ctx->ext_zfh = cpu->cfg.ext_zfh; | ||
50 | + ctx->ext_zfhmin = cpu->cfg.ext_zfhmin; | ||
51 | ctx->vlen = cpu->cfg.vlen; | ||
52 | ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS); | ||
53 | ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); | ||
54 | diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
57 | +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc | ||
58 | @@ -XXX,XX +XXX,XX @@ | ||
59 | } \ | ||
60 | } while (0) | ||
61 | |||
62 | +#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do { \ | ||
63 | + if (!(ctx->ext_zfh || ctx->ext_zfhmin)) { \ | ||
64 | + return false; \ | ||
65 | + } \ | ||
66 | +} while (0) | ||
67 | + | ||
68 | static bool trans_flh(DisasContext *ctx, arg_flh *a) | ||
69 | { | ||
70 | TCGv_i64 dest; | ||
71 | TCGv t0; | ||
72 | |||
73 | REQUIRE_FPU; | ||
74 | - REQUIRE_ZFH(ctx); | ||
75 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
76 | |||
77 | t0 = get_gpr(ctx, a->rs1, EXT_NONE); | ||
78 | if (a->imm) { | ||
79 | @@ -XXX,XX +XXX,XX @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) | ||
80 | TCGv t0; | ||
81 | |||
82 | REQUIRE_FPU; | ||
83 | - REQUIRE_ZFH(ctx); | ||
84 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
85 | |||
86 | t0 = get_gpr(ctx, a->rs1, EXT_NONE); | ||
87 | if (a->imm) { | ||
88 | @@ -XXX,XX +XXX,XX @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a) | ||
89 | static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a) | ||
90 | { | ||
91 | REQUIRE_FPU; | ||
92 | - REQUIRE_ZFH(ctx); | ||
93 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
94 | |||
95 | gen_set_rm(ctx, a->rm); | ||
96 | gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
97 | @@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a) | ||
98 | static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a) | ||
99 | { | ||
100 | REQUIRE_FPU; | ||
101 | - REQUIRE_ZFH(ctx); | ||
102 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
103 | REQUIRE_EXT(ctx, RVD); | ||
104 | |||
105 | gen_set_rm(ctx, a->rm); | ||
106 | @@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a) | ||
107 | static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a) | ||
108 | { | ||
109 | REQUIRE_FPU; | ||
110 | - REQUIRE_ZFH(ctx); | ||
111 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
112 | |||
113 | gen_set_rm(ctx, a->rm); | ||
114 | gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]); | ||
115 | @@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a) | ||
116 | static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a) | ||
117 | { | ||
118 | REQUIRE_FPU; | ||
119 | - REQUIRE_ZFH(ctx); | ||
120 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
121 | REQUIRE_EXT(ctx, RVD); | ||
122 | |||
123 | gen_set_rm(ctx, a->rm); | ||
124 | @@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a) | ||
125 | static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a) | ||
126 | { | ||
127 | REQUIRE_FPU; | ||
128 | - REQUIRE_ZFH(ctx); | ||
129 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
130 | |||
131 | TCGv dest = dest_gpr(ctx, a->rd); | ||
132 | |||
133 | @@ -XXX,XX +XXX,XX @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a) | ||
134 | static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a) | ||
135 | { | ||
136 | REQUIRE_FPU; | ||
137 | - REQUIRE_ZFH(ctx); | ||
138 | + REQUIRE_ZFH_OR_ZFHMIN(ctx); | ||
139 | |||
140 | TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
141 | |||
142 | -- | ||
143 | 2.31.1 | ||
144 | |||
145 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-id: 20211210074329.5775-9-frank.chang@sifive.com | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/cpu.c | 1 + | ||
9 | 1 file changed, 1 insertion(+) | ||
10 | |||
11 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/cpu.c | ||
14 | +++ b/target/riscv/cpu.c | ||
15 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
16 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | ||
17 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | ||
18 | DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), | ||
19 | + DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false), | ||
20 | DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), | ||
21 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), | ||
22 | |||
23 | -- | ||
24 | 2.31.1 | ||
25 | |||
26 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
7 | Message-Id: <20211210075704.23951-2-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 2 +- | ||
11 | target/riscv/cpu.c | 16 ++++++++-------- | ||
12 | 2 files changed, 9 insertions(+), 9 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu.h | ||
17 | +++ b/target/riscv/cpu.h | ||
18 | @@ -XXX,XX +XXX,XX @@ enum { | ||
19 | #define PRIV_VERSION_1_10_0 0x00011000 | ||
20 | #define PRIV_VERSION_1_11_0 0x00011100 | ||
21 | |||
22 | -#define VEXT_VERSION_0_07_1 0x00000701 | ||
23 | +#define VEXT_VERSION_1_00_0 0x00010000 | ||
24 | |||
25 | enum { | ||
26 | TRANSLATE_SUCCESS, | ||
27 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/riscv/cpu.c | ||
30 | +++ b/target/riscv/cpu.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
32 | ext |= RVH; | ||
33 | } | ||
34 | if (cpu->cfg.ext_v) { | ||
35 | - int vext_version = VEXT_VERSION_0_07_1; | ||
36 | + int vext_version = VEXT_VERSION_1_00_0; | ||
37 | ext |= RVV; | ||
38 | if (!is_power_of_2(cpu->cfg.vlen)) { | ||
39 | error_setg(errp, | ||
40 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
41 | return; | ||
42 | } | ||
43 | if (cpu->cfg.vext_spec) { | ||
44 | - if (!g_strcmp0(cpu->cfg.vext_spec, "v0.7.1")) { | ||
45 | - vext_version = VEXT_VERSION_0_07_1; | ||
46 | + if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) { | ||
47 | + vext_version = VEXT_VERSION_1_00_0; | ||
48 | } else { | ||
49 | error_setg(errp, | ||
50 | "Unsupported vector spec version '%s'", | ||
51 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
52 | } | ||
53 | } else { | ||
54 | qemu_log("vector version is not specified, " | ||
55 | - "use the default value v0.7.1\n"); | ||
56 | + "use the default value v1.0\n"); | ||
57 | } | ||
58 | set_vext_version(env, vext_version); | ||
59 | } | ||
60 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
61 | DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true), | ||
62 | DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true), | ||
63 | DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true), | ||
64 | + DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), | ||
65 | DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true), | ||
66 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | ||
67 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | ||
68 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
69 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), | ||
70 | |||
71 | DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), | ||
72 | + DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), | ||
73 | + DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), | ||
74 | + DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
75 | |||
76 | /* These are experimental so mark with 'x-' */ | ||
77 | DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false), | ||
78 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
79 | DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false), | ||
80 | DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), | ||
81 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | ||
82 | - DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), | ||
83 | - DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), | ||
84 | - DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), | ||
85 | - DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
86 | /* ePMP 0.9.3 */ | ||
87 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | ||
88 | |||
89 | -- | ||
90 | 2.31.1 | ||
91 | |||
92 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-3-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/vector_helper.c | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/vector_helper.c | ||
15 | +++ b/target/riscv/vector_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_lmul(uint32_t desc) | ||
17 | |||
18 | static uint32_t vext_wd(uint32_t desc) | ||
19 | { | ||
20 | - return (simd_data(desc) >> 11) & 0x1; | ||
21 | + return FIELD_EX32(simd_data(desc), VDATA, WD); | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | -- | ||
26 | 2.31.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
1 | 2 | ||
3 | Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
4 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-4-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 2 ++ | ||
11 | target/riscv/cpu_bits.h | 1 + | ||
12 | target/riscv/cpu_helper.c | 20 +++++++++++++++++++- | ||
13 | target/riscv/csr.c | 12 +++++++++++- | ||
14 | 4 files changed, 33 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/cpu.h | ||
19 | +++ b/target/riscv/cpu.h | ||
20 | @@ -XXX,XX +XXX,XX @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, | ||
21 | int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); | ||
22 | int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); | ||
23 | bool riscv_cpu_fp_enabled(CPURISCVState *env); | ||
24 | +bool riscv_cpu_vector_enabled(CPURISCVState *env); | ||
25 | bool riscv_cpu_virt_enabled(CPURISCVState *env); | ||
26 | void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); | ||
27 | bool riscv_cpu_two_stage_lookup(int mmu_idx); | ||
28 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); | ||
29 | #define TB_FLAGS_PRIV_MMU_MASK 3 | ||
30 | #define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2) | ||
31 | #define TB_FLAGS_MSTATUS_FS MSTATUS_FS | ||
32 | +#define TB_FLAGS_MSTATUS_VS MSTATUS_VS | ||
33 | |||
34 | typedef CPURISCVState CPUArchState; | ||
35 | typedef RISCVCPU ArchCPU; | ||
36 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/target/riscv/cpu_bits.h | ||
39 | +++ b/target/riscv/cpu_bits.h | ||
40 | @@ -XXX,XX +XXX,XX @@ | ||
41 | #define MSTATUS_UBE 0x00000040 | ||
42 | #define MSTATUS_MPIE 0x00000080 | ||
43 | #define MSTATUS_SPP 0x00000100 | ||
44 | +#define MSTATUS_VS 0x00000600 | ||
45 | #define MSTATUS_MPP 0x00001800 | ||
46 | #define MSTATUS_FS 0x00006000 | ||
47 | #define MSTATUS_XS 0x00018000 | ||
48 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/riscv/cpu_helper.c | ||
51 | +++ b/target/riscv/cpu_helper.c | ||
52 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | ||
53 | |||
54 | #ifdef CONFIG_USER_ONLY | ||
55 | flags |= TB_FLAGS_MSTATUS_FS; | ||
56 | + flags |= TB_FLAGS_MSTATUS_VS; | ||
57 | #else | ||
58 | flags |= cpu_mmu_index(env, 0); | ||
59 | if (riscv_cpu_fp_enabled(env)) { | ||
60 | flags |= env->mstatus & MSTATUS_FS; | ||
61 | } | ||
62 | |||
63 | + if (riscv_cpu_vector_enabled(env)) { | ||
64 | + flags |= env->mstatus & MSTATUS_VS; | ||
65 | + } | ||
66 | + | ||
67 | if (riscv_has_ext(env, RVH)) { | ||
68 | if (env->priv == PRV_M || | ||
69 | (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) || | ||
70 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_fp_enabled(CPURISCVState *env) | ||
71 | return false; | ||
72 | } | ||
73 | |||
74 | +/* Return true is vector support is currently enabled */ | ||
75 | +bool riscv_cpu_vector_enabled(CPURISCVState *env) | ||
76 | +{ | ||
77 | + if (env->mstatus & MSTATUS_VS) { | ||
78 | + if (riscv_cpu_virt_enabled(env) && !(env->mstatus_hs & MSTATUS_VS)) { | ||
79 | + return false; | ||
80 | + } | ||
81 | + return true; | ||
82 | + } | ||
83 | + | ||
84 | + return false; | ||
85 | +} | ||
86 | + | ||
87 | void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env) | ||
88 | { | ||
89 | uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS | | ||
90 | MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE | | ||
91 | - MSTATUS64_UXL; | ||
92 | + MSTATUS64_UXL | MSTATUS_VS; | ||
93 | bool current_virt = riscv_cpu_virt_enabled(env); | ||
94 | |||
95 | g_assert(riscv_has_ext(env, RVH)); | ||
96 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
97 | index XXXXXXX..XXXXXXX 100644 | ||
98 | --- a/target/riscv/csr.c | ||
99 | +++ b/target/riscv/csr.c | ||
100 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno, | ||
101 | { | ||
102 | #if !defined(CONFIG_USER_ONLY) | ||
103 | env->mstatus |= MSTATUS_FS; | ||
104 | + env->mstatus |= MSTATUS_VS; | ||
105 | #endif | ||
106 | env->frm = (val & FSR_RD) >> FSR_RD_SHIFT; | ||
107 | if (vs(env, csrno) >= 0) { | ||
108 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_vxrm(CPURISCVState *env, int csrno, | ||
109 | static RISCVException write_vxrm(CPURISCVState *env, int csrno, | ||
110 | target_ulong val) | ||
111 | { | ||
112 | +#if !defined(CONFIG_USER_ONLY) | ||
113 | + env->mstatus |= MSTATUS_VS; | ||
114 | +#endif | ||
115 | env->vxrm = val; | ||
116 | return RISCV_EXCP_NONE; | ||
117 | } | ||
118 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_vxsat(CPURISCVState *env, int csrno, | ||
119 | static RISCVException write_vxsat(CPURISCVState *env, int csrno, | ||
120 | target_ulong val) | ||
121 | { | ||
122 | +#if !defined(CONFIG_USER_ONLY) | ||
123 | + env->mstatus |= MSTATUS_VS; | ||
124 | +#endif | ||
125 | env->vxsat = val; | ||
126 | return RISCV_EXCP_NONE; | ||
127 | } | ||
128 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_vstart(CPURISCVState *env, int csrno, | ||
129 | static RISCVException write_vstart(CPURISCVState *env, int csrno, | ||
130 | target_ulong val) | ||
131 | { | ||
132 | +#if !defined(CONFIG_USER_ONLY) | ||
133 | + env->mstatus |= MSTATUS_VS; | ||
134 | +#endif | ||
135 | env->vstart = val; | ||
136 | return RISCV_EXCP_NONE; | ||
137 | } | ||
138 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, | ||
139 | mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | | ||
140 | MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | | ||
141 | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | | ||
142 | - MSTATUS_TW; | ||
143 | + MSTATUS_TW | MSTATUS_VS; | ||
144 | |||
145 | if (riscv_cpu_mxl(env) != MXL_RV32) { | ||
146 | /* | ||
147 | -- | ||
148 | 2.31.1 | ||
149 | |||
150 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-5-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/csr.c | 1 + | ||
10 | 1 file changed, 1 insertion(+) | ||
11 | |||
12 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/csr.c | ||
15 | +++ b/target/riscv/csr.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_mhartid(CPURISCVState *env, int csrno, | ||
17 | static uint64_t add_status_sd(RISCVMXL xl, uint64_t status) | ||
18 | { | ||
19 | if ((status & MSTATUS_FS) == MSTATUS_FS || | ||
20 | + (status & MSTATUS_VS) == MSTATUS_VS || | ||
21 | (status & MSTATUS_XS) == MSTATUS_XS) { | ||
22 | switch (xl) { | ||
23 | case MXL_RV32: | ||
24 | -- | ||
25 | 2.31.1 | ||
26 | |||
27 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
1 | 2 | ||
3 | Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
4 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-6-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu_bits.h | 1 + | ||
11 | target/riscv/csr.c | 2 +- | ||
12 | 2 files changed, 2 insertions(+), 1 deletion(-) | ||
13 | |||
14 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu_bits.h | ||
17 | +++ b/target/riscv/cpu_bits.h | ||
18 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
19 | #define SSTATUS_UPIE 0x00000010 | ||
20 | #define SSTATUS_SPIE 0x00000020 | ||
21 | #define SSTATUS_SPP 0x00000100 | ||
22 | +#define SSTATUS_VS 0x00000600 | ||
23 | #define SSTATUS_FS 0x00006000 | ||
24 | #define SSTATUS_XS 0x00018000 | ||
25 | #define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */ | ||
26 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/riscv/csr.c | ||
29 | +++ b/target/riscv/csr.c | ||
30 | @@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS & | ||
31 | (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT))); | ||
32 | static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | | ||
33 | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | | ||
34 | - SSTATUS_SUM | SSTATUS_MXR; | ||
35 | + SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS; | ||
36 | static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; | ||
37 | static const target_ulong hip_writable_mask = MIP_VSSIP; | ||
38 | static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP; | ||
39 | -- | ||
40 | 2.31.1 | ||
41 | |||
42 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Implementations may have a writable misa.v field. Analogous to the way | ||
4 | in which the floating-point unit is handled, the mstatus.vs field may | ||
5 | exist even if misa.v is clear. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20211210075704.23951-7-frank.chang@sifive.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/csr.c | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/csr.c | ||
19 | +++ b/target/riscv/csr.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_misa(CPURISCVState *env, int csrno, | ||
21 | val &= env->misa_ext_mask; | ||
22 | |||
23 | /* Mask extensions that are not supported by QEMU */ | ||
24 | - val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU); | ||
25 | + val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV); | ||
26 | |||
27 | /* 'D' depends on 'F', so clear 'D' if 'F' is not present */ | ||
28 | if ((val & RVD) && !(val & RVF)) { | ||
29 | -- | ||
30 | 2.31.1 | ||
31 | |||
32 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
4 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-8-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 5 +- | ||
11 | target/riscv/cpu_helper.c | 3 + | ||
12 | target/riscv/translate.c | 40 +++++++++++++ | ||
13 | target/riscv/insn_trans/trans_rvv.c.inc | 75 +++++++++++++++++++++---- | ||
14 | 4 files changed, 109 insertions(+), 14 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/cpu.h | ||
19 | +++ b/target/riscv/cpu.h | ||
20 | @@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, VILL, 9, 1) | ||
21 | /* Is a Hypervisor instruction load/store allowed? */ | ||
22 | FIELD(TB_FLAGS, HLSX, 10, 1) | ||
23 | FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2) | ||
24 | +FIELD(TB_FLAGS, MSTATUS_HS_VS, 13, 2) | ||
25 | /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ | ||
26 | -FIELD(TB_FLAGS, XL, 13, 2) | ||
27 | +FIELD(TB_FLAGS, XL, 15, 2) | ||
28 | /* If PointerMasking should be applied */ | ||
29 | -FIELD(TB_FLAGS, PM_ENABLED, 15, 1) | ||
30 | +FIELD(TB_FLAGS, PM_ENABLED, 17, 1) | ||
31 | |||
32 | #ifdef TARGET_RISCV32 | ||
33 | #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) | ||
34 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/cpu_helper.c | ||
37 | +++ b/target/riscv/cpu_helper.c | ||
38 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | ||
39 | |||
40 | flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS, | ||
41 | get_field(env->mstatus_hs, MSTATUS_FS)); | ||
42 | + | ||
43 | + flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS, | ||
44 | + get_field(env->mstatus_hs, MSTATUS_VS)); | ||
45 | } | ||
46 | if (riscv_has_ext(env, RVJ)) { | ||
47 | int priv = flags & TB_FLAGS_PRIV_MMU_MASK; | ||
48 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/riscv/translate.c | ||
51 | +++ b/target/riscv/translate.c | ||
52 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
53 | uint32_t misa_ext; | ||
54 | uint32_t opcode; | ||
55 | uint32_t mstatus_fs; | ||
56 | + uint32_t mstatus_vs; | ||
57 | uint32_t mstatus_hs_fs; | ||
58 | + uint32_t mstatus_hs_vs; | ||
59 | uint32_t mem_idx; | ||
60 | /* Remember the rounding mode encoded in the previous fp instruction, | ||
61 | which we have already installed into env->fp_status. Or -1 for | ||
62 | @@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx) | ||
63 | static inline void mark_fs_dirty(DisasContext *ctx) { } | ||
64 | #endif | ||
65 | |||
66 | +#ifndef CONFIG_USER_ONLY | ||
67 | +/* The states of mstatus_vs are: | ||
68 | + * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty | ||
69 | + * We will have already diagnosed disabled state, | ||
70 | + * and need to turn initial/clean into dirty. | ||
71 | + */ | ||
72 | +static void mark_vs_dirty(DisasContext *ctx) | ||
73 | +{ | ||
74 | + TCGv tmp; | ||
75 | + | ||
76 | + if (ctx->mstatus_vs != MSTATUS_VS) { | ||
77 | + /* Remember the state change for the rest of the TB. */ | ||
78 | + ctx->mstatus_vs = MSTATUS_VS; | ||
79 | + | ||
80 | + tmp = tcg_temp_new(); | ||
81 | + tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus)); | ||
82 | + tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS); | ||
83 | + tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus)); | ||
84 | + tcg_temp_free(tmp); | ||
85 | + } | ||
86 | + | ||
87 | + if (ctx->virt_enabled && ctx->mstatus_hs_vs != MSTATUS_VS) { | ||
88 | + /* Remember the stage change for the rest of the TB. */ | ||
89 | + ctx->mstatus_hs_vs = MSTATUS_VS; | ||
90 | + | ||
91 | + tmp = tcg_temp_new(); | ||
92 | + tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs)); | ||
93 | + tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS); | ||
94 | + tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs)); | ||
95 | + tcg_temp_free(tmp); | ||
96 | + } | ||
97 | +} | ||
98 | +#else | ||
99 | +static inline void mark_vs_dirty(DisasContext *ctx) { } | ||
100 | +#endif | ||
101 | + | ||
102 | static void gen_set_rm(DisasContext *ctx, int rm) | ||
103 | { | ||
104 | if (ctx->frm == rm) { | ||
105 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
106 | ctx->pc_succ_insn = ctx->base.pc_first; | ||
107 | ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX); | ||
108 | ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS; | ||
109 | + ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS; | ||
110 | ctx->priv_ver = env->priv_ver; | ||
111 | #if !defined(CONFIG_USER_ONLY) | ||
112 | if (riscv_has_ext(env, RVH)) { | ||
113 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
114 | ctx->ext_zfhmin = cpu->cfg.ext_zfhmin; | ||
115 | ctx->vlen = cpu->cfg.vlen; | ||
116 | ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS); | ||
117 | + ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS); | ||
118 | ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); | ||
119 | ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL); | ||
120 | ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); | ||
121 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
122 | index XXXXXXX..XXXXXXX 100644 | ||
123 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
124 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
125 | @@ -XXX,XX +XXX,XX @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a) | ||
126 | } | ||
127 | gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
128 | gen_set_gpr(ctx, a->rd, dst); | ||
129 | + mark_vs_dirty(ctx); | ||
130 | |||
131 | tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); | ||
132 | tcg_gen_lookup_and_goto_ptr(); | ||
133 | @@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a) | ||
134 | } | ||
135 | gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
136 | gen_set_gpr(ctx, a->rd, dst); | ||
137 | + mark_vs_dirty(ctx); | ||
138 | |||
139 | gen_goto_tb(ctx, 0, ctx->pc_succ_insn); | ||
140 | ctx->base.is_jmp = DISAS_NORETURN; | ||
141 | @@ -XXX,XX +XXX,XX @@ typedef void gen_helper_ldst_us(TCGv_ptr, TCGv_ptr, TCGv, | ||
142 | TCGv_env, TCGv_i32); | ||
143 | |||
144 | static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
145 | - gen_helper_ldst_us *fn, DisasContext *s) | ||
146 | + gen_helper_ldst_us *fn, DisasContext *s, | ||
147 | + bool is_store) | ||
148 | { | ||
149 | TCGv_ptr dest, mask; | ||
150 | TCGv base; | ||
151 | @@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
152 | |||
153 | tcg_temp_free_ptr(dest); | ||
154 | tcg_temp_free_ptr(mask); | ||
155 | + | ||
156 | + if (!is_store) { | ||
157 | + mark_vs_dirty(s); | ||
158 | + } | ||
159 | + | ||
160 | gen_set_label(over); | ||
161 | return true; | ||
162 | } | ||
163 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
164 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
165 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
166 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
167 | - return ldst_us_trans(a->rd, a->rs1, data, fn, s); | ||
168 | + return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
169 | } | ||
170 | |||
171 | static bool ld_us_check(DisasContext *s, arg_r2nfvm* a) | ||
172 | @@ -XXX,XX +XXX,XX @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
173 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
174 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
175 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
176 | - return ldst_us_trans(a->rd, a->rs1, data, fn, s); | ||
177 | + return ldst_us_trans(a->rd, a->rs1, data, fn, s, true); | ||
178 | } | ||
179 | |||
180 | static bool st_us_check(DisasContext *s, arg_r2nfvm* a) | ||
181 | @@ -XXX,XX +XXX,XX @@ typedef void gen_helper_ldst_stride(TCGv_ptr, TCGv_ptr, TCGv, | ||
182 | |||
183 | static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2, | ||
184 | uint32_t data, gen_helper_ldst_stride *fn, | ||
185 | - DisasContext *s) | ||
186 | + DisasContext *s, bool is_store) | ||
187 | { | ||
188 | TCGv_ptr dest, mask; | ||
189 | TCGv base, stride; | ||
190 | @@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2, | ||
191 | |||
192 | tcg_temp_free_ptr(dest); | ||
193 | tcg_temp_free_ptr(mask); | ||
194 | + | ||
195 | + if (!is_store) { | ||
196 | + mark_vs_dirty(s); | ||
197 | + } | ||
198 | + | ||
199 | gen_set_label(over); | ||
200 | return true; | ||
201 | } | ||
202 | @@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
203 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
204 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
205 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
206 | - return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s); | ||
207 | + return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
208 | } | ||
209 | |||
210 | static bool ld_stride_check(DisasContext *s, arg_rnfvm* a) | ||
211 | @@ -XXX,XX +XXX,XX @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
212 | return false; | ||
213 | } | ||
214 | |||
215 | - return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s); | ||
216 | + return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, true); | ||
217 | } | ||
218 | |||
219 | static bool st_stride_check(DisasContext *s, arg_rnfvm* a) | ||
220 | @@ -XXX,XX +XXX,XX @@ typedef void gen_helper_ldst_index(TCGv_ptr, TCGv_ptr, TCGv, | ||
221 | |||
222 | static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
223 | uint32_t data, gen_helper_ldst_index *fn, | ||
224 | - DisasContext *s) | ||
225 | + DisasContext *s, bool is_store) | ||
226 | { | ||
227 | TCGv_ptr dest, mask, index; | ||
228 | TCGv base; | ||
229 | @@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
230 | tcg_temp_free_ptr(dest); | ||
231 | tcg_temp_free_ptr(mask); | ||
232 | tcg_temp_free_ptr(index); | ||
233 | + | ||
234 | + if (!is_store) { | ||
235 | + mark_vs_dirty(s); | ||
236 | + } | ||
237 | + | ||
238 | gen_set_label(over); | ||
239 | return true; | ||
240 | } | ||
241 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
242 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
243 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
244 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
245 | - return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s); | ||
246 | + return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | @@ -XXX,XX +XXX,XX @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
251 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
252 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
253 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
254 | - return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s); | ||
255 | + return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true); | ||
256 | } | ||
257 | |||
258 | static bool st_index_check(DisasContext *s, arg_rnfvm* a) | ||
259 | @@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
260 | |||
261 | tcg_temp_free_ptr(dest); | ||
262 | tcg_temp_free_ptr(mask); | ||
263 | + mark_vs_dirty(s); | ||
264 | gen_set_label(over); | ||
265 | return true; | ||
266 | } | ||
267 | @@ -XXX,XX +XXX,XX @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
268 | tcg_temp_free_ptr(dest); | ||
269 | tcg_temp_free_ptr(mask); | ||
270 | tcg_temp_free_ptr(index); | ||
271 | + mark_vs_dirty(s); | ||
272 | gen_set_label(over); | ||
273 | return true; | ||
274 | } | ||
275 | @@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn, | ||
276 | vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), | ||
277 | cpu_env, s->vlen / 8, s->vlen / 8, data, fn); | ||
278 | } | ||
279 | + mark_vs_dirty(s); | ||
280 | gen_set_label(over); | ||
281 | return true; | ||
282 | } | ||
283 | @@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm, | ||
284 | tcg_temp_free_ptr(dest); | ||
285 | tcg_temp_free_ptr(mask); | ||
286 | tcg_temp_free_ptr(src2); | ||
287 | + mark_vs_dirty(s); | ||
288 | gen_set_label(over); | ||
289 | return true; | ||
290 | } | ||
291 | @@ -XXX,XX +XXX,XX @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn, | ||
292 | src1, MAXSZ(s), MAXSZ(s)); | ||
293 | |||
294 | tcg_temp_free_i64(src1); | ||
295 | + mark_vs_dirty(s); | ||
296 | return true; | ||
297 | } | ||
298 | return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); | ||
299 | @@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
300 | tcg_temp_free_ptr(dest); | ||
301 | tcg_temp_free_ptr(mask); | ||
302 | tcg_temp_free_ptr(src2); | ||
303 | + mark_vs_dirty(s); | ||
304 | gen_set_label(over); | ||
305 | return true; | ||
306 | } | ||
307 | @@ -XXX,XX +XXX,XX @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn, | ||
308 | gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), | ||
309 | sextract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s)); | ||
310 | } | ||
311 | - } else { | ||
312 | - return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, zx); | ||
313 | + mark_vs_dirty(s); | ||
314 | + return true; | ||
315 | } | ||
316 | - return true; | ||
317 | + return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, zx); | ||
318 | } | ||
319 | |||
320 | /* OPIVI with GVEC IR */ | ||
321 | @@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a, | ||
322 | vreg_ofs(s, a->rs2), | ||
323 | cpu_env, s->vlen / 8, s->vlen / 8, | ||
324 | data, fn); | ||
325 | + mark_vs_dirty(s); | ||
326 | gen_set_label(over); | ||
327 | return true; | ||
328 | } | ||
329 | @@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a, | ||
330 | vreg_ofs(s, a->rs1), | ||
331 | vreg_ofs(s, a->rs2), | ||
332 | cpu_env, s->vlen / 8, s->vlen / 8, data, fn); | ||
333 | + mark_vs_dirty(s); | ||
334 | gen_set_label(over); | ||
335 | return true; | ||
336 | } | ||
337 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
338 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
339 | s->vlen / 8, s->vlen / 8, data, \ | ||
340 | fns[s->sew]); \ | ||
341 | + mark_vs_dirty(s); \ | ||
342 | gen_set_label(over); \ | ||
343 | return true; \ | ||
344 | } \ | ||
345 | @@ -XXX,XX +XXX,XX @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn, | ||
346 | src1, MAXSZ(s), MAXSZ(s)); | ||
347 | |||
348 | tcg_temp_free_i32(src1); | ||
349 | + mark_vs_dirty(s); | ||
350 | return true; | ||
351 | } | ||
352 | return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s); | ||
353 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
354 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
355 | s->vlen / 8, s->vlen / 8, data, \ | ||
356 | fns[s->sew]); \ | ||
357 | + mark_vs_dirty(s); \ | ||
358 | gen_set_label(over); \ | ||
359 | return true; \ | ||
360 | } \ | ||
361 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a) | ||
362 | fns[s->sew]); | ||
363 | gen_set_label(over); | ||
364 | } | ||
365 | + mark_vs_dirty(s); | ||
366 | return true; | ||
367 | } | ||
368 | return false; | ||
369 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a) | ||
370 | tcg_temp_free_i64(s1_i64); | ||
371 | } | ||
372 | |||
373 | + mark_vs_dirty(s); | ||
374 | gen_set_label(over); | ||
375 | return true; | ||
376 | } | ||
377 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a) | ||
378 | if (s->vl_eq_vlmax) { | ||
379 | tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd), | ||
380 | MAXSZ(s), MAXSZ(s), simm); | ||
381 | + mark_vs_dirty(s); | ||
382 | } else { | ||
383 | TCGv_i32 desc; | ||
384 | TCGv_i64 s1; | ||
385 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a) | ||
386 | fns[s->sew](dest, s1, cpu_env, desc); | ||
387 | |||
388 | tcg_temp_free_ptr(dest); | ||
389 | + mark_vs_dirty(s); | ||
390 | gen_set_label(over); | ||
391 | } | ||
392 | return true; | ||
393 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
394 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
395 | s->vlen / 8, s->vlen / 8, data, \ | ||
396 | fns[s->sew - 1]); \ | ||
397 | + mark_vs_dirty(s); \ | ||
398 | gen_set_label(over); \ | ||
399 | return true; \ | ||
400 | } \ | ||
401 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
402 | tcg_temp_free_ptr(dest); | ||
403 | tcg_temp_free_ptr(mask); | ||
404 | tcg_temp_free_ptr(src2); | ||
405 | + mark_vs_dirty(s); | ||
406 | gen_set_label(over); | ||
407 | return true; | ||
408 | } | ||
409 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
410 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
411 | s->vlen / 8, s->vlen / 8, data, \ | ||
412 | fns[s->sew - 1]); \ | ||
413 | + mark_vs_dirty(s); \ | ||
414 | gen_set_label(over); \ | ||
415 | return true; \ | ||
416 | } \ | ||
417 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
418 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
419 | s->vlen / 8, s->vlen / 8, data, \ | ||
420 | fns[s->sew - 1]); \ | ||
421 | + mark_vs_dirty(s); \ | ||
422 | gen_set_label(over); \ | ||
423 | return true; \ | ||
424 | } \ | ||
425 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
426 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
427 | s->vlen / 8, s->vlen / 8, data, \ | ||
428 | fns[s->sew - 1]); \ | ||
429 | + mark_vs_dirty(s); \ | ||
430 | gen_set_label(over); \ | ||
431 | return true; \ | ||
432 | } \ | ||
433 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
434 | if (s->vl_eq_vlmax) { | ||
435 | tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd), | ||
436 | MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]); | ||
437 | + mark_vs_dirty(s); | ||
438 | } else { | ||
439 | TCGv_ptr dest; | ||
440 | TCGv_i32 desc; | ||
441 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
442 | fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc); | ||
443 | |||
444 | tcg_temp_free_ptr(dest); | ||
445 | + mark_vs_dirty(s); | ||
446 | gen_set_label(over); | ||
447 | } | ||
448 | return true; | ||
449 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
450 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
451 | s->vlen / 8, s->vlen / 8, data, \ | ||
452 | fns[s->sew - 1]); \ | ||
453 | + mark_vs_dirty(s); \ | ||
454 | gen_set_label(over); \ | ||
455 | return true; \ | ||
456 | } \ | ||
457 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
458 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
459 | s->vlen / 8, s->vlen / 8, data, \ | ||
460 | fns[s->sew - 1]); \ | ||
461 | + mark_vs_dirty(s); \ | ||
462 | gen_set_label(over); \ | ||
463 | return true; \ | ||
464 | } \ | ||
465 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \ | ||
466 | vreg_ofs(s, a->rs1), \ | ||
467 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
468 | s->vlen / 8, s->vlen / 8, data, fn); \ | ||
469 | + mark_vs_dirty(s); \ | ||
470 | gen_set_label(over); \ | ||
471 | return true; \ | ||
472 | } \ | ||
473 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
474 | vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \ | ||
475 | cpu_env, s->vlen / 8, s->vlen / 8, \ | ||
476 | data, fn); \ | ||
477 | + mark_vs_dirty(s); \ | ||
478 | gen_set_label(over); \ | ||
479 | return true; \ | ||
480 | } \ | ||
481 | @@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
482 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
483 | vreg_ofs(s, a->rs2), cpu_env, | ||
484 | s->vlen / 8, s->vlen / 8, data, fns[s->sew]); | ||
485 | + mark_vs_dirty(s); | ||
486 | gen_set_label(over); | ||
487 | return true; | ||
488 | } | ||
489 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
490 | tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
491 | cpu_env, s->vlen / 8, s->vlen / 8, | ||
492 | data, fns[s->sew]); | ||
493 | + mark_vs_dirty(s); | ||
494 | gen_set_label(over); | ||
495 | return true; | ||
496 | } | ||
497 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) | ||
498 | tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]); | ||
499 | vec_element_storei(s, a->rd, 0, t1); | ||
500 | tcg_temp_free_i64(t1); | ||
501 | + mark_vs_dirty(s); | ||
502 | done: | ||
503 | gen_set_label(over); | ||
504 | return true; | ||
505 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
506 | } | ||
507 | vec_element_storei(s, a->rd, 0, t1); | ||
508 | tcg_temp_free_i64(t1); | ||
509 | + mark_vs_dirty(s); | ||
510 | gen_set_label(over); | ||
511 | return true; | ||
512 | } | ||
513 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a) | ||
514 | tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd), | ||
515 | MAXSZ(s), MAXSZ(s), dest); | ||
516 | tcg_temp_free_i64(dest); | ||
517 | + mark_vs_dirty(s); | ||
518 | } else { | ||
519 | static gen_helper_opivx * const fns[4] = { | ||
520 | gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h, | ||
521 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) | ||
522 | endian_ofs(s, a->rs2, a->rs1), | ||
523 | MAXSZ(s), MAXSZ(s)); | ||
524 | } | ||
525 | + mark_vs_dirty(s); | ||
526 | } else { | ||
527 | static gen_helper_opivx * const fns[4] = { | ||
528 | gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h, | ||
529 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
530 | vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), | ||
531 | cpu_env, s->vlen / 8, s->vlen / 8, data, | ||
532 | fns[s->sew]); | ||
533 | + mark_vs_dirty(s); | ||
534 | gen_set_label(over); | ||
535 | return true; | ||
536 | } | ||
537 | -- | ||
538 | 2.31.1 | ||
539 | |||
540 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Remove VXRM and VXSAT fields from FCSR register as they are only | ||
4 | presented in VCSR register. | ||
5 | * Remove RVV loose check in fs() predicate function. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20211210075704.23951-9-frank.chang@sifive.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/csr.c | 13 ------------- | ||
14 | 1 file changed, 13 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/csr.c | ||
19 | +++ b/target/riscv/csr.c | ||
20 | @@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops) | ||
21 | static RISCVException fs(CPURISCVState *env, int csrno) | ||
22 | { | ||
23 | #if !defined(CONFIG_USER_ONLY) | ||
24 | - /* loose check condition for fcsr in vector extension */ | ||
25 | - if ((csrno == CSR_FCSR) && (env->misa_ext & RVV)) { | ||
26 | - return RISCV_EXCP_NONE; | ||
27 | - } | ||
28 | if (!env->debugger && !riscv_cpu_fp_enabled(env)) { | ||
29 | return RISCV_EXCP_ILLEGAL_INST; | ||
30 | } | ||
31 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_fcsr(CPURISCVState *env, int csrno, | ||
32 | { | ||
33 | *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT) | ||
34 | | (env->frm << FSR_RD_SHIFT); | ||
35 | - if (vs(env, csrno) >= 0) { | ||
36 | - *val |= (env->vxrm << FSR_VXRM_SHIFT) | ||
37 | - | (env->vxsat << FSR_VXSAT_SHIFT); | ||
38 | - } | ||
39 | return RISCV_EXCP_NONE; | ||
40 | } | ||
41 | |||
42 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno, | ||
43 | { | ||
44 | #if !defined(CONFIG_USER_ONLY) | ||
45 | env->mstatus |= MSTATUS_FS; | ||
46 | - env->mstatus |= MSTATUS_VS; | ||
47 | #endif | ||
48 | env->frm = (val & FSR_RD) >> FSR_RD_SHIFT; | ||
49 | - if (vs(env, csrno) >= 0) { | ||
50 | - env->vxrm = (val & FSR_VXRM) >> FSR_VXRM_SHIFT; | ||
51 | - env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT; | ||
52 | - } | ||
53 | riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT); | ||
54 | return RISCV_EXCP_NONE; | ||
55 | } | ||
56 | -- | ||
57 | 2.31.1 | ||
58 | |||
59 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
1 | 2 | ||
3 | Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> | ||
4 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-10-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu_bits.h | 7 +++++++ | ||
11 | target/riscv/csr.c | 17 +++++++++++++++++ | ||
12 | 2 files changed, 24 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu_bits.h | ||
17 | +++ b/target/riscv/cpu_bits.h | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | #define CSR_VSTART 0x008 | ||
20 | #define CSR_VXSAT 0x009 | ||
21 | #define CSR_VXRM 0x00a | ||
22 | +#define CSR_VCSR 0x00f | ||
23 | #define CSR_VL 0xc20 | ||
24 | #define CSR_VTYPE 0xc21 | ||
25 | |||
26 | +/* VCSR fields */ | ||
27 | +#define VCSR_VXSAT_SHIFT 0 | ||
28 | +#define VCSR_VXSAT (0x1 << VCSR_VXSAT_SHIFT) | ||
29 | +#define VCSR_VXRM_SHIFT 1 | ||
30 | +#define VCSR_VXRM (0x3 << VCSR_VXRM_SHIFT) | ||
31 | + | ||
32 | /* User Timers and Counters */ | ||
33 | #define CSR_CYCLE 0xc00 | ||
34 | #define CSR_TIME 0xc01 | ||
35 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/target/riscv/csr.c | ||
38 | +++ b/target/riscv/csr.c | ||
39 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_vstart(CPURISCVState *env, int csrno, | ||
40 | return RISCV_EXCP_NONE; | ||
41 | } | ||
42 | |||
43 | +static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val) | ||
44 | +{ | ||
45 | + *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT); | ||
46 | + return RISCV_EXCP_NONE; | ||
47 | +} | ||
48 | + | ||
49 | +static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val) | ||
50 | +{ | ||
51 | +#if !defined(CONFIG_USER_ONLY) | ||
52 | + env->mstatus |= MSTATUS_VS; | ||
53 | +#endif | ||
54 | + env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT; | ||
55 | + env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT; | ||
56 | + return RISCV_EXCP_NONE; | ||
57 | +} | ||
58 | + | ||
59 | /* User Timers and Counters */ | ||
60 | static RISCVException read_instret(CPURISCVState *env, int csrno, | ||
61 | target_ulong *val) | ||
62 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
63 | [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart }, | ||
64 | [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat }, | ||
65 | [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm }, | ||
66 | + [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr }, | ||
67 | [CSR_VL] = { "vl", vs, read_vl }, | ||
68 | [CSR_VTYPE] = { "vtype", vs, read_vtype }, | ||
69 | /* User Timers and Counters */ | ||
70 | -- | ||
71 | 2.31.1 | ||
72 | |||
73 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Greentime Hu <greentime.hu@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Greentime Hu <greentime.hu@sifive.com> | ||
4 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-11-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu_bits.h | 1 + | ||
11 | target/riscv/csr.c | 7 +++++++ | ||
12 | 2 files changed, 8 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu_bits.h | ||
17 | +++ b/target/riscv/cpu_bits.h | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | #define CSR_VCSR 0x00f | ||
20 | #define CSR_VL 0xc20 | ||
21 | #define CSR_VTYPE 0xc21 | ||
22 | +#define CSR_VLENB 0xc22 | ||
23 | |||
24 | /* VCSR fields */ | ||
25 | #define VCSR_VXSAT_SHIFT 0 | ||
26 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/riscv/csr.c | ||
29 | +++ b/target/riscv/csr.c | ||
30 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_vl(CPURISCVState *env, int csrno, | ||
31 | return RISCV_EXCP_NONE; | ||
32 | } | ||
33 | |||
34 | +static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val) | ||
35 | +{ | ||
36 | + *val = env_archcpu(env)->cfg.vlen >> 3; | ||
37 | + return RISCV_EXCP_NONE; | ||
38 | +} | ||
39 | + | ||
40 | static RISCVException read_vxrm(CPURISCVState *env, int csrno, | ||
41 | target_ulong *val) | ||
42 | { | ||
43 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
44 | [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr }, | ||
45 | [CSR_VL] = { "vl", vs, read_vl }, | ||
46 | [CSR_VTYPE] = { "vtype", vs, read_vtype }, | ||
47 | + [CSR_VLENB] = { "vlenb", vs, read_vlenb }, | ||
48 | /* User Timers and Counters */ | ||
49 | [CSR_CYCLE] = { "cycle", ctr, read_instret }, | ||
50 | [CSR_INSTRET] = { "instret", ctr, read_instret }, | ||
51 | -- | ||
52 | 2.31.1 | ||
53 | |||
54 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | If VS field is off, accessing vector csr registers should raise an | ||
4 | illegal-instruction exception. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-12-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/csr.c | 5 +++++ | ||
13 | 1 file changed, 5 insertions(+) | ||
14 | |||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/csr.c | ||
18 | +++ b/target/riscv/csr.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno) | ||
20 | static RISCVException vs(CPURISCVState *env, int csrno) | ||
21 | { | ||
22 | if (env->misa_ext & RVV) { | ||
23 | +#if !defined(CONFIG_USER_ONLY) | ||
24 | + if (!env->debugger && !riscv_cpu_vector_enabled(env)) { | ||
25 | + return RISCV_EXCP_ILLEGAL_INST; | ||
26 | + } | ||
27 | +#endif | ||
28 | return RISCV_EXCP_NONE; | ||
29 | } | ||
30 | return RISCV_EXCP_ILLEGAL_INST; | ||
31 | -- | ||
32 | 2.31.1 | ||
33 | |||
34 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | As in RVV 1.0 design, MLEN is hardcoded with value 1 (Section 4.5). | ||
4 | Thus, remove all MLEN related calculations. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-13-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/internals.h | 9 +- | ||
13 | target/riscv/translate.c | 2 - | ||
14 | target/riscv/vector_helper.c | 252 ++++++++++-------------- | ||
15 | target/riscv/insn_trans/trans_rvv.c.inc | 35 +--- | ||
16 | 4 files changed, 111 insertions(+), 187 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/internals.h | ||
21 | +++ b/target/riscv/internals.h | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | #include "hw/registerfields.h" | ||
24 | |||
25 | /* share data between vector helpers and decode code */ | ||
26 | -FIELD(VDATA, MLEN, 0, 8) | ||
27 | -FIELD(VDATA, VM, 8, 1) | ||
28 | -FIELD(VDATA, LMUL, 9, 2) | ||
29 | -FIELD(VDATA, NF, 11, 4) | ||
30 | -FIELD(VDATA, WD, 11, 1) | ||
31 | +FIELD(VDATA, VM, 0, 1) | ||
32 | +FIELD(VDATA, LMUL, 1, 3) | ||
33 | +FIELD(VDATA, NF, 4, 4) | ||
34 | +FIELD(VDATA, WD, 4, 1) | ||
35 | |||
36 | /* float point classify helpers */ | ||
37 | target_ulong fclass_h(uint64_t frs1); | ||
38 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/target/riscv/translate.c | ||
41 | +++ b/target/riscv/translate.c | ||
42 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
43 | uint8_t lmul; | ||
44 | uint8_t sew; | ||
45 | uint16_t vlen; | ||
46 | - uint16_t mlen; | ||
47 | bool vl_eq_vlmax; | ||
48 | uint8_t ntemp; | ||
49 | CPUState *cs; | ||
50 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
51 | ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL); | ||
52 | ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); | ||
53 | ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL); | ||
54 | - ctx->mlen = 1 << (ctx->sew + 3 - ctx->lmul); | ||
55 | ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); | ||
56 | ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); | ||
57 | ctx->cs = cs; | ||
58 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/vector_helper.c | ||
61 | +++ b/target/riscv/vector_helper.c | ||
62 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_nf(uint32_t desc) | ||
63 | return FIELD_EX32(simd_data(desc), VDATA, NF); | ||
64 | } | ||
65 | |||
66 | -static inline uint32_t vext_mlen(uint32_t desc) | ||
67 | -{ | ||
68 | - return FIELD_EX32(simd_data(desc), VDATA, MLEN); | ||
69 | -} | ||
70 | - | ||
71 | static inline uint32_t vext_vm(uint32_t desc) | ||
72 | { | ||
73 | return FIELD_EX32(simd_data(desc), VDATA, VM); | ||
74 | @@ -XXX,XX +XXX,XX @@ static void clearq(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot) | ||
75 | vext_clear(cur, cnt, tot); | ||
76 | } | ||
77 | |||
78 | -static inline void vext_set_elem_mask(void *v0, int mlen, int index, | ||
79 | - uint8_t value) | ||
80 | +static inline void vext_set_elem_mask(void *v0, int index, | ||
81 | + uint8_t value) | ||
82 | { | ||
83 | - int idx = (index * mlen) / 64; | ||
84 | - int pos = (index * mlen) % 64; | ||
85 | + int idx = index / 64; | ||
86 | + int pos = index % 64; | ||
87 | uint64_t old = ((uint64_t *)v0)[idx]; | ||
88 | - ((uint64_t *)v0)[idx] = deposit64(old, pos, mlen, value); | ||
89 | + ((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value); | ||
90 | } | ||
91 | |||
92 | -static inline int vext_elem_mask(void *v0, int mlen, int index) | ||
93 | +/* | ||
94 | + * Earlier designs (pre-0.9) had a varying number of bits | ||
95 | + * per mask value (MLEN). In the 0.9 design, MLEN=1. | ||
96 | + * (Section 4.5) | ||
97 | + */ | ||
98 | +static inline int vext_elem_mask(void *v0, int index) | ||
99 | { | ||
100 | - int idx = (index * mlen) / 64; | ||
101 | - int pos = (index * mlen) % 64; | ||
102 | + int idx = index / 64; | ||
103 | + int pos = index % 64; | ||
104 | return (((uint64_t *)v0)[idx] >> pos) & 1; | ||
105 | } | ||
106 | |||
107 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
108 | { | ||
109 | uint32_t i, k; | ||
110 | uint32_t nf = vext_nf(desc); | ||
111 | - uint32_t mlen = vext_mlen(desc); | ||
112 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
113 | |||
114 | /* probe every access*/ | ||
115 | for (i = 0; i < env->vl; i++) { | ||
116 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
117 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
118 | continue; | ||
119 | } | ||
120 | probe_pages(env, base + stride * i, nf * msz, ra, access_type); | ||
121 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
122 | /* do real access */ | ||
123 | for (i = 0; i < env->vl; i++) { | ||
124 | k = 0; | ||
125 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
126 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
127 | continue; | ||
128 | } | ||
129 | while (k < nf) { | ||
130 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
131 | uint32_t i, k; | ||
132 | uint32_t nf = vext_nf(desc); | ||
133 | uint32_t vm = vext_vm(desc); | ||
134 | - uint32_t mlen = vext_mlen(desc); | ||
135 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
136 | |||
137 | /* probe every access*/ | ||
138 | for (i = 0; i < env->vl; i++) { | ||
139 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
140 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
141 | continue; | ||
142 | } | ||
143 | probe_pages(env, get_index_addr(base, i, vs2), nf * msz, ra, | ||
144 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
145 | /* load bytes from guest memory */ | ||
146 | for (i = 0; i < env->vl; i++) { | ||
147 | k = 0; | ||
148 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
149 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
150 | continue; | ||
151 | } | ||
152 | while (k < nf) { | ||
153 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
154 | { | ||
155 | void *host; | ||
156 | uint32_t i, k, vl = 0; | ||
157 | - uint32_t mlen = vext_mlen(desc); | ||
158 | uint32_t nf = vext_nf(desc); | ||
159 | uint32_t vm = vext_vm(desc); | ||
160 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
161 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
162 | |||
163 | /* probe every access*/ | ||
164 | for (i = 0; i < env->vl; i++) { | ||
165 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
166 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
167 | continue; | ||
168 | } | ||
169 | addr = base + nf * i * msz; | ||
170 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
171 | } | ||
172 | for (i = 0; i < env->vl; i++) { | ||
173 | k = 0; | ||
174 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
175 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
176 | continue; | ||
177 | } | ||
178 | while (k < nf) { | ||
179 | @@ -XXX,XX +XXX,XX @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base, | ||
180 | target_long addr; | ||
181 | uint32_t wd = vext_wd(desc); | ||
182 | uint32_t vm = vext_vm(desc); | ||
183 | - uint32_t mlen = vext_mlen(desc); | ||
184 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
185 | |||
186 | for (i = 0; i < env->vl; i++) { | ||
187 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
188 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
189 | continue; | ||
190 | } | ||
191 | probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_LOAD); | ||
192 | probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_STORE); | ||
193 | } | ||
194 | for (i = 0; i < env->vl; i++) { | ||
195 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
196 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
197 | continue; | ||
198 | } | ||
199 | addr = get_index_addr(base, i, vs2); | ||
200 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
201 | opivv2_fn *fn, clear_fn *clearfn) | ||
202 | { | ||
203 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
204 | - uint32_t mlen = vext_mlen(desc); | ||
205 | uint32_t vm = vext_vm(desc); | ||
206 | uint32_t vl = env->vl; | ||
207 | uint32_t i; | ||
208 | |||
209 | for (i = 0; i < vl; i++) { | ||
210 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
211 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
212 | continue; | ||
213 | } | ||
214 | fn(vd, vs1, vs2, i); | ||
215 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
216 | opivx2_fn fn, clear_fn *clearfn) | ||
217 | { | ||
218 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
219 | - uint32_t mlen = vext_mlen(desc); | ||
220 | uint32_t vm = vext_vm(desc); | ||
221 | uint32_t vl = env->vl; | ||
222 | uint32_t i; | ||
223 | |||
224 | for (i = 0; i < vl; i++) { | ||
225 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
226 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
227 | continue; | ||
228 | } | ||
229 | fn(vd, s1, vs2, i); | ||
230 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VX(vwsub_wx_w, 4, 8, clearq) | ||
231 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
232 | CPURISCVState *env, uint32_t desc) \ | ||
233 | { \ | ||
234 | - uint32_t mlen = vext_mlen(desc); \ | ||
235 | uint32_t vl = env->vl; \ | ||
236 | uint32_t esz = sizeof(ETYPE); \ | ||
237 | uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
238 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
239 | for (i = 0; i < vl; i++) { \ | ||
240 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
241 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
242 | - uint8_t carry = vext_elem_mask(v0, mlen, i); \ | ||
243 | + uint8_t carry = vext_elem_mask(v0, i); \ | ||
244 | \ | ||
245 | *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \ | ||
246 | } \ | ||
247 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VADC_VVM(vsbc_vvm_d, uint64_t, H8, DO_VSBC, clearq) | ||
248 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
249 | CPURISCVState *env, uint32_t desc) \ | ||
250 | { \ | ||
251 | - uint32_t mlen = vext_mlen(desc); \ | ||
252 | uint32_t vl = env->vl; \ | ||
253 | uint32_t esz = sizeof(ETYPE); \ | ||
254 | uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
255 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
256 | \ | ||
257 | for (i = 0; i < vl; i++) { \ | ||
258 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
259 | - uint8_t carry = vext_elem_mask(v0, mlen, i); \ | ||
260 | + uint8_t carry = vext_elem_mask(v0, i); \ | ||
261 | \ | ||
262 | *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\ | ||
263 | } \ | ||
264 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VADC_VXM(vsbc_vxm_d, uint64_t, H8, DO_VSBC, clearq) | ||
265 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
266 | CPURISCVState *env, uint32_t desc) \ | ||
267 | { \ | ||
268 | - uint32_t mlen = vext_mlen(desc); \ | ||
269 | uint32_t vl = env->vl; \ | ||
270 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
271 | uint32_t i; \ | ||
272 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
273 | for (i = 0; i < vl; i++) { \ | ||
274 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
275 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
276 | - uint8_t carry = vext_elem_mask(v0, mlen, i); \ | ||
277 | + uint8_t carry = vext_elem_mask(v0, i); \ | ||
278 | \ | ||
279 | - vext_set_elem_mask(vd, mlen, i, DO_OP(s2, s1, carry));\ | ||
280 | + vext_set_elem_mask(vd, i, DO_OP(s2, s1, carry)); \ | ||
281 | } \ | ||
282 | for (; i < vlmax; i++) { \ | ||
283 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
284 | + vext_set_elem_mask(vd, i, 0); \ | ||
285 | } \ | ||
286 | } | ||
287 | |||
288 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VMADC_VVM(vmsbc_vvm_d, uint64_t, H8, DO_MSBC) | ||
289 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
290 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
291 | { \ | ||
292 | - uint32_t mlen = vext_mlen(desc); \ | ||
293 | uint32_t vl = env->vl; \ | ||
294 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
295 | uint32_t i; \ | ||
296 | \ | ||
297 | for (i = 0; i < vl; i++) { \ | ||
298 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
299 | - uint8_t carry = vext_elem_mask(v0, mlen, i); \ | ||
300 | + uint8_t carry = vext_elem_mask(v0, i); \ | ||
301 | \ | ||
302 | - vext_set_elem_mask(vd, mlen, i, \ | ||
303 | + vext_set_elem_mask(vd, i, \ | ||
304 | DO_OP(s2, (ETYPE)(target_long)s1, carry)); \ | ||
305 | } \ | ||
306 | for (; i < vlmax; i++) { \ | ||
307 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
308 | + vext_set_elem_mask(vd, i, 0); \ | ||
309 | } \ | ||
310 | } | ||
311 | |||
312 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VX(vxor_vx_d, 8, 8, clearq) | ||
313 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
314 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
315 | { \ | ||
316 | - uint32_t mlen = vext_mlen(desc); \ | ||
317 | uint32_t vm = vext_vm(desc); \ | ||
318 | uint32_t vl = env->vl; \ | ||
319 | uint32_t esz = sizeof(TS1); \ | ||
320 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
321 | uint32_t i; \ | ||
322 | \ | ||
323 | for (i = 0; i < vl; i++) { \ | ||
324 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
325 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
326 | continue; \ | ||
327 | } \ | ||
328 | TS1 s1 = *((TS1 *)vs1 + HS1(i)); \ | ||
329 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_SHIFT_VV(vsra_vv_d, uint64_t, int64_t, H8, H8, DO_SRL, 0x3f, clearq) | ||
330 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
331 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
332 | { \ | ||
333 | - uint32_t mlen = vext_mlen(desc); \ | ||
334 | uint32_t vm = vext_vm(desc); \ | ||
335 | uint32_t vl = env->vl; \ | ||
336 | uint32_t esz = sizeof(TD); \ | ||
337 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
338 | uint32_t i; \ | ||
339 | \ | ||
340 | for (i = 0; i < vl; i++) { \ | ||
341 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
342 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
343 | continue; \ | ||
344 | } \ | ||
345 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
346 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_SHIFT_VX(vnsra_vx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f, clearl) | ||
347 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
348 | CPURISCVState *env, uint32_t desc) \ | ||
349 | { \ | ||
350 | - uint32_t mlen = vext_mlen(desc); \ | ||
351 | uint32_t vm = vext_vm(desc); \ | ||
352 | uint32_t vl = env->vl; \ | ||
353 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
354 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
355 | for (i = 0; i < vl; i++) { \ | ||
356 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
357 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
358 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
359 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
360 | continue; \ | ||
361 | } \ | ||
362 | - vext_set_elem_mask(vd, mlen, i, DO_OP(s2, s1)); \ | ||
363 | + vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \ | ||
364 | } \ | ||
365 | for (; i < vlmax; i++) { \ | ||
366 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
367 | + vext_set_elem_mask(vd, i, 0); \ | ||
368 | } \ | ||
369 | } | ||
370 | |||
371 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VV(vmsle_vv_d, int64_t, H8, DO_MSLE) | ||
372 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
373 | CPURISCVState *env, uint32_t desc) \ | ||
374 | { \ | ||
375 | - uint32_t mlen = vext_mlen(desc); \ | ||
376 | uint32_t vm = vext_vm(desc); \ | ||
377 | uint32_t vl = env->vl; \ | ||
378 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
379 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
380 | \ | ||
381 | for (i = 0; i < vl; i++) { \ | ||
382 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
383 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
384 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
385 | continue; \ | ||
386 | } \ | ||
387 | - vext_set_elem_mask(vd, mlen, i, \ | ||
388 | + vext_set_elem_mask(vd, i, \ | ||
389 | DO_OP(s2, (ETYPE)(target_long)s1)); \ | ||
390 | } \ | ||
391 | for (; i < vlmax; i++) { \ | ||
392 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
393 | + vext_set_elem_mask(vd, i, 0); \ | ||
394 | } \ | ||
395 | } | ||
396 | |||
397 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VMV_VX(vmv_v_x_d, int64_t, H8, clearq) | ||
398 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
399 | CPURISCVState *env, uint32_t desc) \ | ||
400 | { \ | ||
401 | - uint32_t mlen = vext_mlen(desc); \ | ||
402 | uint32_t vl = env->vl; \ | ||
403 | uint32_t esz = sizeof(ETYPE); \ | ||
404 | uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
405 | uint32_t i; \ | ||
406 | \ | ||
407 | for (i = 0; i < vl; i++) { \ | ||
408 | - ETYPE *vt = (!vext_elem_mask(v0, mlen, i) ? vs2 : vs1); \ | ||
409 | + ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \ | ||
410 | *((ETYPE *)vd + H(i)) = *(vt + H(i)); \ | ||
411 | } \ | ||
412 | CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
413 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VMERGE_VV(vmerge_vvm_d, int64_t, H8, clearq) | ||
414 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
415 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
416 | { \ | ||
417 | - uint32_t mlen = vext_mlen(desc); \ | ||
418 | uint32_t vl = env->vl; \ | ||
419 | uint32_t esz = sizeof(ETYPE); \ | ||
420 | uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
421 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
422 | \ | ||
423 | for (i = 0; i < vl; i++) { \ | ||
424 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
425 | - ETYPE d = (!vext_elem_mask(v0, mlen, i) ? s2 : \ | ||
426 | + ETYPE d = (!vext_elem_mask(v0, i) ? s2 : \ | ||
427 | (ETYPE)(target_long)s1); \ | ||
428 | *((ETYPE *)vd + H(i)) = d; \ | ||
429 | } \ | ||
430 | @@ -XXX,XX +XXX,XX @@ do_##NAME(void *vd, void *vs1, void *vs2, int i, \ | ||
431 | static inline void | ||
432 | vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2, | ||
433 | CPURISCVState *env, | ||
434 | - uint32_t vl, uint32_t vm, uint32_t mlen, int vxrm, | ||
435 | + uint32_t vl, uint32_t vm, int vxrm, | ||
436 | opivv2_rm_fn *fn) | ||
437 | { | ||
438 | for (uint32_t i = 0; i < vl; i++) { | ||
439 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
440 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
441 | continue; | ||
442 | } | ||
443 | fn(vd, vs1, vs2, i, env, vxrm); | ||
444 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2, | ||
445 | opivv2_rm_fn *fn, clear_fn *clearfn) | ||
446 | { | ||
447 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
448 | - uint32_t mlen = vext_mlen(desc); | ||
449 | uint32_t vm = vext_vm(desc); | ||
450 | uint32_t vl = env->vl; | ||
451 | |||
452 | switch (env->vxrm) { | ||
453 | case 0: /* rnu */ | ||
454 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
455 | - env, vl, vm, mlen, 0, fn); | ||
456 | + env, vl, vm, 0, fn); | ||
457 | break; | ||
458 | case 1: /* rne */ | ||
459 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
460 | - env, vl, vm, mlen, 1, fn); | ||
461 | + env, vl, vm, 1, fn); | ||
462 | break; | ||
463 | case 2: /* rdn */ | ||
464 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
465 | - env, vl, vm, mlen, 2, fn); | ||
466 | + env, vl, vm, 2, fn); | ||
467 | break; | ||
468 | default: /* rod */ | ||
469 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
470 | - env, vl, vm, mlen, 3, fn); | ||
471 | + env, vl, vm, 3, fn); | ||
472 | break; | ||
473 | } | ||
474 | |||
475 | @@ -XXX,XX +XXX,XX @@ do_##NAME(void *vd, target_long s1, void *vs2, int i, \ | ||
476 | static inline void | ||
477 | vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, | ||
478 | CPURISCVState *env, | ||
479 | - uint32_t vl, uint32_t vm, uint32_t mlen, int vxrm, | ||
480 | + uint32_t vl, uint32_t vm, int vxrm, | ||
481 | opivx2_rm_fn *fn) | ||
482 | { | ||
483 | for (uint32_t i = 0; i < vl; i++) { | ||
484 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
485 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
486 | continue; | ||
487 | } | ||
488 | fn(vd, s1, vs2, i, env, vxrm); | ||
489 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, | ||
490 | opivx2_rm_fn *fn, clear_fn *clearfn) | ||
491 | { | ||
492 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
493 | - uint32_t mlen = vext_mlen(desc); | ||
494 | uint32_t vm = vext_vm(desc); | ||
495 | uint32_t vl = env->vl; | ||
496 | |||
497 | switch (env->vxrm) { | ||
498 | case 0: /* rnu */ | ||
499 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
500 | - env, vl, vm, mlen, 0, fn); | ||
501 | + env, vl, vm, 0, fn); | ||
502 | break; | ||
503 | case 1: /* rne */ | ||
504 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
505 | - env, vl, vm, mlen, 1, fn); | ||
506 | + env, vl, vm, 1, fn); | ||
507 | break; | ||
508 | case 2: /* rdn */ | ||
509 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
510 | - env, vl, vm, mlen, 2, fn); | ||
511 | + env, vl, vm, 2, fn); | ||
512 | break; | ||
513 | default: /* rod */ | ||
514 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
515 | - env, vl, vm, mlen, 3, fn); | ||
516 | + env, vl, vm, 3, fn); | ||
517 | break; | ||
518 | } | ||
519 | |||
520 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
521 | uint32_t desc) \ | ||
522 | { \ | ||
523 | uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
524 | - uint32_t mlen = vext_mlen(desc); \ | ||
525 | uint32_t vm = vext_vm(desc); \ | ||
526 | uint32_t vl = env->vl; \ | ||
527 | uint32_t i; \ | ||
528 | \ | ||
529 | for (i = 0; i < vl; i++) { \ | ||
530 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
531 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
532 | continue; \ | ||
533 | } \ | ||
534 | do_##NAME(vd, vs1, vs2, i, env); \ | ||
535 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
536 | uint32_t desc) \ | ||
537 | { \ | ||
538 | uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
539 | - uint32_t mlen = vext_mlen(desc); \ | ||
540 | uint32_t vm = vext_vm(desc); \ | ||
541 | uint32_t vl = env->vl; \ | ||
542 | uint32_t i; \ | ||
543 | \ | ||
544 | for (i = 0; i < vl; i++) { \ | ||
545 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
546 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
547 | continue; \ | ||
548 | } \ | ||
549 | do_##NAME(vd, s1, vs2, i, env); \ | ||
550 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
551 | CPURISCVState *env, uint32_t desc) \ | ||
552 | { \ | ||
553 | uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
554 | - uint32_t mlen = vext_mlen(desc); \ | ||
555 | uint32_t vm = vext_vm(desc); \ | ||
556 | uint32_t vl = env->vl; \ | ||
557 | uint32_t i; \ | ||
558 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
559 | return; \ | ||
560 | } \ | ||
561 | for (i = 0; i < vl; i++) { \ | ||
562 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
563 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
564 | continue; \ | ||
565 | } \ | ||
566 | do_##NAME(vd, vs2, i, env); \ | ||
567 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfsgnjx_vf_d, 8, 8, clearq) | ||
568 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
569 | CPURISCVState *env, uint32_t desc) \ | ||
570 | { \ | ||
571 | - uint32_t mlen = vext_mlen(desc); \ | ||
572 | uint32_t vm = vext_vm(desc); \ | ||
573 | uint32_t vl = env->vl; \ | ||
574 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
575 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
576 | for (i = 0; i < vl; i++) { \ | ||
577 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
578 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
579 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
580 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
581 | continue; \ | ||
582 | } \ | ||
583 | - vext_set_elem_mask(vd, mlen, i, \ | ||
584 | + vext_set_elem_mask(vd, i, \ | ||
585 | DO_OP(s2, s1, &env->fp_status)); \ | ||
586 | } \ | ||
587 | for (; i < vlmax; i++) { \ | ||
588 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
589 | + vext_set_elem_mask(vd, i, 0); \ | ||
590 | } \ | ||
591 | } | ||
592 | |||
593 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VV_ENV(vmfeq_vv_d, uint64_t, H8, float64_eq_quiet) | ||
594 | void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
595 | CPURISCVState *env, uint32_t desc) \ | ||
596 | { \ | ||
597 | - uint32_t mlen = vext_mlen(desc); \ | ||
598 | uint32_t vm = vext_vm(desc); \ | ||
599 | uint32_t vl = env->vl; \ | ||
600 | uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
601 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
602 | \ | ||
603 | for (i = 0; i < vl; i++) { \ | ||
604 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
605 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
606 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
607 | continue; \ | ||
608 | } \ | ||
609 | - vext_set_elem_mask(vd, mlen, i, \ | ||
610 | + vext_set_elem_mask(vd, i, \ | ||
611 | DO_OP(s2, (ETYPE)s1, &env->fp_status)); \ | ||
612 | } \ | ||
613 | for (; i < vlmax; i++) { \ | ||
614 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
615 | + vext_set_elem_mask(vd, i, 0); \ | ||
616 | } \ | ||
617 | } | ||
618 | |||
619 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
620 | CPURISCVState *env, uint32_t desc) \ | ||
621 | { \ | ||
622 | uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
623 | - uint32_t mlen = vext_mlen(desc); \ | ||
624 | uint32_t vm = vext_vm(desc); \ | ||
625 | uint32_t vl = env->vl; \ | ||
626 | uint32_t i; \ | ||
627 | \ | ||
628 | for (i = 0; i < vl; i++) { \ | ||
629 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
630 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
631 | continue; \ | ||
632 | } \ | ||
633 | do_##NAME(vd, vs2, i); \ | ||
634 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V(vfclass_v_d, 8, 8, clearq) | ||
635 | void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
636 | CPURISCVState *env, uint32_t desc) \ | ||
637 | { \ | ||
638 | - uint32_t mlen = vext_mlen(desc); \ | ||
639 | uint32_t vm = vext_vm(desc); \ | ||
640 | uint32_t vl = env->vl; \ | ||
641 | uint32_t esz = sizeof(ETYPE); \ | ||
642 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
643 | for (i = 0; i < vl; i++) { \ | ||
644 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
645 | *((ETYPE *)vd + H(i)) \ | ||
646 | - = (!vm && !vext_elem_mask(v0, mlen, i) ? s2 : s1); \ | ||
647 | + = (!vm && !vext_elem_mask(v0, i) ? s2 : s1); \ | ||
648 | } \ | ||
649 | CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
650 | } | ||
651 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4, clearl) | ||
652 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
653 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
654 | { \ | ||
655 | - uint32_t mlen = vext_mlen(desc); \ | ||
656 | uint32_t vm = vext_vm(desc); \ | ||
657 | uint32_t vl = env->vl; \ | ||
658 | uint32_t i; \ | ||
659 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
660 | \ | ||
661 | for (i = 0; i < vl; i++) { \ | ||
662 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
663 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
664 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
665 | continue; \ | ||
666 | } \ | ||
667 | s1 = OP(s1, (TD)s2); \ | ||
668 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
669 | void *vs2, CPURISCVState *env, \ | ||
670 | uint32_t desc) \ | ||
671 | { \ | ||
672 | - uint32_t mlen = vext_mlen(desc); \ | ||
673 | uint32_t vm = vext_vm(desc); \ | ||
674 | uint32_t vl = env->vl; \ | ||
675 | uint32_t i; \ | ||
676 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
677 | \ | ||
678 | for (i = 0; i < vl; i++) { \ | ||
679 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
680 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
681 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
682 | continue; \ | ||
683 | } \ | ||
684 | s1 = OP(s1, (TD)s2, &env->fp_status); \ | ||
685 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum, clearq) | ||
686 | void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
687 | void *vs2, CPURISCVState *env, uint32_t desc) | ||
688 | { | ||
689 | - uint32_t mlen = vext_mlen(desc); | ||
690 | uint32_t vm = vext_vm(desc); | ||
691 | uint32_t vl = env->vl; | ||
692 | uint32_t i; | ||
693 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
694 | |||
695 | for (i = 0; i < vl; i++) { | ||
696 | uint16_t s2 = *((uint16_t *)vs2 + H2(i)); | ||
697 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
698 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
699 | continue; | ||
700 | } | ||
701 | s1 = float32_add(s1, float16_to_float32(s2, true, &env->fp_status), | ||
702 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
703 | void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
704 | void *vs2, CPURISCVState *env, uint32_t desc) | ||
705 | { | ||
706 | - uint32_t mlen = vext_mlen(desc); | ||
707 | uint32_t vm = vext_vm(desc); | ||
708 | uint32_t vl = env->vl; | ||
709 | uint32_t i; | ||
710 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
711 | |||
712 | for (i = 0; i < vl; i++) { | ||
713 | uint32_t s2 = *((uint32_t *)vs2 + H4(i)); | ||
714 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
715 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
716 | continue; | ||
717 | } | ||
718 | s1 = float64_add(s1, float32_to_float64(s2, &env->fp_status), | ||
719 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
720 | void *vs2, CPURISCVState *env, \ | ||
721 | uint32_t desc) \ | ||
722 | { \ | ||
723 | - uint32_t mlen = vext_mlen(desc); \ | ||
724 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
725 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
726 | uint32_t vl = env->vl; \ | ||
727 | uint32_t i; \ | ||
728 | int a, b; \ | ||
729 | \ | ||
730 | for (i = 0; i < vl; i++) { \ | ||
731 | - a = vext_elem_mask(vs1, mlen, i); \ | ||
732 | - b = vext_elem_mask(vs2, mlen, i); \ | ||
733 | - vext_set_elem_mask(vd, mlen, i, OP(b, a)); \ | ||
734 | + a = vext_elem_mask(vs1, i); \ | ||
735 | + b = vext_elem_mask(vs2, i); \ | ||
736 | + vext_set_elem_mask(vd, i, OP(b, a)); \ | ||
737 | } \ | ||
738 | for (; i < vlmax; i++) { \ | ||
739 | - vext_set_elem_mask(vd, mlen, i, 0); \ | ||
740 | + vext_set_elem_mask(vd, i, 0); \ | ||
741 | } \ | ||
742 | } | ||
743 | |||
744 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env, | ||
745 | uint32_t desc) | ||
746 | { | ||
747 | target_ulong cnt = 0; | ||
748 | - uint32_t mlen = vext_mlen(desc); | ||
749 | uint32_t vm = vext_vm(desc); | ||
750 | uint32_t vl = env->vl; | ||
751 | int i; | ||
752 | |||
753 | for (i = 0; i < vl; i++) { | ||
754 | - if (vm || vext_elem_mask(v0, mlen, i)) { | ||
755 | - if (vext_elem_mask(vs2, mlen, i)) { | ||
756 | + if (vm || vext_elem_mask(v0, i)) { | ||
757 | + if (vext_elem_mask(vs2, i)) { | ||
758 | cnt++; | ||
759 | } | ||
760 | } | ||
761 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env, | ||
762 | target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env, | ||
763 | uint32_t desc) | ||
764 | { | ||
765 | - uint32_t mlen = vext_mlen(desc); | ||
766 | uint32_t vm = vext_vm(desc); | ||
767 | uint32_t vl = env->vl; | ||
768 | int i; | ||
769 | |||
770 | for (i = 0; i < vl; i++) { | ||
771 | - if (vm || vext_elem_mask(v0, mlen, i)) { | ||
772 | - if (vext_elem_mask(vs2, mlen, i)) { | ||
773 | + if (vm || vext_elem_mask(v0, i)) { | ||
774 | + if (vext_elem_mask(vs2, i)) { | ||
775 | return i; | ||
776 | } | ||
777 | } | ||
778 | @@ -XXX,XX +XXX,XX @@ enum set_mask_type { | ||
779 | static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
780 | uint32_t desc, enum set_mask_type type) | ||
781 | { | ||
782 | - uint32_t mlen = vext_mlen(desc); | ||
783 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; | ||
784 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; | ||
785 | uint32_t vm = vext_vm(desc); | ||
786 | uint32_t vl = env->vl; | ||
787 | int i; | ||
788 | bool first_mask_bit = false; | ||
789 | |||
790 | for (i = 0; i < vl; i++) { | ||
791 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { | ||
792 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
793 | continue; | ||
794 | } | ||
795 | /* write a zero to all following active elements */ | ||
796 | if (first_mask_bit) { | ||
797 | - vext_set_elem_mask(vd, mlen, i, 0); | ||
798 | + vext_set_elem_mask(vd, i, 0); | ||
799 | continue; | ||
800 | } | ||
801 | - if (vext_elem_mask(vs2, mlen, i)) { | ||
802 | + if (vext_elem_mask(vs2, i)) { | ||
803 | first_mask_bit = true; | ||
804 | if (type == BEFORE_FIRST) { | ||
805 | - vext_set_elem_mask(vd, mlen, i, 0); | ||
806 | + vext_set_elem_mask(vd, i, 0); | ||
807 | } else { | ||
808 | - vext_set_elem_mask(vd, mlen, i, 1); | ||
809 | + vext_set_elem_mask(vd, i, 1); | ||
810 | } | ||
811 | } else { | ||
812 | if (type == ONLY_FIRST) { | ||
813 | - vext_set_elem_mask(vd, mlen, i, 0); | ||
814 | + vext_set_elem_mask(vd, i, 0); | ||
815 | } else { | ||
816 | - vext_set_elem_mask(vd, mlen, i, 1); | ||
817 | + vext_set_elem_mask(vd, i, 1); | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | for (; i < vlmax; i++) { | ||
822 | - vext_set_elem_mask(vd, mlen, i, 0); | ||
823 | + vext_set_elem_mask(vd, i, 0); | ||
824 | } | ||
825 | } | ||
826 | |||
827 | @@ -XXX,XX +XXX,XX @@ void HELPER(vmsof_m)(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
828 | void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
829 | uint32_t desc) \ | ||
830 | { \ | ||
831 | - uint32_t mlen = vext_mlen(desc); \ | ||
832 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
833 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
834 | uint32_t vm = vext_vm(desc); \ | ||
835 | uint32_t vl = env->vl; \ | ||
836 | uint32_t sum = 0; \ | ||
837 | int i; \ | ||
838 | \ | ||
839 | for (i = 0; i < vl; i++) { \ | ||
840 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
841 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
842 | continue; \ | ||
843 | } \ | ||
844 | *((ETYPE *)vd + H(i)) = sum; \ | ||
845 | - if (vext_elem_mask(vs2, mlen, i)) { \ | ||
846 | + if (vext_elem_mask(vs2, i)) { \ | ||
847 | sum++; \ | ||
848 | } \ | ||
849 | } \ | ||
850 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VIOTA_M(viota_m_d, uint64_t, H8, clearq) | ||
851 | #define GEN_VEXT_VID_V(NAME, ETYPE, H, CLEAR_FN) \ | ||
852 | void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
853 | { \ | ||
854 | - uint32_t mlen = vext_mlen(desc); \ | ||
855 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
856 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
857 | uint32_t vm = vext_vm(desc); \ | ||
858 | uint32_t vl = env->vl; \ | ||
859 | int i; \ | ||
860 | \ | ||
861 | for (i = 0; i < vl; i++) { \ | ||
862 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
863 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
864 | continue; \ | ||
865 | } \ | ||
866 | *((ETYPE *)vd + H(i)) = i; \ | ||
867 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VID_V(vid_v_d, uint64_t, H8, clearq) | ||
868 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
869 | CPURISCVState *env, uint32_t desc) \ | ||
870 | { \ | ||
871 | - uint32_t mlen = vext_mlen(desc); \ | ||
872 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
873 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
874 | uint32_t vm = vext_vm(desc); \ | ||
875 | uint32_t vl = env->vl; \ | ||
876 | target_ulong offset = s1, i; \ | ||
877 | \ | ||
878 | for (i = offset; i < vl; i++) { \ | ||
879 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
880 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
881 | continue; \ | ||
882 | } \ | ||
883 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \ | ||
884 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8, clearq) | ||
885 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
886 | CPURISCVState *env, uint32_t desc) \ | ||
887 | { \ | ||
888 | - uint32_t mlen = vext_mlen(desc); \ | ||
889 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
890 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
891 | uint32_t vm = vext_vm(desc); \ | ||
892 | uint32_t vl = env->vl; \ | ||
893 | target_ulong offset = s1, i; \ | ||
894 | \ | ||
895 | for (i = 0; i < vl; ++i) { \ | ||
896 | target_ulong j = i + offset; \ | ||
897 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
898 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
899 | continue; \ | ||
900 | } \ | ||
901 | *((ETYPE *)vd + H(i)) = j >= vlmax ? 0 : *((ETYPE *)vs2 + H(j)); \ | ||
902 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8, clearq) | ||
903 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
904 | CPURISCVState *env, uint32_t desc) \ | ||
905 | { \ | ||
906 | - uint32_t mlen = vext_mlen(desc); \ | ||
907 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
908 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
909 | uint32_t vm = vext_vm(desc); \ | ||
910 | uint32_t vl = env->vl; \ | ||
911 | uint32_t i; \ | ||
912 | \ | ||
913 | for (i = 0; i < vl; i++) { \ | ||
914 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
915 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
916 | continue; \ | ||
917 | } \ | ||
918 | if (i == 0) { \ | ||
919 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, uint64_t, H8, clearq) | ||
920 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
921 | CPURISCVState *env, uint32_t desc) \ | ||
922 | { \ | ||
923 | - uint32_t mlen = vext_mlen(desc); \ | ||
924 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
925 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
926 | uint32_t vm = vext_vm(desc); \ | ||
927 | uint32_t vl = env->vl; \ | ||
928 | uint32_t i; \ | ||
929 | \ | ||
930 | for (i = 0; i < vl; i++) { \ | ||
931 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
932 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
933 | continue; \ | ||
934 | } \ | ||
935 | if (i == vl - 1) { \ | ||
936 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8, clearq) | ||
937 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
938 | CPURISCVState *env, uint32_t desc) \ | ||
939 | { \ | ||
940 | - uint32_t mlen = vext_mlen(desc); \ | ||
941 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
942 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
943 | uint32_t vm = vext_vm(desc); \ | ||
944 | uint32_t vl = env->vl; \ | ||
945 | uint64_t index; \ | ||
946 | uint32_t i; \ | ||
947 | \ | ||
948 | for (i = 0; i < vl; i++) { \ | ||
949 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
950 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
951 | continue; \ | ||
952 | } \ | ||
953 | index = *((ETYPE *)vs1 + H(i)); \ | ||
954 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8, clearq) | ||
955 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
956 | CPURISCVState *env, uint32_t desc) \ | ||
957 | { \ | ||
958 | - uint32_t mlen = vext_mlen(desc); \ | ||
959 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
960 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
961 | uint32_t vm = vext_vm(desc); \ | ||
962 | uint32_t vl = env->vl; \ | ||
963 | uint64_t index = s1; \ | ||
964 | uint32_t i; \ | ||
965 | \ | ||
966 | for (i = 0; i < vl; i++) { \ | ||
967 | - if (!vm && !vext_elem_mask(v0, mlen, i)) { \ | ||
968 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
969 | continue; \ | ||
970 | } \ | ||
971 | if (index >= vlmax) { \ | ||
972 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VRGATHER_VX(vrgather_vx_d, uint64_t, H8, clearq) | ||
973 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
974 | CPURISCVState *env, uint32_t desc) \ | ||
975 | { \ | ||
976 | - uint32_t mlen = vext_mlen(desc); \ | ||
977 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \ | ||
978 | + uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
979 | uint32_t vl = env->vl; \ | ||
980 | uint32_t num = 0, i; \ | ||
981 | \ | ||
982 | for (i = 0; i < vl; i++) { \ | ||
983 | - if (!vext_elem_mask(vs1, mlen, i)) { \ | ||
984 | + if (!vext_elem_mask(vs1, i)) { \ | ||
985 | continue; \ | ||
986 | } \ | ||
987 | *((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i)); \ | ||
988 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
989 | index XXXXXXX..XXXXXXX 100644 | ||
990 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
991 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
992 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
993 | return false; | ||
994 | } | ||
995 | |||
996 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
997 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
998 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
999 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1000 | @@ -XXX,XX +XXX,XX @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
1001 | return false; | ||
1002 | } | ||
1003 | |||
1004 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1005 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1006 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1007 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1008 | @@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
1009 | return false; | ||
1010 | } | ||
1011 | |||
1012 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1013 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1014 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1015 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1016 | @@ -XXX,XX +XXX,XX @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
1017 | gen_helper_vsse_v_w, gen_helper_vsse_v_d } | ||
1018 | }; | ||
1019 | |||
1020 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1021 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1022 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1023 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1024 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
1025 | return false; | ||
1026 | } | ||
1027 | |||
1028 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1029 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1030 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1031 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1032 | @@ -XXX,XX +XXX,XX @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
1033 | return false; | ||
1034 | } | ||
1035 | |||
1036 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1037 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1038 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1039 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1040 | @@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
1041 | return false; | ||
1042 | } | ||
1043 | |||
1044 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1045 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1046 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1047 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
1048 | @@ -XXX,XX +XXX,XX @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq) | ||
1049 | g_assert_not_reached(); | ||
1050 | } | ||
1051 | |||
1052 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1053 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1054 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1055 | data = FIELD_DP32(data, VDATA, WD, a->wd); | ||
1056 | @@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn, | ||
1057 | } else { | ||
1058 | uint32_t data = 0; | ||
1059 | |||
1060 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1061 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1062 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1063 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
1064 | @@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm, | ||
1065 | src2 = tcg_temp_new_ptr(); | ||
1066 | src1 = get_gpr(s, rs1, EXT_NONE); | ||
1067 | |||
1068 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1069 | data = FIELD_DP32(data, VDATA, VM, vm); | ||
1070 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1071 | desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
1072 | @@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
1073 | } else { | ||
1074 | src1 = tcg_constant_tl(sextract64(imm, 0, 5)); | ||
1075 | } | ||
1076 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1077 | data = FIELD_DP32(data, VDATA, VM, vm); | ||
1078 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1079 | desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
1080 | @@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a, | ||
1081 | TCGLabel *over = gen_new_label(); | ||
1082 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
1083 | |||
1084 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1085 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1086 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1087 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
1088 | @@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a, | ||
1089 | TCGLabel *over = gen_new_label(); | ||
1090 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
1091 | |||
1092 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1093 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1094 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1095 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
1096 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1097 | TCGLabel *over = gen_new_label(); \ | ||
1098 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1099 | \ | ||
1100 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1101 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1102 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1103 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1104 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1105 | TCGLabel *over = gen_new_label(); \ | ||
1106 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1107 | \ | ||
1108 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1109 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1110 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1111 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1112 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1113 | gen_set_rm(s, 7); \ | ||
1114 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1115 | \ | ||
1116 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1117 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1118 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1119 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1120 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1121 | gen_helper_##NAME##_d, \ | ||
1122 | }; \ | ||
1123 | gen_set_rm(s, 7); \ | ||
1124 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1125 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1126 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1127 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
1128 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1129 | gen_set_rm(s, 7); \ | ||
1130 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1131 | \ | ||
1132 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1133 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1134 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1135 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1136 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1137 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
1138 | }; \ | ||
1139 | gen_set_rm(s, 7); \ | ||
1140 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1141 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1142 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1143 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
1144 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1145 | gen_set_rm(s, 7); \ | ||
1146 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1147 | \ | ||
1148 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1149 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1150 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1151 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1152 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
1153 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
1154 | }; \ | ||
1155 | gen_set_rm(s, 7); \ | ||
1156 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1157 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1158 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1159 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
1160 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
1161 | gen_set_rm(s, 7); \ | ||
1162 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1163 | \ | ||
1164 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1165 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1166 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1167 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1168 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
1169 | gen_set_rm(s, 7); \ | ||
1170 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1171 | \ | ||
1172 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1173 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1174 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1175 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1176 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
1177 | gen_set_rm(s, 7); \ | ||
1178 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1179 | \ | ||
1180 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1181 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1182 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1183 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1184 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \ | ||
1185 | TCGLabel *over = gen_new_label(); \ | ||
1186 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1187 | \ | ||
1188 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1189 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1190 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
1191 | vreg_ofs(s, a->rs1), \ | ||
1192 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a) | ||
1193 | TCGv dst; | ||
1194 | TCGv_i32 desc; | ||
1195 | uint32_t data = 0; | ||
1196 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1197 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1198 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1199 | |||
1200 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a) | ||
1201 | TCGv dst; | ||
1202 | TCGv_i32 desc; | ||
1203 | uint32_t data = 0; | ||
1204 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1205 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1206 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1207 | |||
1208 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
1209 | TCGLabel *over = gen_new_label(); \ | ||
1210 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
1211 | \ | ||
1212 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \ | ||
1213 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
1214 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
1215 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \ | ||
1216 | @@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
1217 | TCGLabel *over = gen_new_label(); | ||
1218 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
1219 | |||
1220 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1221 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1222 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1223 | static gen_helper_gvec_3_ptr * const fns[4] = { | ||
1224 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
1225 | TCGLabel *over = gen_new_label(); | ||
1226 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
1227 | |||
1228 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1229 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
1230 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1231 | static gen_helper_gvec_2_ptr * const fns[4] = { | ||
1232 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a) | ||
1233 | } | ||
1234 | |||
1235 | if (a->vm && s->vl_eq_vlmax) { | ||
1236 | - int vlmax = s->vlen / s->mlen; | ||
1237 | + int vlmax = s->vlen; | ||
1238 | TCGv_i64 dest = tcg_temp_new_i64(); | ||
1239 | |||
1240 | if (a->rs1 == 0) { | ||
1241 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) | ||
1242 | } | ||
1243 | |||
1244 | if (a->vm && s->vl_eq_vlmax) { | ||
1245 | - if (a->rs1 >= s->vlen / s->mlen) { | ||
1246 | + if (a->rs1 >= s->vlen) { | ||
1247 | tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), | ||
1248 | MAXSZ(s), MAXSZ(s), 0); | ||
1249 | } else { | ||
1250 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
1251 | TCGLabel *over = gen_new_label(); | ||
1252 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
1253 | |||
1254 | - data = FIELD_DP32(data, VDATA, MLEN, s->mlen); | ||
1255 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
1256 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
1257 | vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), | ||
1258 | -- | ||
1259 | 2.31.1 | ||
1260 | |||
1261 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Introduce the concepts of fractional LMUL for RVV 1.0. | ||
4 | In RVV 1.0, LMUL bits are contiguous in vtype register. | ||
5 | |||
6 | Also rearrange rvv bits in TB_FLAGS to skip MSTATUS_VS (0x600) | ||
7 | and MSTATUS_FS (0x6000) bits. | ||
8 | |||
9 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20211210075704.23951-14-frank.chang@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/cpu.h | 26 ++++++++++++++------------ | ||
16 | target/riscv/translate.c | 16 ++++++++++++++-- | ||
17 | target/riscv/vector_helper.c | 16 ++++++++++++++-- | ||
18 | 3 files changed, 42 insertions(+), 16 deletions(-) | ||
19 | |||
20 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/cpu.h | ||
23 | +++ b/target/riscv/cpu.h | ||
24 | @@ -XXX,XX +XXX,XX @@ typedef struct CPURISCVState CPURISCVState; | ||
25 | |||
26 | #define RV_VLEN_MAX 256 | ||
27 | |||
28 | -FIELD(VTYPE, VLMUL, 0, 2) | ||
29 | -FIELD(VTYPE, VSEW, 2, 3) | ||
30 | -FIELD(VTYPE, VEDIV, 5, 2) | ||
31 | -FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9) | ||
32 | +FIELD(VTYPE, VLMUL, 0, 3) | ||
33 | +FIELD(VTYPE, VSEW, 3, 3) | ||
34 | +FIELD(VTYPE, VEDIV, 8, 2) | ||
35 | +FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11) | ||
36 | FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1) | ||
37 | |||
38 | struct CPURISCVState { | ||
39 | @@ -XXX,XX +XXX,XX @@ typedef RISCVCPU ArchCPU; | ||
40 | #include "exec/cpu-all.h" | ||
41 | |||
42 | FIELD(TB_FLAGS, MEM_IDX, 0, 3) | ||
43 | -FIELD(TB_FLAGS, VL_EQ_VLMAX, 3, 1) | ||
44 | -FIELD(TB_FLAGS, LMUL, 4, 2) | ||
45 | +FIELD(TB_FLAGS, LMUL, 3, 3) | ||
46 | FIELD(TB_FLAGS, SEW, 6, 3) | ||
47 | -FIELD(TB_FLAGS, VILL, 9, 1) | ||
48 | +/* Skip MSTATUS_VS (0x600) bits */ | ||
49 | +FIELD(TB_FLAGS, VL_EQ_VLMAX, 11, 1) | ||
50 | +FIELD(TB_FLAGS, VILL, 12, 1) | ||
51 | +/* Skip MSTATUS_FS (0x6000) bits */ | ||
52 | /* Is a Hypervisor instruction load/store allowed? */ | ||
53 | -FIELD(TB_FLAGS, HLSX, 10, 1) | ||
54 | -FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2) | ||
55 | -FIELD(TB_FLAGS, MSTATUS_HS_VS, 13, 2) | ||
56 | +FIELD(TB_FLAGS, HLSX, 15, 1) | ||
57 | +FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2) | ||
58 | +FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2) | ||
59 | /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */ | ||
60 | -FIELD(TB_FLAGS, XL, 15, 2) | ||
61 | +FIELD(TB_FLAGS, XL, 20, 2) | ||
62 | /* If PointerMasking should be applied */ | ||
63 | -FIELD(TB_FLAGS, PM_ENABLED, 17, 1) | ||
64 | +FIELD(TB_FLAGS, PM_ENABLED, 22, 1) | ||
65 | |||
66 | #ifdef TARGET_RISCV32 | ||
67 | #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) | ||
68 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/translate.c | ||
71 | +++ b/target/riscv/translate.c | ||
72 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
73 | bool hlsx; | ||
74 | /* vector extension */ | ||
75 | bool vill; | ||
76 | - uint8_t lmul; | ||
77 | + /* | ||
78 | + * Encode LMUL to lmul as follows: | ||
79 | + * LMUL vlmul lmul | ||
80 | + * 1 000 0 | ||
81 | + * 2 001 1 | ||
82 | + * 4 010 2 | ||
83 | + * 8 011 3 | ||
84 | + * - 100 - | ||
85 | + * 1/8 101 -3 | ||
86 | + * 1/4 110 -2 | ||
87 | + * 1/2 111 -1 | ||
88 | + */ | ||
89 | + int8_t lmul; | ||
90 | uint8_t sew; | ||
91 | uint16_t vlen; | ||
92 | bool vl_eq_vlmax; | ||
93 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
94 | ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); | ||
95 | ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL); | ||
96 | ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); | ||
97 | - ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL); | ||
98 | + ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3); | ||
99 | ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); | ||
100 | ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); | ||
101 | ctx->cs = cs; | ||
102 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
103 | index XXXXXXX..XXXXXXX 100644 | ||
104 | --- a/target/riscv/vector_helper.c | ||
105 | +++ b/target/riscv/vector_helper.c | ||
106 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_vm(uint32_t desc) | ||
107 | return FIELD_EX32(simd_data(desc), VDATA, VM); | ||
108 | } | ||
109 | |||
110 | -static inline uint32_t vext_lmul(uint32_t desc) | ||
111 | +/* | ||
112 | + * Encode LMUL to lmul as following: | ||
113 | + * LMUL vlmul lmul | ||
114 | + * 1 000 0 | ||
115 | + * 2 001 1 | ||
116 | + * 4 010 2 | ||
117 | + * 8 011 3 | ||
118 | + * - 100 - | ||
119 | + * 1/8 101 -3 | ||
120 | + * 1/4 110 -2 | ||
121 | + * 1/2 111 -1 | ||
122 | + */ | ||
123 | +static inline int32_t vext_lmul(uint32_t desc) | ||
124 | { | ||
125 | - return FIELD_EX32(simd_data(desc), VDATA, LMUL); | ||
126 | + return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3); | ||
127 | } | ||
128 | |||
129 | static uint32_t vext_wd(uint32_t desc) | ||
130 | -- | ||
131 | 2.31.1 | ||
132 | |||
133 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Introduce vma and vta fields in vtype register. | ||
4 | |||
5 | According to RVV 1.0 spec (section 3.3.3): | ||
6 | |||
7 | When a set is marked agnostic, the corresponding set of destination | ||
8 | elements in any vector or mask destination operand can either retain | ||
9 | the value they previously held, or are overwritten with 1s. | ||
10 | |||
11 | So, either vta/vma is set to undisturbed or agnostic, it's legal to | ||
12 | retain the inactive masked-off elements and tail elements' original | ||
13 | values unchanged. Therefore, besides declaring vta/vma fields in vtype | ||
14 | register, also remove all the tail elements clean functions in this | ||
15 | commit. | ||
16 | |||
17 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
18 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | Message-Id: <20211210075704.23951-15-frank.chang@sifive.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | --- | ||
23 | target/riscv/cpu.h | 2 + | ||
24 | target/riscv/vector_helper.c | 1927 ++++++++++++++++------------------ | ||
25 | 2 files changed, 891 insertions(+), 1038 deletions(-) | ||
26 | |||
27 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/riscv/cpu.h | ||
30 | +++ b/target/riscv/cpu.h | ||
31 | @@ -XXX,XX +XXX,XX @@ typedef struct CPURISCVState CPURISCVState; | ||
32 | |||
33 | FIELD(VTYPE, VLMUL, 0, 3) | ||
34 | FIELD(VTYPE, VSEW, 3, 3) | ||
35 | +FIELD(VTYPE, VTA, 6, 1) | ||
36 | +FIELD(VTYPE, VMA, 7, 1) | ||
37 | FIELD(VTYPE, VEDIV, 8, 2) | ||
38 | FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11) | ||
39 | FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1) | ||
40 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/riscv/vector_helper.c | ||
43 | +++ b/target/riscv/vector_helper.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr, | ||
45 | } | ||
46 | } | ||
47 | |||
48 | -#ifdef HOST_WORDS_BIGENDIAN | ||
49 | -static void vext_clear(void *tail, uint32_t cnt, uint32_t tot) | ||
50 | -{ | ||
51 | - /* | ||
52 | - * Split the remaining range to two parts. | ||
53 | - * The first part is in the last uint64_t unit. | ||
54 | - * The second part start from the next uint64_t unit. | ||
55 | - */ | ||
56 | - int part1 = 0, part2 = tot - cnt; | ||
57 | - if (cnt % 8) { | ||
58 | - part1 = 8 - (cnt % 8); | ||
59 | - part2 = tot - cnt - part1; | ||
60 | - memset(QEMU_ALIGN_PTR_DOWN(tail, 8), 0, part1); | ||
61 | - memset(QEMU_ALIGN_PTR_UP(tail, 8), 0, part2); | ||
62 | - } else { | ||
63 | - memset(tail, 0, part2); | ||
64 | - } | ||
65 | -} | ||
66 | -#else | ||
67 | -static void vext_clear(void *tail, uint32_t cnt, uint32_t tot) | ||
68 | -{ | ||
69 | - memset(tail, 0, tot - cnt); | ||
70 | -} | ||
71 | -#endif | ||
72 | - | ||
73 | -static void clearb(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot) | ||
74 | -{ | ||
75 | - int8_t *cur = ((int8_t *)vd + H1(idx)); | ||
76 | - vext_clear(cur, cnt, tot); | ||
77 | -} | ||
78 | - | ||
79 | -static void clearh(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot) | ||
80 | -{ | ||
81 | - int16_t *cur = ((int16_t *)vd + H2(idx)); | ||
82 | - vext_clear(cur, cnt, tot); | ||
83 | -} | ||
84 | - | ||
85 | -static void clearl(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot) | ||
86 | -{ | ||
87 | - int32_t *cur = ((int32_t *)vd + H4(idx)); | ||
88 | - vext_clear(cur, cnt, tot); | ||
89 | -} | ||
90 | - | ||
91 | -static void clearq(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot) | ||
92 | -{ | ||
93 | - int64_t *cur = (int64_t *)vd + idx; | ||
94 | - vext_clear(cur, cnt, tot); | ||
95 | -} | ||
96 | - | ||
97 | static inline void vext_set_elem_mask(void *v0, int index, | ||
98 | uint8_t value) | ||
99 | { | ||
100 | @@ -XXX,XX +XXX,XX @@ static inline int vext_elem_mask(void *v0, int index) | ||
101 | /* elements operations for load and store */ | ||
102 | typedef void vext_ldst_elem_fn(CPURISCVState *env, target_ulong addr, | ||
103 | uint32_t idx, void *vd, uintptr_t retaddr); | ||
104 | -typedef void clear_fn(void *vd, uint32_t idx, uint32_t cnt, uint32_t tot); | ||
105 | |||
106 | #define GEN_VEXT_LD_ELEM(NAME, MTYPE, ETYPE, H, LDSUF) \ | ||
107 | static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
108 | @@ -XXX,XX +XXX,XX @@ static void | ||
109 | vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
110 | target_ulong stride, CPURISCVState *env, | ||
111 | uint32_t desc, uint32_t vm, | ||
112 | - vext_ldst_elem_fn *ldst_elem, clear_fn *clear_elem, | ||
113 | + vext_ldst_elem_fn *ldst_elem, | ||
114 | uint32_t esz, uint32_t msz, uintptr_t ra, | ||
115 | MMUAccessType access_type) | ||
116 | { | ||
117 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
118 | k++; | ||
119 | } | ||
120 | } | ||
121 | - /* clear tail elements */ | ||
122 | - if (clear_elem) { | ||
123 | - for (k = 0; k < nf; k++) { | ||
124 | - clear_elem(vd, env->vl + k * vlmax, env->vl * esz, vlmax * esz); | ||
125 | - } | ||
126 | - } | ||
127 | } | ||
128 | |||
129 | -#define GEN_VEXT_LD_STRIDE(NAME, MTYPE, ETYPE, LOAD_FN, CLEAR_FN) \ | ||
130 | +#define GEN_VEXT_LD_STRIDE(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
131 | void HELPER(NAME)(void *vd, void * v0, target_ulong base, \ | ||
132 | target_ulong stride, CPURISCVState *env, \ | ||
133 | uint32_t desc) \ | ||
134 | { \ | ||
135 | uint32_t vm = vext_vm(desc); \ | ||
136 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \ | ||
137 | - CLEAR_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
138 | + sizeof(ETYPE), sizeof(MTYPE), \ | ||
139 | GETPC(), MMU_DATA_LOAD); \ | ||
140 | } | ||
141 | |||
142 | -GEN_VEXT_LD_STRIDE(vlsb_v_b, int8_t, int8_t, ldb_b, clearb) | ||
143 | -GEN_VEXT_LD_STRIDE(vlsb_v_h, int8_t, int16_t, ldb_h, clearh) | ||
144 | -GEN_VEXT_LD_STRIDE(vlsb_v_w, int8_t, int32_t, ldb_w, clearl) | ||
145 | -GEN_VEXT_LD_STRIDE(vlsb_v_d, int8_t, int64_t, ldb_d, clearq) | ||
146 | -GEN_VEXT_LD_STRIDE(vlsh_v_h, int16_t, int16_t, ldh_h, clearh) | ||
147 | -GEN_VEXT_LD_STRIDE(vlsh_v_w, int16_t, int32_t, ldh_w, clearl) | ||
148 | -GEN_VEXT_LD_STRIDE(vlsh_v_d, int16_t, int64_t, ldh_d, clearq) | ||
149 | -GEN_VEXT_LD_STRIDE(vlsw_v_w, int32_t, int32_t, ldw_w, clearl) | ||
150 | -GEN_VEXT_LD_STRIDE(vlsw_v_d, int32_t, int64_t, ldw_d, clearq) | ||
151 | -GEN_VEXT_LD_STRIDE(vlse_v_b, int8_t, int8_t, lde_b, clearb) | ||
152 | -GEN_VEXT_LD_STRIDE(vlse_v_h, int16_t, int16_t, lde_h, clearh) | ||
153 | -GEN_VEXT_LD_STRIDE(vlse_v_w, int32_t, int32_t, lde_w, clearl) | ||
154 | -GEN_VEXT_LD_STRIDE(vlse_v_d, int64_t, int64_t, lde_d, clearq) | ||
155 | -GEN_VEXT_LD_STRIDE(vlsbu_v_b, uint8_t, uint8_t, ldbu_b, clearb) | ||
156 | -GEN_VEXT_LD_STRIDE(vlsbu_v_h, uint8_t, uint16_t, ldbu_h, clearh) | ||
157 | -GEN_VEXT_LD_STRIDE(vlsbu_v_w, uint8_t, uint32_t, ldbu_w, clearl) | ||
158 | -GEN_VEXT_LD_STRIDE(vlsbu_v_d, uint8_t, uint64_t, ldbu_d, clearq) | ||
159 | -GEN_VEXT_LD_STRIDE(vlshu_v_h, uint16_t, uint16_t, ldhu_h, clearh) | ||
160 | -GEN_VEXT_LD_STRIDE(vlshu_v_w, uint16_t, uint32_t, ldhu_w, clearl) | ||
161 | -GEN_VEXT_LD_STRIDE(vlshu_v_d, uint16_t, uint64_t, ldhu_d, clearq) | ||
162 | -GEN_VEXT_LD_STRIDE(vlswu_v_w, uint32_t, uint32_t, ldwu_w, clearl) | ||
163 | -GEN_VEXT_LD_STRIDE(vlswu_v_d, uint32_t, uint64_t, ldwu_d, clearq) | ||
164 | +GEN_VEXT_LD_STRIDE(vlsb_v_b, int8_t, int8_t, ldb_b) | ||
165 | +GEN_VEXT_LD_STRIDE(vlsb_v_h, int8_t, int16_t, ldb_h) | ||
166 | +GEN_VEXT_LD_STRIDE(vlsb_v_w, int8_t, int32_t, ldb_w) | ||
167 | +GEN_VEXT_LD_STRIDE(vlsb_v_d, int8_t, int64_t, ldb_d) | ||
168 | +GEN_VEXT_LD_STRIDE(vlsh_v_h, int16_t, int16_t, ldh_h) | ||
169 | +GEN_VEXT_LD_STRIDE(vlsh_v_w, int16_t, int32_t, ldh_w) | ||
170 | +GEN_VEXT_LD_STRIDE(vlsh_v_d, int16_t, int64_t, ldh_d) | ||
171 | +GEN_VEXT_LD_STRIDE(vlsw_v_w, int32_t, int32_t, ldw_w) | ||
172 | +GEN_VEXT_LD_STRIDE(vlsw_v_d, int32_t, int64_t, ldw_d) | ||
173 | +GEN_VEXT_LD_STRIDE(vlse_v_b, int8_t, int8_t, lde_b) | ||
174 | +GEN_VEXT_LD_STRIDE(vlse_v_h, int16_t, int16_t, lde_h) | ||
175 | +GEN_VEXT_LD_STRIDE(vlse_v_w, int32_t, int32_t, lde_w) | ||
176 | +GEN_VEXT_LD_STRIDE(vlse_v_d, int64_t, int64_t, lde_d) | ||
177 | +GEN_VEXT_LD_STRIDE(vlsbu_v_b, uint8_t, uint8_t, ldbu_b) | ||
178 | +GEN_VEXT_LD_STRIDE(vlsbu_v_h, uint8_t, uint16_t, ldbu_h) | ||
179 | +GEN_VEXT_LD_STRIDE(vlsbu_v_w, uint8_t, uint32_t, ldbu_w) | ||
180 | +GEN_VEXT_LD_STRIDE(vlsbu_v_d, uint8_t, uint64_t, ldbu_d) | ||
181 | +GEN_VEXT_LD_STRIDE(vlshu_v_h, uint16_t, uint16_t, ldhu_h) | ||
182 | +GEN_VEXT_LD_STRIDE(vlshu_v_w, uint16_t, uint32_t, ldhu_w) | ||
183 | +GEN_VEXT_LD_STRIDE(vlshu_v_d, uint16_t, uint64_t, ldhu_d) | ||
184 | +GEN_VEXT_LD_STRIDE(vlswu_v_w, uint32_t, uint32_t, ldwu_w) | ||
185 | +GEN_VEXT_LD_STRIDE(vlswu_v_d, uint32_t, uint64_t, ldwu_d) | ||
186 | |||
187 | #define GEN_VEXT_ST_STRIDE(NAME, MTYPE, ETYPE, STORE_FN) \ | ||
188 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
189 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
190 | { \ | ||
191 | uint32_t vm = vext_vm(desc); \ | ||
192 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN, \ | ||
193 | - NULL, sizeof(ETYPE), sizeof(MTYPE), \ | ||
194 | + sizeof(ETYPE), sizeof(MTYPE), \ | ||
195 | GETPC(), MMU_DATA_STORE); \ | ||
196 | } | ||
197 | |||
198 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_STRIDE(vsse_v_d, int64_t, int64_t, ste_d) | ||
199 | /* unmasked unit-stride load and store operation*/ | ||
200 | static void | ||
201 | vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
202 | - vext_ldst_elem_fn *ldst_elem, clear_fn *clear_elem, | ||
203 | - uint32_t esz, uint32_t msz, uintptr_t ra, | ||
204 | - MMUAccessType access_type) | ||
205 | + vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t msz, | ||
206 | + uintptr_t ra, MMUAccessType access_type) | ||
207 | { | ||
208 | uint32_t i, k; | ||
209 | uint32_t nf = vext_nf(desc); | ||
210 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
211 | k++; | ||
212 | } | ||
213 | } | ||
214 | - /* clear tail elements */ | ||
215 | - if (clear_elem) { | ||
216 | - for (k = 0; k < nf; k++) { | ||
217 | - clear_elem(vd, env->vl + k * vlmax, env->vl * esz, vlmax * esz); | ||
218 | - } | ||
219 | - } | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
224 | * stride = NF * sizeof (MTYPE) | ||
225 | */ | ||
226 | |||
227 | -#define GEN_VEXT_LD_US(NAME, MTYPE, ETYPE, LOAD_FN, CLEAR_FN) \ | ||
228 | +#define GEN_VEXT_LD_US(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
229 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
230 | CPURISCVState *env, uint32_t desc) \ | ||
231 | { \ | ||
232 | uint32_t stride = vext_nf(desc) * sizeof(MTYPE); \ | ||
233 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN, \ | ||
234 | - CLEAR_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
235 | + sizeof(ETYPE), sizeof(MTYPE), \ | ||
236 | GETPC(), MMU_DATA_LOAD); \ | ||
237 | } \ | ||
238 | \ | ||
239 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
240 | CPURISCVState *env, uint32_t desc) \ | ||
241 | { \ | ||
242 | - vext_ldst_us(vd, base, env, desc, LOAD_FN, CLEAR_FN, \ | ||
243 | + vext_ldst_us(vd, base, env, desc, LOAD_FN, \ | ||
244 | sizeof(ETYPE), sizeof(MTYPE), GETPC(), MMU_DATA_LOAD); \ | ||
245 | } | ||
246 | |||
247 | -GEN_VEXT_LD_US(vlb_v_b, int8_t, int8_t, ldb_b, clearb) | ||
248 | -GEN_VEXT_LD_US(vlb_v_h, int8_t, int16_t, ldb_h, clearh) | ||
249 | -GEN_VEXT_LD_US(vlb_v_w, int8_t, int32_t, ldb_w, clearl) | ||
250 | -GEN_VEXT_LD_US(vlb_v_d, int8_t, int64_t, ldb_d, clearq) | ||
251 | -GEN_VEXT_LD_US(vlh_v_h, int16_t, int16_t, ldh_h, clearh) | ||
252 | -GEN_VEXT_LD_US(vlh_v_w, int16_t, int32_t, ldh_w, clearl) | ||
253 | -GEN_VEXT_LD_US(vlh_v_d, int16_t, int64_t, ldh_d, clearq) | ||
254 | -GEN_VEXT_LD_US(vlw_v_w, int32_t, int32_t, ldw_w, clearl) | ||
255 | -GEN_VEXT_LD_US(vlw_v_d, int32_t, int64_t, ldw_d, clearq) | ||
256 | -GEN_VEXT_LD_US(vle_v_b, int8_t, int8_t, lde_b, clearb) | ||
257 | -GEN_VEXT_LD_US(vle_v_h, int16_t, int16_t, lde_h, clearh) | ||
258 | -GEN_VEXT_LD_US(vle_v_w, int32_t, int32_t, lde_w, clearl) | ||
259 | -GEN_VEXT_LD_US(vle_v_d, int64_t, int64_t, lde_d, clearq) | ||
260 | -GEN_VEXT_LD_US(vlbu_v_b, uint8_t, uint8_t, ldbu_b, clearb) | ||
261 | -GEN_VEXT_LD_US(vlbu_v_h, uint8_t, uint16_t, ldbu_h, clearh) | ||
262 | -GEN_VEXT_LD_US(vlbu_v_w, uint8_t, uint32_t, ldbu_w, clearl) | ||
263 | -GEN_VEXT_LD_US(vlbu_v_d, uint8_t, uint64_t, ldbu_d, clearq) | ||
264 | -GEN_VEXT_LD_US(vlhu_v_h, uint16_t, uint16_t, ldhu_h, clearh) | ||
265 | -GEN_VEXT_LD_US(vlhu_v_w, uint16_t, uint32_t, ldhu_w, clearl) | ||
266 | -GEN_VEXT_LD_US(vlhu_v_d, uint16_t, uint64_t, ldhu_d, clearq) | ||
267 | -GEN_VEXT_LD_US(vlwu_v_w, uint32_t, uint32_t, ldwu_w, clearl) | ||
268 | -GEN_VEXT_LD_US(vlwu_v_d, uint32_t, uint64_t, ldwu_d, clearq) | ||
269 | +GEN_VEXT_LD_US(vlb_v_b, int8_t, int8_t, ldb_b) | ||
270 | +GEN_VEXT_LD_US(vlb_v_h, int8_t, int16_t, ldb_h) | ||
271 | +GEN_VEXT_LD_US(vlb_v_w, int8_t, int32_t, ldb_w) | ||
272 | +GEN_VEXT_LD_US(vlb_v_d, int8_t, int64_t, ldb_d) | ||
273 | +GEN_VEXT_LD_US(vlh_v_h, int16_t, int16_t, ldh_h) | ||
274 | +GEN_VEXT_LD_US(vlh_v_w, int16_t, int32_t, ldh_w) | ||
275 | +GEN_VEXT_LD_US(vlh_v_d, int16_t, int64_t, ldh_d) | ||
276 | +GEN_VEXT_LD_US(vlw_v_w, int32_t, int32_t, ldw_w) | ||
277 | +GEN_VEXT_LD_US(vlw_v_d, int32_t, int64_t, ldw_d) | ||
278 | +GEN_VEXT_LD_US(vle_v_b, int8_t, int8_t, lde_b) | ||
279 | +GEN_VEXT_LD_US(vle_v_h, int16_t, int16_t, lde_h) | ||
280 | +GEN_VEXT_LD_US(vle_v_w, int32_t, int32_t, lde_w) | ||
281 | +GEN_VEXT_LD_US(vle_v_d, int64_t, int64_t, lde_d) | ||
282 | +GEN_VEXT_LD_US(vlbu_v_b, uint8_t, uint8_t, ldbu_b) | ||
283 | +GEN_VEXT_LD_US(vlbu_v_h, uint8_t, uint16_t, ldbu_h) | ||
284 | +GEN_VEXT_LD_US(vlbu_v_w, uint8_t, uint32_t, ldbu_w) | ||
285 | +GEN_VEXT_LD_US(vlbu_v_d, uint8_t, uint64_t, ldbu_d) | ||
286 | +GEN_VEXT_LD_US(vlhu_v_h, uint16_t, uint16_t, ldhu_h) | ||
287 | +GEN_VEXT_LD_US(vlhu_v_w, uint16_t, uint32_t, ldhu_w) | ||
288 | +GEN_VEXT_LD_US(vlhu_v_d, uint16_t, uint64_t, ldhu_d) | ||
289 | +GEN_VEXT_LD_US(vlwu_v_w, uint32_t, uint32_t, ldwu_w) | ||
290 | +GEN_VEXT_LD_US(vlwu_v_d, uint32_t, uint64_t, ldwu_d) | ||
291 | |||
292 | #define GEN_VEXT_ST_US(NAME, MTYPE, ETYPE, STORE_FN) \ | ||
293 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
294 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
295 | { \ | ||
296 | uint32_t stride = vext_nf(desc) * sizeof(MTYPE); \ | ||
297 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \ | ||
298 | - NULL, sizeof(ETYPE), sizeof(MTYPE), \ | ||
299 | + sizeof(ETYPE), sizeof(MTYPE), \ | ||
300 | GETPC(), MMU_DATA_STORE); \ | ||
301 | } \ | ||
302 | \ | ||
303 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
304 | CPURISCVState *env, uint32_t desc) \ | ||
305 | { \ | ||
306 | - vext_ldst_us(vd, base, env, desc, STORE_FN, NULL, \ | ||
307 | + vext_ldst_us(vd, base, env, desc, STORE_FN, \ | ||
308 | sizeof(ETYPE), sizeof(MTYPE), GETPC(), MMU_DATA_STORE);\ | ||
309 | } | ||
310 | |||
311 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
312 | void *vs2, CPURISCVState *env, uint32_t desc, | ||
313 | vext_get_index_addr get_index_addr, | ||
314 | vext_ldst_elem_fn *ldst_elem, | ||
315 | - clear_fn *clear_elem, | ||
316 | uint32_t esz, uint32_t msz, uintptr_t ra, | ||
317 | MMUAccessType access_type) | ||
318 | { | ||
319 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
320 | k++; | ||
321 | } | ||
322 | } | ||
323 | - /* clear tail elements */ | ||
324 | - if (clear_elem) { | ||
325 | - for (k = 0; k < nf; k++) { | ||
326 | - clear_elem(vd, env->vl + k * vlmax, env->vl * esz, vlmax * esz); | ||
327 | - } | ||
328 | - } | ||
329 | } | ||
330 | |||
331 | -#define GEN_VEXT_LD_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, LOAD_FN, CLEAR_FN) \ | ||
332 | +#define GEN_VEXT_LD_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, LOAD_FN) \ | ||
333 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
334 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
335 | { \ | ||
336 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
337 | - LOAD_FN, CLEAR_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
338 | + LOAD_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
339 | GETPC(), MMU_DATA_LOAD); \ | ||
340 | } | ||
341 | |||
342 | -GEN_VEXT_LD_INDEX(vlxb_v_b, int8_t, int8_t, idx_b, ldb_b, clearb) | ||
343 | -GEN_VEXT_LD_INDEX(vlxb_v_h, int8_t, int16_t, idx_h, ldb_h, clearh) | ||
344 | -GEN_VEXT_LD_INDEX(vlxb_v_w, int8_t, int32_t, idx_w, ldb_w, clearl) | ||
345 | -GEN_VEXT_LD_INDEX(vlxb_v_d, int8_t, int64_t, idx_d, ldb_d, clearq) | ||
346 | -GEN_VEXT_LD_INDEX(vlxh_v_h, int16_t, int16_t, idx_h, ldh_h, clearh) | ||
347 | -GEN_VEXT_LD_INDEX(vlxh_v_w, int16_t, int32_t, idx_w, ldh_w, clearl) | ||
348 | -GEN_VEXT_LD_INDEX(vlxh_v_d, int16_t, int64_t, idx_d, ldh_d, clearq) | ||
349 | -GEN_VEXT_LD_INDEX(vlxw_v_w, int32_t, int32_t, idx_w, ldw_w, clearl) | ||
350 | -GEN_VEXT_LD_INDEX(vlxw_v_d, int32_t, int64_t, idx_d, ldw_d, clearq) | ||
351 | -GEN_VEXT_LD_INDEX(vlxe_v_b, int8_t, int8_t, idx_b, lde_b, clearb) | ||
352 | -GEN_VEXT_LD_INDEX(vlxe_v_h, int16_t, int16_t, idx_h, lde_h, clearh) | ||
353 | -GEN_VEXT_LD_INDEX(vlxe_v_w, int32_t, int32_t, idx_w, lde_w, clearl) | ||
354 | -GEN_VEXT_LD_INDEX(vlxe_v_d, int64_t, int64_t, idx_d, lde_d, clearq) | ||
355 | -GEN_VEXT_LD_INDEX(vlxbu_v_b, uint8_t, uint8_t, idx_b, ldbu_b, clearb) | ||
356 | -GEN_VEXT_LD_INDEX(vlxbu_v_h, uint8_t, uint16_t, idx_h, ldbu_h, clearh) | ||
357 | -GEN_VEXT_LD_INDEX(vlxbu_v_w, uint8_t, uint32_t, idx_w, ldbu_w, clearl) | ||
358 | -GEN_VEXT_LD_INDEX(vlxbu_v_d, uint8_t, uint64_t, idx_d, ldbu_d, clearq) | ||
359 | -GEN_VEXT_LD_INDEX(vlxhu_v_h, uint16_t, uint16_t, idx_h, ldhu_h, clearh) | ||
360 | -GEN_VEXT_LD_INDEX(vlxhu_v_w, uint16_t, uint32_t, idx_w, ldhu_w, clearl) | ||
361 | -GEN_VEXT_LD_INDEX(vlxhu_v_d, uint16_t, uint64_t, idx_d, ldhu_d, clearq) | ||
362 | -GEN_VEXT_LD_INDEX(vlxwu_v_w, uint32_t, uint32_t, idx_w, ldwu_w, clearl) | ||
363 | -GEN_VEXT_LD_INDEX(vlxwu_v_d, uint32_t, uint64_t, idx_d, ldwu_d, clearq) | ||
364 | +GEN_VEXT_LD_INDEX(vlxb_v_b, int8_t, int8_t, idx_b, ldb_b) | ||
365 | +GEN_VEXT_LD_INDEX(vlxb_v_h, int8_t, int16_t, idx_h, ldb_h) | ||
366 | +GEN_VEXT_LD_INDEX(vlxb_v_w, int8_t, int32_t, idx_w, ldb_w) | ||
367 | +GEN_VEXT_LD_INDEX(vlxb_v_d, int8_t, int64_t, idx_d, ldb_d) | ||
368 | +GEN_VEXT_LD_INDEX(vlxh_v_h, int16_t, int16_t, idx_h, ldh_h) | ||
369 | +GEN_VEXT_LD_INDEX(vlxh_v_w, int16_t, int32_t, idx_w, ldh_w) | ||
370 | +GEN_VEXT_LD_INDEX(vlxh_v_d, int16_t, int64_t, idx_d, ldh_d) | ||
371 | +GEN_VEXT_LD_INDEX(vlxw_v_w, int32_t, int32_t, idx_w, ldw_w) | ||
372 | +GEN_VEXT_LD_INDEX(vlxw_v_d, int32_t, int64_t, idx_d, ldw_d) | ||
373 | +GEN_VEXT_LD_INDEX(vlxe_v_b, int8_t, int8_t, idx_b, lde_b) | ||
374 | +GEN_VEXT_LD_INDEX(vlxe_v_h, int16_t, int16_t, idx_h, lde_h) | ||
375 | +GEN_VEXT_LD_INDEX(vlxe_v_w, int32_t, int32_t, idx_w, lde_w) | ||
376 | +GEN_VEXT_LD_INDEX(vlxe_v_d, int64_t, int64_t, idx_d, lde_d) | ||
377 | +GEN_VEXT_LD_INDEX(vlxbu_v_b, uint8_t, uint8_t, idx_b, ldbu_b) | ||
378 | +GEN_VEXT_LD_INDEX(vlxbu_v_h, uint8_t, uint16_t, idx_h, ldbu_h) | ||
379 | +GEN_VEXT_LD_INDEX(vlxbu_v_w, uint8_t, uint32_t, idx_w, ldbu_w) | ||
380 | +GEN_VEXT_LD_INDEX(vlxbu_v_d, uint8_t, uint64_t, idx_d, ldbu_d) | ||
381 | +GEN_VEXT_LD_INDEX(vlxhu_v_h, uint16_t, uint16_t, idx_h, ldhu_h) | ||
382 | +GEN_VEXT_LD_INDEX(vlxhu_v_w, uint16_t, uint32_t, idx_w, ldhu_w) | ||
383 | +GEN_VEXT_LD_INDEX(vlxhu_v_d, uint16_t, uint64_t, idx_d, ldhu_d) | ||
384 | +GEN_VEXT_LD_INDEX(vlxwu_v_w, uint32_t, uint32_t, idx_w, ldwu_w) | ||
385 | +GEN_VEXT_LD_INDEX(vlxwu_v_d, uint32_t, uint64_t, idx_d, ldwu_d) | ||
386 | |||
387 | #define GEN_VEXT_ST_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, STORE_FN)\ | ||
388 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
389 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
390 | { \ | ||
391 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
392 | - STORE_FN, NULL, sizeof(ETYPE), sizeof(MTYPE),\ | ||
393 | + STORE_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
394 | GETPC(), MMU_DATA_STORE); \ | ||
395 | } | ||
396 | |||
397 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
398 | vext_ldff(void *vd, void *v0, target_ulong base, | ||
399 | CPURISCVState *env, uint32_t desc, | ||
400 | vext_ldst_elem_fn *ldst_elem, | ||
401 | - clear_fn *clear_elem, | ||
402 | uint32_t esz, uint32_t msz, uintptr_t ra) | ||
403 | { | ||
404 | void *host; | ||
405 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
406 | k++; | ||
407 | } | ||
408 | } | ||
409 | - /* clear tail elements */ | ||
410 | - if (vl != 0) { | ||
411 | - return; | ||
412 | - } | ||
413 | - for (k = 0; k < nf; k++) { | ||
414 | - clear_elem(vd, env->vl + k * vlmax, env->vl * esz, vlmax * esz); | ||
415 | - } | ||
416 | } | ||
417 | |||
418 | -#define GEN_VEXT_LDFF(NAME, MTYPE, ETYPE, LOAD_FN, CLEAR_FN) \ | ||
419 | +#define GEN_VEXT_LDFF(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
420 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
421 | CPURISCVState *env, uint32_t desc) \ | ||
422 | { \ | ||
423 | - vext_ldff(vd, v0, base, env, desc, LOAD_FN, CLEAR_FN, \ | ||
424 | + vext_ldff(vd, v0, base, env, desc, LOAD_FN, \ | ||
425 | sizeof(ETYPE), sizeof(MTYPE), GETPC()); \ | ||
426 | } | ||
427 | |||
428 | -GEN_VEXT_LDFF(vlbff_v_b, int8_t, int8_t, ldb_b, clearb) | ||
429 | -GEN_VEXT_LDFF(vlbff_v_h, int8_t, int16_t, ldb_h, clearh) | ||
430 | -GEN_VEXT_LDFF(vlbff_v_w, int8_t, int32_t, ldb_w, clearl) | ||
431 | -GEN_VEXT_LDFF(vlbff_v_d, int8_t, int64_t, ldb_d, clearq) | ||
432 | -GEN_VEXT_LDFF(vlhff_v_h, int16_t, int16_t, ldh_h, clearh) | ||
433 | -GEN_VEXT_LDFF(vlhff_v_w, int16_t, int32_t, ldh_w, clearl) | ||
434 | -GEN_VEXT_LDFF(vlhff_v_d, int16_t, int64_t, ldh_d, clearq) | ||
435 | -GEN_VEXT_LDFF(vlwff_v_w, int32_t, int32_t, ldw_w, clearl) | ||
436 | -GEN_VEXT_LDFF(vlwff_v_d, int32_t, int64_t, ldw_d, clearq) | ||
437 | -GEN_VEXT_LDFF(vleff_v_b, int8_t, int8_t, lde_b, clearb) | ||
438 | -GEN_VEXT_LDFF(vleff_v_h, int16_t, int16_t, lde_h, clearh) | ||
439 | -GEN_VEXT_LDFF(vleff_v_w, int32_t, int32_t, lde_w, clearl) | ||
440 | -GEN_VEXT_LDFF(vleff_v_d, int64_t, int64_t, lde_d, clearq) | ||
441 | -GEN_VEXT_LDFF(vlbuff_v_b, uint8_t, uint8_t, ldbu_b, clearb) | ||
442 | -GEN_VEXT_LDFF(vlbuff_v_h, uint8_t, uint16_t, ldbu_h, clearh) | ||
443 | -GEN_VEXT_LDFF(vlbuff_v_w, uint8_t, uint32_t, ldbu_w, clearl) | ||
444 | -GEN_VEXT_LDFF(vlbuff_v_d, uint8_t, uint64_t, ldbu_d, clearq) | ||
445 | -GEN_VEXT_LDFF(vlhuff_v_h, uint16_t, uint16_t, ldhu_h, clearh) | ||
446 | -GEN_VEXT_LDFF(vlhuff_v_w, uint16_t, uint32_t, ldhu_w, clearl) | ||
447 | -GEN_VEXT_LDFF(vlhuff_v_d, uint16_t, uint64_t, ldhu_d, clearq) | ||
448 | -GEN_VEXT_LDFF(vlwuff_v_w, uint32_t, uint32_t, ldwu_w, clearl) | ||
449 | -GEN_VEXT_LDFF(vlwuff_v_d, uint32_t, uint64_t, ldwu_d, clearq) | ||
450 | +GEN_VEXT_LDFF(vlbff_v_b, int8_t, int8_t, ldb_b) | ||
451 | +GEN_VEXT_LDFF(vlbff_v_h, int8_t, int16_t, ldb_h) | ||
452 | +GEN_VEXT_LDFF(vlbff_v_w, int8_t, int32_t, ldb_w) | ||
453 | +GEN_VEXT_LDFF(vlbff_v_d, int8_t, int64_t, ldb_d) | ||
454 | +GEN_VEXT_LDFF(vlhff_v_h, int16_t, int16_t, ldh_h) | ||
455 | +GEN_VEXT_LDFF(vlhff_v_w, int16_t, int32_t, ldh_w) | ||
456 | +GEN_VEXT_LDFF(vlhff_v_d, int16_t, int64_t, ldh_d) | ||
457 | +GEN_VEXT_LDFF(vlwff_v_w, int32_t, int32_t, ldw_w) | ||
458 | +GEN_VEXT_LDFF(vlwff_v_d, int32_t, int64_t, ldw_d) | ||
459 | +GEN_VEXT_LDFF(vleff_v_b, int8_t, int8_t, lde_b) | ||
460 | +GEN_VEXT_LDFF(vleff_v_h, int16_t, int16_t, lde_h) | ||
461 | +GEN_VEXT_LDFF(vleff_v_w, int32_t, int32_t, lde_w) | ||
462 | +GEN_VEXT_LDFF(vleff_v_d, int64_t, int64_t, lde_d) | ||
463 | +GEN_VEXT_LDFF(vlbuff_v_b, uint8_t, uint8_t, ldbu_b) | ||
464 | +GEN_VEXT_LDFF(vlbuff_v_h, uint8_t, uint16_t, ldbu_h) | ||
465 | +GEN_VEXT_LDFF(vlbuff_v_w, uint8_t, uint32_t, ldbu_w) | ||
466 | +GEN_VEXT_LDFF(vlbuff_v_d, uint8_t, uint64_t, ldbu_d) | ||
467 | +GEN_VEXT_LDFF(vlhuff_v_h, uint16_t, uint16_t, ldhu_h) | ||
468 | +GEN_VEXT_LDFF(vlhuff_v_w, uint16_t, uint32_t, ldhu_w) | ||
469 | +GEN_VEXT_LDFF(vlhuff_v_d, uint16_t, uint64_t, ldhu_d) | ||
470 | +GEN_VEXT_LDFF(vlwuff_v_w, uint32_t, uint32_t, ldwu_w) | ||
471 | +GEN_VEXT_LDFF(vlwuff_v_d, uint32_t, uint64_t, ldwu_d) | ||
472 | |||
473 | /* | ||
474 | *** Vector AMO Operations (Zvamo) | ||
475 | @@ -XXX,XX +XXX,XX @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base, | ||
476 | void *vs2, CPURISCVState *env, uint32_t desc, | ||
477 | vext_get_index_addr get_index_addr, | ||
478 | vext_amo_noatomic_fn *noatomic_op, | ||
479 | - clear_fn *clear_elem, | ||
480 | uint32_t esz, uint32_t msz, uintptr_t ra) | ||
481 | { | ||
482 | uint32_t i; | ||
483 | target_long addr; | ||
484 | uint32_t wd = vext_wd(desc); | ||
485 | uint32_t vm = vext_vm(desc); | ||
486 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
487 | |||
488 | for (i = 0; i < env->vl; i++) { | ||
489 | if (!vm && !vext_elem_mask(v0, i)) { | ||
490 | @@ -XXX,XX +XXX,XX @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base, | ||
491 | addr = get_index_addr(base, i, vs2); | ||
492 | noatomic_op(vs3, addr, wd, i, env, ra); | ||
493 | } | ||
494 | - clear_elem(vs3, env->vl, env->vl * esz, vlmax * esz); | ||
495 | } | ||
496 | |||
497 | -#define GEN_VEXT_AMO(NAME, MTYPE, ETYPE, INDEX_FN, CLEAR_FN) \ | ||
498 | +#define GEN_VEXT_AMO(NAME, MTYPE, ETYPE, INDEX_FN) \ | ||
499 | void HELPER(NAME)(void *vs3, void *v0, target_ulong base, \ | ||
500 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
501 | { \ | ||
502 | vext_amo_noatomic(vs3, v0, base, vs2, env, desc, \ | ||
503 | INDEX_FN, vext_##NAME##_noatomic_op, \ | ||
504 | - CLEAR_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
505 | + sizeof(ETYPE), sizeof(MTYPE), \ | ||
506 | GETPC()); \ | ||
507 | } | ||
508 | |||
509 | -GEN_VEXT_AMO(vamoswapw_v_d, int32_t, int64_t, idx_d, clearq) | ||
510 | -GEN_VEXT_AMO(vamoswapd_v_d, int64_t, int64_t, idx_d, clearq) | ||
511 | -GEN_VEXT_AMO(vamoaddw_v_d, int32_t, int64_t, idx_d, clearq) | ||
512 | -GEN_VEXT_AMO(vamoaddd_v_d, int64_t, int64_t, idx_d, clearq) | ||
513 | -GEN_VEXT_AMO(vamoxorw_v_d, int32_t, int64_t, idx_d, clearq) | ||
514 | -GEN_VEXT_AMO(vamoxord_v_d, int64_t, int64_t, idx_d, clearq) | ||
515 | -GEN_VEXT_AMO(vamoandw_v_d, int32_t, int64_t, idx_d, clearq) | ||
516 | -GEN_VEXT_AMO(vamoandd_v_d, int64_t, int64_t, idx_d, clearq) | ||
517 | -GEN_VEXT_AMO(vamoorw_v_d, int32_t, int64_t, idx_d, clearq) | ||
518 | -GEN_VEXT_AMO(vamoord_v_d, int64_t, int64_t, idx_d, clearq) | ||
519 | -GEN_VEXT_AMO(vamominw_v_d, int32_t, int64_t, idx_d, clearq) | ||
520 | -GEN_VEXT_AMO(vamomind_v_d, int64_t, int64_t, idx_d, clearq) | ||
521 | -GEN_VEXT_AMO(vamomaxw_v_d, int32_t, int64_t, idx_d, clearq) | ||
522 | -GEN_VEXT_AMO(vamomaxd_v_d, int64_t, int64_t, idx_d, clearq) | ||
523 | -GEN_VEXT_AMO(vamominuw_v_d, uint32_t, uint64_t, idx_d, clearq) | ||
524 | -GEN_VEXT_AMO(vamominud_v_d, uint64_t, uint64_t, idx_d, clearq) | ||
525 | -GEN_VEXT_AMO(vamomaxuw_v_d, uint32_t, uint64_t, idx_d, clearq) | ||
526 | -GEN_VEXT_AMO(vamomaxud_v_d, uint64_t, uint64_t, idx_d, clearq) | ||
527 | -GEN_VEXT_AMO(vamoswapw_v_w, int32_t, int32_t, idx_w, clearl) | ||
528 | -GEN_VEXT_AMO(vamoaddw_v_w, int32_t, int32_t, idx_w, clearl) | ||
529 | -GEN_VEXT_AMO(vamoxorw_v_w, int32_t, int32_t, idx_w, clearl) | ||
530 | -GEN_VEXT_AMO(vamoandw_v_w, int32_t, int32_t, idx_w, clearl) | ||
531 | -GEN_VEXT_AMO(vamoorw_v_w, int32_t, int32_t, idx_w, clearl) | ||
532 | -GEN_VEXT_AMO(vamominw_v_w, int32_t, int32_t, idx_w, clearl) | ||
533 | -GEN_VEXT_AMO(vamomaxw_v_w, int32_t, int32_t, idx_w, clearl) | ||
534 | -GEN_VEXT_AMO(vamominuw_v_w, uint32_t, uint32_t, idx_w, clearl) | ||
535 | -GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w, clearl) | ||
536 | +GEN_VEXT_AMO(vamoswapw_v_d, int32_t, int64_t, idx_d) | ||
537 | +GEN_VEXT_AMO(vamoswapd_v_d, int64_t, int64_t, idx_d) | ||
538 | +GEN_VEXT_AMO(vamoaddw_v_d, int32_t, int64_t, idx_d) | ||
539 | +GEN_VEXT_AMO(vamoaddd_v_d, int64_t, int64_t, idx_d) | ||
540 | +GEN_VEXT_AMO(vamoxorw_v_d, int32_t, int64_t, idx_d) | ||
541 | +GEN_VEXT_AMO(vamoxord_v_d, int64_t, int64_t, idx_d) | ||
542 | +GEN_VEXT_AMO(vamoandw_v_d, int32_t, int64_t, idx_d) | ||
543 | +GEN_VEXT_AMO(vamoandd_v_d, int64_t, int64_t, idx_d) | ||
544 | +GEN_VEXT_AMO(vamoorw_v_d, int32_t, int64_t, idx_d) | ||
545 | +GEN_VEXT_AMO(vamoord_v_d, int64_t, int64_t, idx_d) | ||
546 | +GEN_VEXT_AMO(vamominw_v_d, int32_t, int64_t, idx_d) | ||
547 | +GEN_VEXT_AMO(vamomind_v_d, int64_t, int64_t, idx_d) | ||
548 | +GEN_VEXT_AMO(vamomaxw_v_d, int32_t, int64_t, idx_d) | ||
549 | +GEN_VEXT_AMO(vamomaxd_v_d, int64_t, int64_t, idx_d) | ||
550 | +GEN_VEXT_AMO(vamominuw_v_d, uint32_t, uint64_t, idx_d) | ||
551 | +GEN_VEXT_AMO(vamominud_v_d, uint64_t, uint64_t, idx_d) | ||
552 | +GEN_VEXT_AMO(vamomaxuw_v_d, uint32_t, uint64_t, idx_d) | ||
553 | +GEN_VEXT_AMO(vamomaxud_v_d, uint64_t, uint64_t, idx_d) | ||
554 | +GEN_VEXT_AMO(vamoswapw_v_w, int32_t, int32_t, idx_w) | ||
555 | +GEN_VEXT_AMO(vamoaddw_v_w, int32_t, int32_t, idx_w) | ||
556 | +GEN_VEXT_AMO(vamoxorw_v_w, int32_t, int32_t, idx_w) | ||
557 | +GEN_VEXT_AMO(vamoandw_v_w, int32_t, int32_t, idx_w) | ||
558 | +GEN_VEXT_AMO(vamoorw_v_w, int32_t, int32_t, idx_w) | ||
559 | +GEN_VEXT_AMO(vamominw_v_w, int32_t, int32_t, idx_w) | ||
560 | +GEN_VEXT_AMO(vamomaxw_v_w, int32_t, int32_t, idx_w) | ||
561 | +GEN_VEXT_AMO(vamominuw_v_w, uint32_t, uint32_t, idx_w) | ||
562 | +GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w) | ||
563 | |||
564 | /* | ||
565 | *** Vector Integer Arithmetic Instructions | ||
566 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB) | ||
567 | static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
568 | CPURISCVState *env, uint32_t desc, | ||
569 | uint32_t esz, uint32_t dsz, | ||
570 | - opivv2_fn *fn, clear_fn *clearfn) | ||
571 | + opivv2_fn *fn) | ||
572 | { | ||
573 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
574 | uint32_t vm = vext_vm(desc); | ||
575 | uint32_t vl = env->vl; | ||
576 | uint32_t i; | ||
577 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
578 | } | ||
579 | fn(vd, vs1, vs2, i); | ||
580 | } | ||
581 | - clearfn(vd, vl, vl * dsz, vlmax * dsz); | ||
582 | } | ||
583 | |||
584 | /* generate the helpers for OPIVV */ | ||
585 | -#define GEN_VEXT_VV(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
586 | +#define GEN_VEXT_VV(NAME, ESZ, DSZ) \ | ||
587 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
588 | void *vs2, CPURISCVState *env, \ | ||
589 | uint32_t desc) \ | ||
590 | { \ | ||
591 | do_vext_vv(vd, v0, vs1, vs2, env, desc, ESZ, DSZ, \ | ||
592 | - do_##NAME, CLEAR_FN); \ | ||
593 | + do_##NAME); \ | ||
594 | } | ||
595 | |||
596 | -GEN_VEXT_VV(vadd_vv_b, 1, 1, clearb) | ||
597 | -GEN_VEXT_VV(vadd_vv_h, 2, 2, clearh) | ||
598 | -GEN_VEXT_VV(vadd_vv_w, 4, 4, clearl) | ||
599 | -GEN_VEXT_VV(vadd_vv_d, 8, 8, clearq) | ||
600 | -GEN_VEXT_VV(vsub_vv_b, 1, 1, clearb) | ||
601 | -GEN_VEXT_VV(vsub_vv_h, 2, 2, clearh) | ||
602 | -GEN_VEXT_VV(vsub_vv_w, 4, 4, clearl) | ||
603 | -GEN_VEXT_VV(vsub_vv_d, 8, 8, clearq) | ||
604 | +GEN_VEXT_VV(vadd_vv_b, 1, 1) | ||
605 | +GEN_VEXT_VV(vadd_vv_h, 2, 2) | ||
606 | +GEN_VEXT_VV(vadd_vv_w, 4, 4) | ||
607 | +GEN_VEXT_VV(vadd_vv_d, 8, 8) | ||
608 | +GEN_VEXT_VV(vsub_vv_b, 1, 1) | ||
609 | +GEN_VEXT_VV(vsub_vv_h, 2, 2) | ||
610 | +GEN_VEXT_VV(vsub_vv_w, 4, 4) | ||
611 | +GEN_VEXT_VV(vsub_vv_d, 8, 8) | ||
612 | |||
613 | typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i); | ||
614 | |||
615 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB) | ||
616 | static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
617 | CPURISCVState *env, uint32_t desc, | ||
618 | uint32_t esz, uint32_t dsz, | ||
619 | - opivx2_fn fn, clear_fn *clearfn) | ||
620 | + opivx2_fn fn) | ||
621 | { | ||
622 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
623 | uint32_t vm = vext_vm(desc); | ||
624 | uint32_t vl = env->vl; | ||
625 | uint32_t i; | ||
626 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
627 | } | ||
628 | fn(vd, s1, vs2, i); | ||
629 | } | ||
630 | - clearfn(vd, vl, vl * dsz, vlmax * dsz); | ||
631 | } | ||
632 | |||
633 | /* generate the helpers for OPIVX */ | ||
634 | -#define GEN_VEXT_VX(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
635 | +#define GEN_VEXT_VX(NAME, ESZ, DSZ) \ | ||
636 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
637 | void *vs2, CPURISCVState *env, \ | ||
638 | uint32_t desc) \ | ||
639 | { \ | ||
640 | do_vext_vx(vd, v0, s1, vs2, env, desc, ESZ, DSZ, \ | ||
641 | - do_##NAME, CLEAR_FN); \ | ||
642 | -} | ||
643 | - | ||
644 | -GEN_VEXT_VX(vadd_vx_b, 1, 1, clearb) | ||
645 | -GEN_VEXT_VX(vadd_vx_h, 2, 2, clearh) | ||
646 | -GEN_VEXT_VX(vadd_vx_w, 4, 4, clearl) | ||
647 | -GEN_VEXT_VX(vadd_vx_d, 8, 8, clearq) | ||
648 | -GEN_VEXT_VX(vsub_vx_b, 1, 1, clearb) | ||
649 | -GEN_VEXT_VX(vsub_vx_h, 2, 2, clearh) | ||
650 | -GEN_VEXT_VX(vsub_vx_w, 4, 4, clearl) | ||
651 | -GEN_VEXT_VX(vsub_vx_d, 8, 8, clearq) | ||
652 | -GEN_VEXT_VX(vrsub_vx_b, 1, 1, clearb) | ||
653 | -GEN_VEXT_VX(vrsub_vx_h, 2, 2, clearh) | ||
654 | -GEN_VEXT_VX(vrsub_vx_w, 4, 4, clearl) | ||
655 | -GEN_VEXT_VX(vrsub_vx_d, 8, 8, clearq) | ||
656 | + do_##NAME); \ | ||
657 | +} | ||
658 | + | ||
659 | +GEN_VEXT_VX(vadd_vx_b, 1, 1) | ||
660 | +GEN_VEXT_VX(vadd_vx_h, 2, 2) | ||
661 | +GEN_VEXT_VX(vadd_vx_w, 4, 4) | ||
662 | +GEN_VEXT_VX(vadd_vx_d, 8, 8) | ||
663 | +GEN_VEXT_VX(vsub_vx_b, 1, 1) | ||
664 | +GEN_VEXT_VX(vsub_vx_h, 2, 2) | ||
665 | +GEN_VEXT_VX(vsub_vx_w, 4, 4) | ||
666 | +GEN_VEXT_VX(vsub_vx_d, 8, 8) | ||
667 | +GEN_VEXT_VX(vrsub_vx_b, 1, 1) | ||
668 | +GEN_VEXT_VX(vrsub_vx_h, 2, 2) | ||
669 | +GEN_VEXT_VX(vrsub_vx_w, 4, 4) | ||
670 | +GEN_VEXT_VX(vrsub_vx_d, 8, 8) | ||
671 | |||
672 | void HELPER(vec_rsubs8)(void *d, void *a, uint64_t b, uint32_t desc) | ||
673 | { | ||
674 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vwadd_wv_w, WOP_WSSS_W, H8, H4, H4, DO_ADD) | ||
675 | RVVCALL(OPIVV2, vwsub_wv_b, WOP_WSSS_B, H2, H1, H1, DO_SUB) | ||
676 | RVVCALL(OPIVV2, vwsub_wv_h, WOP_WSSS_H, H4, H2, H2, DO_SUB) | ||
677 | RVVCALL(OPIVV2, vwsub_wv_w, WOP_WSSS_W, H8, H4, H4, DO_SUB) | ||
678 | -GEN_VEXT_VV(vwaddu_vv_b, 1, 2, clearh) | ||
679 | -GEN_VEXT_VV(vwaddu_vv_h, 2, 4, clearl) | ||
680 | -GEN_VEXT_VV(vwaddu_vv_w, 4, 8, clearq) | ||
681 | -GEN_VEXT_VV(vwsubu_vv_b, 1, 2, clearh) | ||
682 | -GEN_VEXT_VV(vwsubu_vv_h, 2, 4, clearl) | ||
683 | -GEN_VEXT_VV(vwsubu_vv_w, 4, 8, clearq) | ||
684 | -GEN_VEXT_VV(vwadd_vv_b, 1, 2, clearh) | ||
685 | -GEN_VEXT_VV(vwadd_vv_h, 2, 4, clearl) | ||
686 | -GEN_VEXT_VV(vwadd_vv_w, 4, 8, clearq) | ||
687 | -GEN_VEXT_VV(vwsub_vv_b, 1, 2, clearh) | ||
688 | -GEN_VEXT_VV(vwsub_vv_h, 2, 4, clearl) | ||
689 | -GEN_VEXT_VV(vwsub_vv_w, 4, 8, clearq) | ||
690 | -GEN_VEXT_VV(vwaddu_wv_b, 1, 2, clearh) | ||
691 | -GEN_VEXT_VV(vwaddu_wv_h, 2, 4, clearl) | ||
692 | -GEN_VEXT_VV(vwaddu_wv_w, 4, 8, clearq) | ||
693 | -GEN_VEXT_VV(vwsubu_wv_b, 1, 2, clearh) | ||
694 | -GEN_VEXT_VV(vwsubu_wv_h, 2, 4, clearl) | ||
695 | -GEN_VEXT_VV(vwsubu_wv_w, 4, 8, clearq) | ||
696 | -GEN_VEXT_VV(vwadd_wv_b, 1, 2, clearh) | ||
697 | -GEN_VEXT_VV(vwadd_wv_h, 2, 4, clearl) | ||
698 | -GEN_VEXT_VV(vwadd_wv_w, 4, 8, clearq) | ||
699 | -GEN_VEXT_VV(vwsub_wv_b, 1, 2, clearh) | ||
700 | -GEN_VEXT_VV(vwsub_wv_h, 2, 4, clearl) | ||
701 | -GEN_VEXT_VV(vwsub_wv_w, 4, 8, clearq) | ||
702 | +GEN_VEXT_VV(vwaddu_vv_b, 1, 2) | ||
703 | +GEN_VEXT_VV(vwaddu_vv_h, 2, 4) | ||
704 | +GEN_VEXT_VV(vwaddu_vv_w, 4, 8) | ||
705 | +GEN_VEXT_VV(vwsubu_vv_b, 1, 2) | ||
706 | +GEN_VEXT_VV(vwsubu_vv_h, 2, 4) | ||
707 | +GEN_VEXT_VV(vwsubu_vv_w, 4, 8) | ||
708 | +GEN_VEXT_VV(vwadd_vv_b, 1, 2) | ||
709 | +GEN_VEXT_VV(vwadd_vv_h, 2, 4) | ||
710 | +GEN_VEXT_VV(vwadd_vv_w, 4, 8) | ||
711 | +GEN_VEXT_VV(vwsub_vv_b, 1, 2) | ||
712 | +GEN_VEXT_VV(vwsub_vv_h, 2, 4) | ||
713 | +GEN_VEXT_VV(vwsub_vv_w, 4, 8) | ||
714 | +GEN_VEXT_VV(vwaddu_wv_b, 1, 2) | ||
715 | +GEN_VEXT_VV(vwaddu_wv_h, 2, 4) | ||
716 | +GEN_VEXT_VV(vwaddu_wv_w, 4, 8) | ||
717 | +GEN_VEXT_VV(vwsubu_wv_b, 1, 2) | ||
718 | +GEN_VEXT_VV(vwsubu_wv_h, 2, 4) | ||
719 | +GEN_VEXT_VV(vwsubu_wv_w, 4, 8) | ||
720 | +GEN_VEXT_VV(vwadd_wv_b, 1, 2) | ||
721 | +GEN_VEXT_VV(vwadd_wv_h, 2, 4) | ||
722 | +GEN_VEXT_VV(vwadd_wv_w, 4, 8) | ||
723 | +GEN_VEXT_VV(vwsub_wv_b, 1, 2) | ||
724 | +GEN_VEXT_VV(vwsub_wv_h, 2, 4) | ||
725 | +GEN_VEXT_VV(vwsub_wv_w, 4, 8) | ||
726 | |||
727 | RVVCALL(OPIVX2, vwaddu_vx_b, WOP_UUU_B, H2, H1, DO_ADD) | ||
728 | RVVCALL(OPIVX2, vwaddu_vx_h, WOP_UUU_H, H4, H2, DO_ADD) | ||
729 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwadd_wx_w, WOP_WSSS_W, H8, H4, DO_ADD) | ||
730 | RVVCALL(OPIVX2, vwsub_wx_b, WOP_WSSS_B, H2, H1, DO_SUB) | ||
731 | RVVCALL(OPIVX2, vwsub_wx_h, WOP_WSSS_H, H4, H2, DO_SUB) | ||
732 | RVVCALL(OPIVX2, vwsub_wx_w, WOP_WSSS_W, H8, H4, DO_SUB) | ||
733 | -GEN_VEXT_VX(vwaddu_vx_b, 1, 2, clearh) | ||
734 | -GEN_VEXT_VX(vwaddu_vx_h, 2, 4, clearl) | ||
735 | -GEN_VEXT_VX(vwaddu_vx_w, 4, 8, clearq) | ||
736 | -GEN_VEXT_VX(vwsubu_vx_b, 1, 2, clearh) | ||
737 | -GEN_VEXT_VX(vwsubu_vx_h, 2, 4, clearl) | ||
738 | -GEN_VEXT_VX(vwsubu_vx_w, 4, 8, clearq) | ||
739 | -GEN_VEXT_VX(vwadd_vx_b, 1, 2, clearh) | ||
740 | -GEN_VEXT_VX(vwadd_vx_h, 2, 4, clearl) | ||
741 | -GEN_VEXT_VX(vwadd_vx_w, 4, 8, clearq) | ||
742 | -GEN_VEXT_VX(vwsub_vx_b, 1, 2, clearh) | ||
743 | -GEN_VEXT_VX(vwsub_vx_h, 2, 4, clearl) | ||
744 | -GEN_VEXT_VX(vwsub_vx_w, 4, 8, clearq) | ||
745 | -GEN_VEXT_VX(vwaddu_wx_b, 1, 2, clearh) | ||
746 | -GEN_VEXT_VX(vwaddu_wx_h, 2, 4, clearl) | ||
747 | -GEN_VEXT_VX(vwaddu_wx_w, 4, 8, clearq) | ||
748 | -GEN_VEXT_VX(vwsubu_wx_b, 1, 2, clearh) | ||
749 | -GEN_VEXT_VX(vwsubu_wx_h, 2, 4, clearl) | ||
750 | -GEN_VEXT_VX(vwsubu_wx_w, 4, 8, clearq) | ||
751 | -GEN_VEXT_VX(vwadd_wx_b, 1, 2, clearh) | ||
752 | -GEN_VEXT_VX(vwadd_wx_h, 2, 4, clearl) | ||
753 | -GEN_VEXT_VX(vwadd_wx_w, 4, 8, clearq) | ||
754 | -GEN_VEXT_VX(vwsub_wx_b, 1, 2, clearh) | ||
755 | -GEN_VEXT_VX(vwsub_wx_h, 2, 4, clearl) | ||
756 | -GEN_VEXT_VX(vwsub_wx_w, 4, 8, clearq) | ||
757 | +GEN_VEXT_VX(vwaddu_vx_b, 1, 2) | ||
758 | +GEN_VEXT_VX(vwaddu_vx_h, 2, 4) | ||
759 | +GEN_VEXT_VX(vwaddu_vx_w, 4, 8) | ||
760 | +GEN_VEXT_VX(vwsubu_vx_b, 1, 2) | ||
761 | +GEN_VEXT_VX(vwsubu_vx_h, 2, 4) | ||
762 | +GEN_VEXT_VX(vwsubu_vx_w, 4, 8) | ||
763 | +GEN_VEXT_VX(vwadd_vx_b, 1, 2) | ||
764 | +GEN_VEXT_VX(vwadd_vx_h, 2, 4) | ||
765 | +GEN_VEXT_VX(vwadd_vx_w, 4, 8) | ||
766 | +GEN_VEXT_VX(vwsub_vx_b, 1, 2) | ||
767 | +GEN_VEXT_VX(vwsub_vx_h, 2, 4) | ||
768 | +GEN_VEXT_VX(vwsub_vx_w, 4, 8) | ||
769 | +GEN_VEXT_VX(vwaddu_wx_b, 1, 2) | ||
770 | +GEN_VEXT_VX(vwaddu_wx_h, 2, 4) | ||
771 | +GEN_VEXT_VX(vwaddu_wx_w, 4, 8) | ||
772 | +GEN_VEXT_VX(vwsubu_wx_b, 1, 2) | ||
773 | +GEN_VEXT_VX(vwsubu_wx_h, 2, 4) | ||
774 | +GEN_VEXT_VX(vwsubu_wx_w, 4, 8) | ||
775 | +GEN_VEXT_VX(vwadd_wx_b, 1, 2) | ||
776 | +GEN_VEXT_VX(vwadd_wx_h, 2, 4) | ||
777 | +GEN_VEXT_VX(vwadd_wx_w, 4, 8) | ||
778 | +GEN_VEXT_VX(vwsub_wx_b, 1, 2) | ||
779 | +GEN_VEXT_VX(vwsub_wx_h, 2, 4) | ||
780 | +GEN_VEXT_VX(vwsub_wx_w, 4, 8) | ||
781 | |||
782 | /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */ | ||
783 | #define DO_VADC(N, M, C) (N + M + C) | ||
784 | #define DO_VSBC(N, M, C) (N - M - C) | ||
785 | |||
786 | -#define GEN_VEXT_VADC_VVM(NAME, ETYPE, H, DO_OP, CLEAR_FN) \ | ||
787 | +#define GEN_VEXT_VADC_VVM(NAME, ETYPE, H, DO_OP) \ | ||
788 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
789 | CPURISCVState *env, uint32_t desc) \ | ||
790 | { \ | ||
791 | uint32_t vl = env->vl; \ | ||
792 | - uint32_t esz = sizeof(ETYPE); \ | ||
793 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
794 | uint32_t i; \ | ||
795 | \ | ||
796 | for (i = 0; i < vl; i++) { \ | ||
797 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
798 | \ | ||
799 | *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \ | ||
800 | } \ | ||
801 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
802 | } | ||
803 | |||
804 | -GEN_VEXT_VADC_VVM(vadc_vvm_b, uint8_t, H1, DO_VADC, clearb) | ||
805 | -GEN_VEXT_VADC_VVM(vadc_vvm_h, uint16_t, H2, DO_VADC, clearh) | ||
806 | -GEN_VEXT_VADC_VVM(vadc_vvm_w, uint32_t, H4, DO_VADC, clearl) | ||
807 | -GEN_VEXT_VADC_VVM(vadc_vvm_d, uint64_t, H8, DO_VADC, clearq) | ||
808 | +GEN_VEXT_VADC_VVM(vadc_vvm_b, uint8_t, H1, DO_VADC) | ||
809 | +GEN_VEXT_VADC_VVM(vadc_vvm_h, uint16_t, H2, DO_VADC) | ||
810 | +GEN_VEXT_VADC_VVM(vadc_vvm_w, uint32_t, H4, DO_VADC) | ||
811 | +GEN_VEXT_VADC_VVM(vadc_vvm_d, uint64_t, H8, DO_VADC) | ||
812 | |||
813 | -GEN_VEXT_VADC_VVM(vsbc_vvm_b, uint8_t, H1, DO_VSBC, clearb) | ||
814 | -GEN_VEXT_VADC_VVM(vsbc_vvm_h, uint16_t, H2, DO_VSBC, clearh) | ||
815 | -GEN_VEXT_VADC_VVM(vsbc_vvm_w, uint32_t, H4, DO_VSBC, clearl) | ||
816 | -GEN_VEXT_VADC_VVM(vsbc_vvm_d, uint64_t, H8, DO_VSBC, clearq) | ||
817 | +GEN_VEXT_VADC_VVM(vsbc_vvm_b, uint8_t, H1, DO_VSBC) | ||
818 | +GEN_VEXT_VADC_VVM(vsbc_vvm_h, uint16_t, H2, DO_VSBC) | ||
819 | +GEN_VEXT_VADC_VVM(vsbc_vvm_w, uint32_t, H4, DO_VSBC) | ||
820 | +GEN_VEXT_VADC_VVM(vsbc_vvm_d, uint64_t, H8, DO_VSBC) | ||
821 | |||
822 | -#define GEN_VEXT_VADC_VXM(NAME, ETYPE, H, DO_OP, CLEAR_FN) \ | ||
823 | +#define GEN_VEXT_VADC_VXM(NAME, ETYPE, H, DO_OP) \ | ||
824 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
825 | CPURISCVState *env, uint32_t desc) \ | ||
826 | { \ | ||
827 | uint32_t vl = env->vl; \ | ||
828 | - uint32_t esz = sizeof(ETYPE); \ | ||
829 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
830 | uint32_t i; \ | ||
831 | \ | ||
832 | for (i = 0; i < vl; i++) { \ | ||
833 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
834 | \ | ||
835 | *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\ | ||
836 | } \ | ||
837 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
838 | } | ||
839 | |||
840 | -GEN_VEXT_VADC_VXM(vadc_vxm_b, uint8_t, H1, DO_VADC, clearb) | ||
841 | -GEN_VEXT_VADC_VXM(vadc_vxm_h, uint16_t, H2, DO_VADC, clearh) | ||
842 | -GEN_VEXT_VADC_VXM(vadc_vxm_w, uint32_t, H4, DO_VADC, clearl) | ||
843 | -GEN_VEXT_VADC_VXM(vadc_vxm_d, uint64_t, H8, DO_VADC, clearq) | ||
844 | +GEN_VEXT_VADC_VXM(vadc_vxm_b, uint8_t, H1, DO_VADC) | ||
845 | +GEN_VEXT_VADC_VXM(vadc_vxm_h, uint16_t, H2, DO_VADC) | ||
846 | +GEN_VEXT_VADC_VXM(vadc_vxm_w, uint32_t, H4, DO_VADC) | ||
847 | +GEN_VEXT_VADC_VXM(vadc_vxm_d, uint64_t, H8, DO_VADC) | ||
848 | |||
849 | -GEN_VEXT_VADC_VXM(vsbc_vxm_b, uint8_t, H1, DO_VSBC, clearb) | ||
850 | -GEN_VEXT_VADC_VXM(vsbc_vxm_h, uint16_t, H2, DO_VSBC, clearh) | ||
851 | -GEN_VEXT_VADC_VXM(vsbc_vxm_w, uint32_t, H4, DO_VSBC, clearl) | ||
852 | -GEN_VEXT_VADC_VXM(vsbc_vxm_d, uint64_t, H8, DO_VSBC, clearq) | ||
853 | +GEN_VEXT_VADC_VXM(vsbc_vxm_b, uint8_t, H1, DO_VSBC) | ||
854 | +GEN_VEXT_VADC_VXM(vsbc_vxm_h, uint16_t, H2, DO_VSBC) | ||
855 | +GEN_VEXT_VADC_VXM(vsbc_vxm_w, uint32_t, H4, DO_VSBC) | ||
856 | +GEN_VEXT_VADC_VXM(vsbc_vxm_d, uint64_t, H8, DO_VSBC) | ||
857 | |||
858 | #define DO_MADC(N, M, C) (C ? (__typeof(N))(N + M + 1) <= N : \ | ||
859 | (__typeof(N))(N + M) < N) | ||
860 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vxor_vv_b, OP_SSS_B, H1, H1, H1, DO_XOR) | ||
861 | RVVCALL(OPIVV2, vxor_vv_h, OP_SSS_H, H2, H2, H2, DO_XOR) | ||
862 | RVVCALL(OPIVV2, vxor_vv_w, OP_SSS_W, H4, H4, H4, DO_XOR) | ||
863 | RVVCALL(OPIVV2, vxor_vv_d, OP_SSS_D, H8, H8, H8, DO_XOR) | ||
864 | -GEN_VEXT_VV(vand_vv_b, 1, 1, clearb) | ||
865 | -GEN_VEXT_VV(vand_vv_h, 2, 2, clearh) | ||
866 | -GEN_VEXT_VV(vand_vv_w, 4, 4, clearl) | ||
867 | -GEN_VEXT_VV(vand_vv_d, 8, 8, clearq) | ||
868 | -GEN_VEXT_VV(vor_vv_b, 1, 1, clearb) | ||
869 | -GEN_VEXT_VV(vor_vv_h, 2, 2, clearh) | ||
870 | -GEN_VEXT_VV(vor_vv_w, 4, 4, clearl) | ||
871 | -GEN_VEXT_VV(vor_vv_d, 8, 8, clearq) | ||
872 | -GEN_VEXT_VV(vxor_vv_b, 1, 1, clearb) | ||
873 | -GEN_VEXT_VV(vxor_vv_h, 2, 2, clearh) | ||
874 | -GEN_VEXT_VV(vxor_vv_w, 4, 4, clearl) | ||
875 | -GEN_VEXT_VV(vxor_vv_d, 8, 8, clearq) | ||
876 | +GEN_VEXT_VV(vand_vv_b, 1, 1) | ||
877 | +GEN_VEXT_VV(vand_vv_h, 2, 2) | ||
878 | +GEN_VEXT_VV(vand_vv_w, 4, 4) | ||
879 | +GEN_VEXT_VV(vand_vv_d, 8, 8) | ||
880 | +GEN_VEXT_VV(vor_vv_b, 1, 1) | ||
881 | +GEN_VEXT_VV(vor_vv_h, 2, 2) | ||
882 | +GEN_VEXT_VV(vor_vv_w, 4, 4) | ||
883 | +GEN_VEXT_VV(vor_vv_d, 8, 8) | ||
884 | +GEN_VEXT_VV(vxor_vv_b, 1, 1) | ||
885 | +GEN_VEXT_VV(vxor_vv_h, 2, 2) | ||
886 | +GEN_VEXT_VV(vxor_vv_w, 4, 4) | ||
887 | +GEN_VEXT_VV(vxor_vv_d, 8, 8) | ||
888 | |||
889 | RVVCALL(OPIVX2, vand_vx_b, OP_SSS_B, H1, H1, DO_AND) | ||
890 | RVVCALL(OPIVX2, vand_vx_h, OP_SSS_H, H2, H2, DO_AND) | ||
891 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vxor_vx_b, OP_SSS_B, H1, H1, DO_XOR) | ||
892 | RVVCALL(OPIVX2, vxor_vx_h, OP_SSS_H, H2, H2, DO_XOR) | ||
893 | RVVCALL(OPIVX2, vxor_vx_w, OP_SSS_W, H4, H4, DO_XOR) | ||
894 | RVVCALL(OPIVX2, vxor_vx_d, OP_SSS_D, H8, H8, DO_XOR) | ||
895 | -GEN_VEXT_VX(vand_vx_b, 1, 1, clearb) | ||
896 | -GEN_VEXT_VX(vand_vx_h, 2, 2, clearh) | ||
897 | -GEN_VEXT_VX(vand_vx_w, 4, 4, clearl) | ||
898 | -GEN_VEXT_VX(vand_vx_d, 8, 8, clearq) | ||
899 | -GEN_VEXT_VX(vor_vx_b, 1, 1, clearb) | ||
900 | -GEN_VEXT_VX(vor_vx_h, 2, 2, clearh) | ||
901 | -GEN_VEXT_VX(vor_vx_w, 4, 4, clearl) | ||
902 | -GEN_VEXT_VX(vor_vx_d, 8, 8, clearq) | ||
903 | -GEN_VEXT_VX(vxor_vx_b, 1, 1, clearb) | ||
904 | -GEN_VEXT_VX(vxor_vx_h, 2, 2, clearh) | ||
905 | -GEN_VEXT_VX(vxor_vx_w, 4, 4, clearl) | ||
906 | -GEN_VEXT_VX(vxor_vx_d, 8, 8, clearq) | ||
907 | +GEN_VEXT_VX(vand_vx_b, 1, 1) | ||
908 | +GEN_VEXT_VX(vand_vx_h, 2, 2) | ||
909 | +GEN_VEXT_VX(vand_vx_w, 4, 4) | ||
910 | +GEN_VEXT_VX(vand_vx_d, 8, 8) | ||
911 | +GEN_VEXT_VX(vor_vx_b, 1, 1) | ||
912 | +GEN_VEXT_VX(vor_vx_h, 2, 2) | ||
913 | +GEN_VEXT_VX(vor_vx_w, 4, 4) | ||
914 | +GEN_VEXT_VX(vor_vx_d, 8, 8) | ||
915 | +GEN_VEXT_VX(vxor_vx_b, 1, 1) | ||
916 | +GEN_VEXT_VX(vxor_vx_h, 2, 2) | ||
917 | +GEN_VEXT_VX(vxor_vx_w, 4, 4) | ||
918 | +GEN_VEXT_VX(vxor_vx_d, 8, 8) | ||
919 | |||
920 | /* Vector Single-Width Bit Shift Instructions */ | ||
921 | #define DO_SLL(N, M) (N << (M)) | ||
922 | #define DO_SRL(N, M) (N >> (M)) | ||
923 | |||
924 | /* generate the helpers for shift instructions with two vector operators */ | ||
925 | -#define GEN_VEXT_SHIFT_VV(NAME, TS1, TS2, HS1, HS2, OP, MASK, CLEAR_FN) \ | ||
926 | +#define GEN_VEXT_SHIFT_VV(NAME, TS1, TS2, HS1, HS2, OP, MASK) \ | ||
927 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
928 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
929 | { \ | ||
930 | uint32_t vm = vext_vm(desc); \ | ||
931 | uint32_t vl = env->vl; \ | ||
932 | - uint32_t esz = sizeof(TS1); \ | ||
933 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
934 | uint32_t i; \ | ||
935 | \ | ||
936 | for (i = 0; i < vl; i++) { \ | ||
937 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
938 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
939 | *((TS1 *)vd + HS1(i)) = OP(s2, s1 & MASK); \ | ||
940 | } \ | ||
941 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
942 | } | ||
943 | |||
944 | -GEN_VEXT_SHIFT_VV(vsll_vv_b, uint8_t, uint8_t, H1, H1, DO_SLL, 0x7, clearb) | ||
945 | -GEN_VEXT_SHIFT_VV(vsll_vv_h, uint16_t, uint16_t, H2, H2, DO_SLL, 0xf, clearh) | ||
946 | -GEN_VEXT_SHIFT_VV(vsll_vv_w, uint32_t, uint32_t, H4, H4, DO_SLL, 0x1f, clearl) | ||
947 | -GEN_VEXT_SHIFT_VV(vsll_vv_d, uint64_t, uint64_t, H8, H8, DO_SLL, 0x3f, clearq) | ||
948 | +GEN_VEXT_SHIFT_VV(vsll_vv_b, uint8_t, uint8_t, H1, H1, DO_SLL, 0x7) | ||
949 | +GEN_VEXT_SHIFT_VV(vsll_vv_h, uint16_t, uint16_t, H2, H2, DO_SLL, 0xf) | ||
950 | +GEN_VEXT_SHIFT_VV(vsll_vv_w, uint32_t, uint32_t, H4, H4, DO_SLL, 0x1f) | ||
951 | +GEN_VEXT_SHIFT_VV(vsll_vv_d, uint64_t, uint64_t, H8, H8, DO_SLL, 0x3f) | ||
952 | |||
953 | -GEN_VEXT_SHIFT_VV(vsrl_vv_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7, clearb) | ||
954 | -GEN_VEXT_SHIFT_VV(vsrl_vv_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf, clearh) | ||
955 | -GEN_VEXT_SHIFT_VV(vsrl_vv_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f, clearl) | ||
956 | -GEN_VEXT_SHIFT_VV(vsrl_vv_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f, clearq) | ||
957 | +GEN_VEXT_SHIFT_VV(vsrl_vv_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7) | ||
958 | +GEN_VEXT_SHIFT_VV(vsrl_vv_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf) | ||
959 | +GEN_VEXT_SHIFT_VV(vsrl_vv_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f) | ||
960 | +GEN_VEXT_SHIFT_VV(vsrl_vv_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f) | ||
961 | |||
962 | -GEN_VEXT_SHIFT_VV(vsra_vv_b, uint8_t, int8_t, H1, H1, DO_SRL, 0x7, clearb) | ||
963 | -GEN_VEXT_SHIFT_VV(vsra_vv_h, uint16_t, int16_t, H2, H2, DO_SRL, 0xf, clearh) | ||
964 | -GEN_VEXT_SHIFT_VV(vsra_vv_w, uint32_t, int32_t, H4, H4, DO_SRL, 0x1f, clearl) | ||
965 | -GEN_VEXT_SHIFT_VV(vsra_vv_d, uint64_t, int64_t, H8, H8, DO_SRL, 0x3f, clearq) | ||
966 | +GEN_VEXT_SHIFT_VV(vsra_vv_b, uint8_t, int8_t, H1, H1, DO_SRL, 0x7) | ||
967 | +GEN_VEXT_SHIFT_VV(vsra_vv_h, uint16_t, int16_t, H2, H2, DO_SRL, 0xf) | ||
968 | +GEN_VEXT_SHIFT_VV(vsra_vv_w, uint32_t, int32_t, H4, H4, DO_SRL, 0x1f) | ||
969 | +GEN_VEXT_SHIFT_VV(vsra_vv_d, uint64_t, int64_t, H8, H8, DO_SRL, 0x3f) | ||
970 | |||
971 | /* generate the helpers for shift instructions with one vector and one scalar */ | ||
972 | -#define GEN_VEXT_SHIFT_VX(NAME, TD, TS2, HD, HS2, OP, MASK, CLEAR_FN) \ | ||
973 | -void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
974 | - void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
975 | -{ \ | ||
976 | - uint32_t vm = vext_vm(desc); \ | ||
977 | - uint32_t vl = env->vl; \ | ||
978 | - uint32_t esz = sizeof(TD); \ | ||
979 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
980 | - uint32_t i; \ | ||
981 | - \ | ||
982 | - for (i = 0; i < vl; i++) { \ | ||
983 | - if (!vm && !vext_elem_mask(v0, i)) { \ | ||
984 | - continue; \ | ||
985 | - } \ | ||
986 | - TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
987 | - *((TD *)vd + HD(i)) = OP(s2, s1 & MASK); \ | ||
988 | - } \ | ||
989 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
990 | -} | ||
991 | - | ||
992 | -GEN_VEXT_SHIFT_VX(vsll_vx_b, uint8_t, int8_t, H1, H1, DO_SLL, 0x7, clearb) | ||
993 | -GEN_VEXT_SHIFT_VX(vsll_vx_h, uint16_t, int16_t, H2, H2, DO_SLL, 0xf, clearh) | ||
994 | -GEN_VEXT_SHIFT_VX(vsll_vx_w, uint32_t, int32_t, H4, H4, DO_SLL, 0x1f, clearl) | ||
995 | -GEN_VEXT_SHIFT_VX(vsll_vx_d, uint64_t, int64_t, H8, H8, DO_SLL, 0x3f, clearq) | ||
996 | - | ||
997 | -GEN_VEXT_SHIFT_VX(vsrl_vx_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7, clearb) | ||
998 | -GEN_VEXT_SHIFT_VX(vsrl_vx_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf, clearh) | ||
999 | -GEN_VEXT_SHIFT_VX(vsrl_vx_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f, clearl) | ||
1000 | -GEN_VEXT_SHIFT_VX(vsrl_vx_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f, clearq) | ||
1001 | - | ||
1002 | -GEN_VEXT_SHIFT_VX(vsra_vx_b, int8_t, int8_t, H1, H1, DO_SRL, 0x7, clearb) | ||
1003 | -GEN_VEXT_SHIFT_VX(vsra_vx_h, int16_t, int16_t, H2, H2, DO_SRL, 0xf, clearh) | ||
1004 | -GEN_VEXT_SHIFT_VX(vsra_vx_w, int32_t, int32_t, H4, H4, DO_SRL, 0x1f, clearl) | ||
1005 | -GEN_VEXT_SHIFT_VX(vsra_vx_d, int64_t, int64_t, H8, H8, DO_SRL, 0x3f, clearq) | ||
1006 | +#define GEN_VEXT_SHIFT_VX(NAME, TD, TS2, HD, HS2, OP, MASK) \ | ||
1007 | +void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
1008 | + void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
1009 | +{ \ | ||
1010 | + uint32_t vm = vext_vm(desc); \ | ||
1011 | + uint32_t vl = env->vl; \ | ||
1012 | + uint32_t i; \ | ||
1013 | + \ | ||
1014 | + for (i = 0; i < vl; i++) { \ | ||
1015 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
1016 | + continue; \ | ||
1017 | + } \ | ||
1018 | + TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
1019 | + *((TD *)vd + HD(i)) = OP(s2, s1 & MASK); \ | ||
1020 | + } \ | ||
1021 | +} | ||
1022 | + | ||
1023 | +GEN_VEXT_SHIFT_VX(vsll_vx_b, uint8_t, int8_t, H1, H1, DO_SLL, 0x7) | ||
1024 | +GEN_VEXT_SHIFT_VX(vsll_vx_h, uint16_t, int16_t, H2, H2, DO_SLL, 0xf) | ||
1025 | +GEN_VEXT_SHIFT_VX(vsll_vx_w, uint32_t, int32_t, H4, H4, DO_SLL, 0x1f) | ||
1026 | +GEN_VEXT_SHIFT_VX(vsll_vx_d, uint64_t, int64_t, H8, H8, DO_SLL, 0x3f) | ||
1027 | + | ||
1028 | +GEN_VEXT_SHIFT_VX(vsrl_vx_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7) | ||
1029 | +GEN_VEXT_SHIFT_VX(vsrl_vx_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf) | ||
1030 | +GEN_VEXT_SHIFT_VX(vsrl_vx_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f) | ||
1031 | +GEN_VEXT_SHIFT_VX(vsrl_vx_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f) | ||
1032 | + | ||
1033 | +GEN_VEXT_SHIFT_VX(vsra_vx_b, int8_t, int8_t, H1, H1, DO_SRL, 0x7) | ||
1034 | +GEN_VEXT_SHIFT_VX(vsra_vx_h, int16_t, int16_t, H2, H2, DO_SRL, 0xf) | ||
1035 | +GEN_VEXT_SHIFT_VX(vsra_vx_w, int32_t, int32_t, H4, H4, DO_SRL, 0x1f) | ||
1036 | +GEN_VEXT_SHIFT_VX(vsra_vx_d, int64_t, int64_t, H8, H8, DO_SRL, 0x3f) | ||
1037 | |||
1038 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
1039 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf, clearb) | ||
1040 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f, clearh) | ||
1041 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f, clearl) | ||
1042 | -GEN_VEXT_SHIFT_VV(vnsra_vv_b, uint8_t, int16_t, H1, H2, DO_SRL, 0xf, clearb) | ||
1043 | -GEN_VEXT_SHIFT_VV(vnsra_vv_h, uint16_t, int32_t, H2, H4, DO_SRL, 0x1f, clearh) | ||
1044 | -GEN_VEXT_SHIFT_VV(vnsra_vv_w, uint32_t, int64_t, H4, H8, DO_SRL, 0x3f, clearl) | ||
1045 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf, clearb) | ||
1046 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f, clearh) | ||
1047 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f, clearl) | ||
1048 | -GEN_VEXT_SHIFT_VX(vnsra_vx_b, int8_t, int16_t, H1, H2, DO_SRL, 0xf, clearb) | ||
1049 | -GEN_VEXT_SHIFT_VX(vnsra_vx_h, int16_t, int32_t, H2, H4, DO_SRL, 0x1f, clearh) | ||
1050 | -GEN_VEXT_SHIFT_VX(vnsra_vx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f, clearl) | ||
1051 | +GEN_VEXT_SHIFT_VV(vnsrl_vv_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
1052 | +GEN_VEXT_SHIFT_VV(vnsrl_vv_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
1053 | +GEN_VEXT_SHIFT_VV(vnsrl_vv_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
1054 | +GEN_VEXT_SHIFT_VV(vnsra_vv_b, uint8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
1055 | +GEN_VEXT_SHIFT_VV(vnsra_vv_h, uint16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
1056 | +GEN_VEXT_SHIFT_VV(vnsra_vv_w, uint32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
1057 | +GEN_VEXT_SHIFT_VX(vnsrl_vx_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
1058 | +GEN_VEXT_SHIFT_VX(vnsrl_vx_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
1059 | +GEN_VEXT_SHIFT_VX(vnsrl_vx_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
1060 | +GEN_VEXT_SHIFT_VX(vnsra_vx_b, int8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
1061 | +GEN_VEXT_SHIFT_VX(vnsra_vx_h, int16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
1062 | +GEN_VEXT_SHIFT_VX(vnsra_vx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
1063 | |||
1064 | /* Vector Integer Comparison Instructions */ | ||
1065 | #define DO_MSEQ(N, M) (N == M) | ||
1066 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vmax_vv_b, OP_SSS_B, H1, H1, H1, DO_MAX) | ||
1067 | RVVCALL(OPIVV2, vmax_vv_h, OP_SSS_H, H2, H2, H2, DO_MAX) | ||
1068 | RVVCALL(OPIVV2, vmax_vv_w, OP_SSS_W, H4, H4, H4, DO_MAX) | ||
1069 | RVVCALL(OPIVV2, vmax_vv_d, OP_SSS_D, H8, H8, H8, DO_MAX) | ||
1070 | -GEN_VEXT_VV(vminu_vv_b, 1, 1, clearb) | ||
1071 | -GEN_VEXT_VV(vminu_vv_h, 2, 2, clearh) | ||
1072 | -GEN_VEXT_VV(vminu_vv_w, 4, 4, clearl) | ||
1073 | -GEN_VEXT_VV(vminu_vv_d, 8, 8, clearq) | ||
1074 | -GEN_VEXT_VV(vmin_vv_b, 1, 1, clearb) | ||
1075 | -GEN_VEXT_VV(vmin_vv_h, 2, 2, clearh) | ||
1076 | -GEN_VEXT_VV(vmin_vv_w, 4, 4, clearl) | ||
1077 | -GEN_VEXT_VV(vmin_vv_d, 8, 8, clearq) | ||
1078 | -GEN_VEXT_VV(vmaxu_vv_b, 1, 1, clearb) | ||
1079 | -GEN_VEXT_VV(vmaxu_vv_h, 2, 2, clearh) | ||
1080 | -GEN_VEXT_VV(vmaxu_vv_w, 4, 4, clearl) | ||
1081 | -GEN_VEXT_VV(vmaxu_vv_d, 8, 8, clearq) | ||
1082 | -GEN_VEXT_VV(vmax_vv_b, 1, 1, clearb) | ||
1083 | -GEN_VEXT_VV(vmax_vv_h, 2, 2, clearh) | ||
1084 | -GEN_VEXT_VV(vmax_vv_w, 4, 4, clearl) | ||
1085 | -GEN_VEXT_VV(vmax_vv_d, 8, 8, clearq) | ||
1086 | +GEN_VEXT_VV(vminu_vv_b, 1, 1) | ||
1087 | +GEN_VEXT_VV(vminu_vv_h, 2, 2) | ||
1088 | +GEN_VEXT_VV(vminu_vv_w, 4, 4) | ||
1089 | +GEN_VEXT_VV(vminu_vv_d, 8, 8) | ||
1090 | +GEN_VEXT_VV(vmin_vv_b, 1, 1) | ||
1091 | +GEN_VEXT_VV(vmin_vv_h, 2, 2) | ||
1092 | +GEN_VEXT_VV(vmin_vv_w, 4, 4) | ||
1093 | +GEN_VEXT_VV(vmin_vv_d, 8, 8) | ||
1094 | +GEN_VEXT_VV(vmaxu_vv_b, 1, 1) | ||
1095 | +GEN_VEXT_VV(vmaxu_vv_h, 2, 2) | ||
1096 | +GEN_VEXT_VV(vmaxu_vv_w, 4, 4) | ||
1097 | +GEN_VEXT_VV(vmaxu_vv_d, 8, 8) | ||
1098 | +GEN_VEXT_VV(vmax_vv_b, 1, 1) | ||
1099 | +GEN_VEXT_VV(vmax_vv_h, 2, 2) | ||
1100 | +GEN_VEXT_VV(vmax_vv_w, 4, 4) | ||
1101 | +GEN_VEXT_VV(vmax_vv_d, 8, 8) | ||
1102 | |||
1103 | RVVCALL(OPIVX2, vminu_vx_b, OP_UUU_B, H1, H1, DO_MIN) | ||
1104 | RVVCALL(OPIVX2, vminu_vx_h, OP_UUU_H, H2, H2, DO_MIN) | ||
1105 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vmax_vx_b, OP_SSS_B, H1, H1, DO_MAX) | ||
1106 | RVVCALL(OPIVX2, vmax_vx_h, OP_SSS_H, H2, H2, DO_MAX) | ||
1107 | RVVCALL(OPIVX2, vmax_vx_w, OP_SSS_W, H4, H4, DO_MAX) | ||
1108 | RVVCALL(OPIVX2, vmax_vx_d, OP_SSS_D, H8, H8, DO_MAX) | ||
1109 | -GEN_VEXT_VX(vminu_vx_b, 1, 1, clearb) | ||
1110 | -GEN_VEXT_VX(vminu_vx_h, 2, 2, clearh) | ||
1111 | -GEN_VEXT_VX(vminu_vx_w, 4, 4, clearl) | ||
1112 | -GEN_VEXT_VX(vminu_vx_d, 8, 8, clearq) | ||
1113 | -GEN_VEXT_VX(vmin_vx_b, 1, 1, clearb) | ||
1114 | -GEN_VEXT_VX(vmin_vx_h, 2, 2, clearh) | ||
1115 | -GEN_VEXT_VX(vmin_vx_w, 4, 4, clearl) | ||
1116 | -GEN_VEXT_VX(vmin_vx_d, 8, 8, clearq) | ||
1117 | -GEN_VEXT_VX(vmaxu_vx_b, 1, 1, clearb) | ||
1118 | -GEN_VEXT_VX(vmaxu_vx_h, 2, 2, clearh) | ||
1119 | -GEN_VEXT_VX(vmaxu_vx_w, 4, 4, clearl) | ||
1120 | -GEN_VEXT_VX(vmaxu_vx_d, 8, 8, clearq) | ||
1121 | -GEN_VEXT_VX(vmax_vx_b, 1, 1, clearb) | ||
1122 | -GEN_VEXT_VX(vmax_vx_h, 2, 2, clearh) | ||
1123 | -GEN_VEXT_VX(vmax_vx_w, 4, 4, clearl) | ||
1124 | -GEN_VEXT_VX(vmax_vx_d, 8, 8, clearq) | ||
1125 | +GEN_VEXT_VX(vminu_vx_b, 1, 1) | ||
1126 | +GEN_VEXT_VX(vminu_vx_h, 2, 2) | ||
1127 | +GEN_VEXT_VX(vminu_vx_w, 4, 4) | ||
1128 | +GEN_VEXT_VX(vminu_vx_d, 8, 8) | ||
1129 | +GEN_VEXT_VX(vmin_vx_b, 1, 1) | ||
1130 | +GEN_VEXT_VX(vmin_vx_h, 2, 2) | ||
1131 | +GEN_VEXT_VX(vmin_vx_w, 4, 4) | ||
1132 | +GEN_VEXT_VX(vmin_vx_d, 8, 8) | ||
1133 | +GEN_VEXT_VX(vmaxu_vx_b, 1, 1) | ||
1134 | +GEN_VEXT_VX(vmaxu_vx_h, 2, 2) | ||
1135 | +GEN_VEXT_VX(vmaxu_vx_w, 4, 4) | ||
1136 | +GEN_VEXT_VX(vmaxu_vx_d, 8, 8) | ||
1137 | +GEN_VEXT_VX(vmax_vx_b, 1, 1) | ||
1138 | +GEN_VEXT_VX(vmax_vx_h, 2, 2) | ||
1139 | +GEN_VEXT_VX(vmax_vx_w, 4, 4) | ||
1140 | +GEN_VEXT_VX(vmax_vx_d, 8, 8) | ||
1141 | |||
1142 | /* Vector Single-Width Integer Multiply Instructions */ | ||
1143 | #define DO_MUL(N, M) (N * M) | ||
1144 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vmul_vv_b, OP_SSS_B, H1, H1, H1, DO_MUL) | ||
1145 | RVVCALL(OPIVV2, vmul_vv_h, OP_SSS_H, H2, H2, H2, DO_MUL) | ||
1146 | RVVCALL(OPIVV2, vmul_vv_w, OP_SSS_W, H4, H4, H4, DO_MUL) | ||
1147 | RVVCALL(OPIVV2, vmul_vv_d, OP_SSS_D, H8, H8, H8, DO_MUL) | ||
1148 | -GEN_VEXT_VV(vmul_vv_b, 1, 1, clearb) | ||
1149 | -GEN_VEXT_VV(vmul_vv_h, 2, 2, clearh) | ||
1150 | -GEN_VEXT_VV(vmul_vv_w, 4, 4, clearl) | ||
1151 | -GEN_VEXT_VV(vmul_vv_d, 8, 8, clearq) | ||
1152 | +GEN_VEXT_VV(vmul_vv_b, 1, 1) | ||
1153 | +GEN_VEXT_VV(vmul_vv_h, 2, 2) | ||
1154 | +GEN_VEXT_VV(vmul_vv_w, 4, 4) | ||
1155 | +GEN_VEXT_VV(vmul_vv_d, 8, 8) | ||
1156 | |||
1157 | static int8_t do_mulh_b(int8_t s2, int8_t s1) | ||
1158 | { | ||
1159 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vmulhsu_vv_b, OP_SUS_B, H1, H1, H1, do_mulhsu_b) | ||
1160 | RVVCALL(OPIVV2, vmulhsu_vv_h, OP_SUS_H, H2, H2, H2, do_mulhsu_h) | ||
1161 | RVVCALL(OPIVV2, vmulhsu_vv_w, OP_SUS_W, H4, H4, H4, do_mulhsu_w) | ||
1162 | RVVCALL(OPIVV2, vmulhsu_vv_d, OP_SUS_D, H8, H8, H8, do_mulhsu_d) | ||
1163 | -GEN_VEXT_VV(vmulh_vv_b, 1, 1, clearb) | ||
1164 | -GEN_VEXT_VV(vmulh_vv_h, 2, 2, clearh) | ||
1165 | -GEN_VEXT_VV(vmulh_vv_w, 4, 4, clearl) | ||
1166 | -GEN_VEXT_VV(vmulh_vv_d, 8, 8, clearq) | ||
1167 | -GEN_VEXT_VV(vmulhu_vv_b, 1, 1, clearb) | ||
1168 | -GEN_VEXT_VV(vmulhu_vv_h, 2, 2, clearh) | ||
1169 | -GEN_VEXT_VV(vmulhu_vv_w, 4, 4, clearl) | ||
1170 | -GEN_VEXT_VV(vmulhu_vv_d, 8, 8, clearq) | ||
1171 | -GEN_VEXT_VV(vmulhsu_vv_b, 1, 1, clearb) | ||
1172 | -GEN_VEXT_VV(vmulhsu_vv_h, 2, 2, clearh) | ||
1173 | -GEN_VEXT_VV(vmulhsu_vv_w, 4, 4, clearl) | ||
1174 | -GEN_VEXT_VV(vmulhsu_vv_d, 8, 8, clearq) | ||
1175 | +GEN_VEXT_VV(vmulh_vv_b, 1, 1) | ||
1176 | +GEN_VEXT_VV(vmulh_vv_h, 2, 2) | ||
1177 | +GEN_VEXT_VV(vmulh_vv_w, 4, 4) | ||
1178 | +GEN_VEXT_VV(vmulh_vv_d, 8, 8) | ||
1179 | +GEN_VEXT_VV(vmulhu_vv_b, 1, 1) | ||
1180 | +GEN_VEXT_VV(vmulhu_vv_h, 2, 2) | ||
1181 | +GEN_VEXT_VV(vmulhu_vv_w, 4, 4) | ||
1182 | +GEN_VEXT_VV(vmulhu_vv_d, 8, 8) | ||
1183 | +GEN_VEXT_VV(vmulhsu_vv_b, 1, 1) | ||
1184 | +GEN_VEXT_VV(vmulhsu_vv_h, 2, 2) | ||
1185 | +GEN_VEXT_VV(vmulhsu_vv_w, 4, 4) | ||
1186 | +GEN_VEXT_VV(vmulhsu_vv_d, 8, 8) | ||
1187 | |||
1188 | RVVCALL(OPIVX2, vmul_vx_b, OP_SSS_B, H1, H1, DO_MUL) | ||
1189 | RVVCALL(OPIVX2, vmul_vx_h, OP_SSS_H, H2, H2, DO_MUL) | ||
1190 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vmulhsu_vx_b, OP_SUS_B, H1, H1, do_mulhsu_b) | ||
1191 | RVVCALL(OPIVX2, vmulhsu_vx_h, OP_SUS_H, H2, H2, do_mulhsu_h) | ||
1192 | RVVCALL(OPIVX2, vmulhsu_vx_w, OP_SUS_W, H4, H4, do_mulhsu_w) | ||
1193 | RVVCALL(OPIVX2, vmulhsu_vx_d, OP_SUS_D, H8, H8, do_mulhsu_d) | ||
1194 | -GEN_VEXT_VX(vmul_vx_b, 1, 1, clearb) | ||
1195 | -GEN_VEXT_VX(vmul_vx_h, 2, 2, clearh) | ||
1196 | -GEN_VEXT_VX(vmul_vx_w, 4, 4, clearl) | ||
1197 | -GEN_VEXT_VX(vmul_vx_d, 8, 8, clearq) | ||
1198 | -GEN_VEXT_VX(vmulh_vx_b, 1, 1, clearb) | ||
1199 | -GEN_VEXT_VX(vmulh_vx_h, 2, 2, clearh) | ||
1200 | -GEN_VEXT_VX(vmulh_vx_w, 4, 4, clearl) | ||
1201 | -GEN_VEXT_VX(vmulh_vx_d, 8, 8, clearq) | ||
1202 | -GEN_VEXT_VX(vmulhu_vx_b, 1, 1, clearb) | ||
1203 | -GEN_VEXT_VX(vmulhu_vx_h, 2, 2, clearh) | ||
1204 | -GEN_VEXT_VX(vmulhu_vx_w, 4, 4, clearl) | ||
1205 | -GEN_VEXT_VX(vmulhu_vx_d, 8, 8, clearq) | ||
1206 | -GEN_VEXT_VX(vmulhsu_vx_b, 1, 1, clearb) | ||
1207 | -GEN_VEXT_VX(vmulhsu_vx_h, 2, 2, clearh) | ||
1208 | -GEN_VEXT_VX(vmulhsu_vx_w, 4, 4, clearl) | ||
1209 | -GEN_VEXT_VX(vmulhsu_vx_d, 8, 8, clearq) | ||
1210 | +GEN_VEXT_VX(vmul_vx_b, 1, 1) | ||
1211 | +GEN_VEXT_VX(vmul_vx_h, 2, 2) | ||
1212 | +GEN_VEXT_VX(vmul_vx_w, 4, 4) | ||
1213 | +GEN_VEXT_VX(vmul_vx_d, 8, 8) | ||
1214 | +GEN_VEXT_VX(vmulh_vx_b, 1, 1) | ||
1215 | +GEN_VEXT_VX(vmulh_vx_h, 2, 2) | ||
1216 | +GEN_VEXT_VX(vmulh_vx_w, 4, 4) | ||
1217 | +GEN_VEXT_VX(vmulh_vx_d, 8, 8) | ||
1218 | +GEN_VEXT_VX(vmulhu_vx_b, 1, 1) | ||
1219 | +GEN_VEXT_VX(vmulhu_vx_h, 2, 2) | ||
1220 | +GEN_VEXT_VX(vmulhu_vx_w, 4, 4) | ||
1221 | +GEN_VEXT_VX(vmulhu_vx_d, 8, 8) | ||
1222 | +GEN_VEXT_VX(vmulhsu_vx_b, 1, 1) | ||
1223 | +GEN_VEXT_VX(vmulhsu_vx_h, 2, 2) | ||
1224 | +GEN_VEXT_VX(vmulhsu_vx_w, 4, 4) | ||
1225 | +GEN_VEXT_VX(vmulhsu_vx_d, 8, 8) | ||
1226 | |||
1227 | /* Vector Integer Divide Instructions */ | ||
1228 | #define DO_DIVU(N, M) (unlikely(M == 0) ? (__typeof(N))(-1) : N / M) | ||
1229 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vrem_vv_b, OP_SSS_B, H1, H1, H1, DO_REM) | ||
1230 | RVVCALL(OPIVV2, vrem_vv_h, OP_SSS_H, H2, H2, H2, DO_REM) | ||
1231 | RVVCALL(OPIVV2, vrem_vv_w, OP_SSS_W, H4, H4, H4, DO_REM) | ||
1232 | RVVCALL(OPIVV2, vrem_vv_d, OP_SSS_D, H8, H8, H8, DO_REM) | ||
1233 | -GEN_VEXT_VV(vdivu_vv_b, 1, 1, clearb) | ||
1234 | -GEN_VEXT_VV(vdivu_vv_h, 2, 2, clearh) | ||
1235 | -GEN_VEXT_VV(vdivu_vv_w, 4, 4, clearl) | ||
1236 | -GEN_VEXT_VV(vdivu_vv_d, 8, 8, clearq) | ||
1237 | -GEN_VEXT_VV(vdiv_vv_b, 1, 1, clearb) | ||
1238 | -GEN_VEXT_VV(vdiv_vv_h, 2, 2, clearh) | ||
1239 | -GEN_VEXT_VV(vdiv_vv_w, 4, 4, clearl) | ||
1240 | -GEN_VEXT_VV(vdiv_vv_d, 8, 8, clearq) | ||
1241 | -GEN_VEXT_VV(vremu_vv_b, 1, 1, clearb) | ||
1242 | -GEN_VEXT_VV(vremu_vv_h, 2, 2, clearh) | ||
1243 | -GEN_VEXT_VV(vremu_vv_w, 4, 4, clearl) | ||
1244 | -GEN_VEXT_VV(vremu_vv_d, 8, 8, clearq) | ||
1245 | -GEN_VEXT_VV(vrem_vv_b, 1, 1, clearb) | ||
1246 | -GEN_VEXT_VV(vrem_vv_h, 2, 2, clearh) | ||
1247 | -GEN_VEXT_VV(vrem_vv_w, 4, 4, clearl) | ||
1248 | -GEN_VEXT_VV(vrem_vv_d, 8, 8, clearq) | ||
1249 | +GEN_VEXT_VV(vdivu_vv_b, 1, 1) | ||
1250 | +GEN_VEXT_VV(vdivu_vv_h, 2, 2) | ||
1251 | +GEN_VEXT_VV(vdivu_vv_w, 4, 4) | ||
1252 | +GEN_VEXT_VV(vdivu_vv_d, 8, 8) | ||
1253 | +GEN_VEXT_VV(vdiv_vv_b, 1, 1) | ||
1254 | +GEN_VEXT_VV(vdiv_vv_h, 2, 2) | ||
1255 | +GEN_VEXT_VV(vdiv_vv_w, 4, 4) | ||
1256 | +GEN_VEXT_VV(vdiv_vv_d, 8, 8) | ||
1257 | +GEN_VEXT_VV(vremu_vv_b, 1, 1) | ||
1258 | +GEN_VEXT_VV(vremu_vv_h, 2, 2) | ||
1259 | +GEN_VEXT_VV(vremu_vv_w, 4, 4) | ||
1260 | +GEN_VEXT_VV(vremu_vv_d, 8, 8) | ||
1261 | +GEN_VEXT_VV(vrem_vv_b, 1, 1) | ||
1262 | +GEN_VEXT_VV(vrem_vv_h, 2, 2) | ||
1263 | +GEN_VEXT_VV(vrem_vv_w, 4, 4) | ||
1264 | +GEN_VEXT_VV(vrem_vv_d, 8, 8) | ||
1265 | |||
1266 | RVVCALL(OPIVX2, vdivu_vx_b, OP_UUU_B, H1, H1, DO_DIVU) | ||
1267 | RVVCALL(OPIVX2, vdivu_vx_h, OP_UUU_H, H2, H2, DO_DIVU) | ||
1268 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrem_vx_b, OP_SSS_B, H1, H1, DO_REM) | ||
1269 | RVVCALL(OPIVX2, vrem_vx_h, OP_SSS_H, H2, H2, DO_REM) | ||
1270 | RVVCALL(OPIVX2, vrem_vx_w, OP_SSS_W, H4, H4, DO_REM) | ||
1271 | RVVCALL(OPIVX2, vrem_vx_d, OP_SSS_D, H8, H8, DO_REM) | ||
1272 | -GEN_VEXT_VX(vdivu_vx_b, 1, 1, clearb) | ||
1273 | -GEN_VEXT_VX(vdivu_vx_h, 2, 2, clearh) | ||
1274 | -GEN_VEXT_VX(vdivu_vx_w, 4, 4, clearl) | ||
1275 | -GEN_VEXT_VX(vdivu_vx_d, 8, 8, clearq) | ||
1276 | -GEN_VEXT_VX(vdiv_vx_b, 1, 1, clearb) | ||
1277 | -GEN_VEXT_VX(vdiv_vx_h, 2, 2, clearh) | ||
1278 | -GEN_VEXT_VX(vdiv_vx_w, 4, 4, clearl) | ||
1279 | -GEN_VEXT_VX(vdiv_vx_d, 8, 8, clearq) | ||
1280 | -GEN_VEXT_VX(vremu_vx_b, 1, 1, clearb) | ||
1281 | -GEN_VEXT_VX(vremu_vx_h, 2, 2, clearh) | ||
1282 | -GEN_VEXT_VX(vremu_vx_w, 4, 4, clearl) | ||
1283 | -GEN_VEXT_VX(vremu_vx_d, 8, 8, clearq) | ||
1284 | -GEN_VEXT_VX(vrem_vx_b, 1, 1, clearb) | ||
1285 | -GEN_VEXT_VX(vrem_vx_h, 2, 2, clearh) | ||
1286 | -GEN_VEXT_VX(vrem_vx_w, 4, 4, clearl) | ||
1287 | -GEN_VEXT_VX(vrem_vx_d, 8, 8, clearq) | ||
1288 | +GEN_VEXT_VX(vdivu_vx_b, 1, 1) | ||
1289 | +GEN_VEXT_VX(vdivu_vx_h, 2, 2) | ||
1290 | +GEN_VEXT_VX(vdivu_vx_w, 4, 4) | ||
1291 | +GEN_VEXT_VX(vdivu_vx_d, 8, 8) | ||
1292 | +GEN_VEXT_VX(vdiv_vx_b, 1, 1) | ||
1293 | +GEN_VEXT_VX(vdiv_vx_h, 2, 2) | ||
1294 | +GEN_VEXT_VX(vdiv_vx_w, 4, 4) | ||
1295 | +GEN_VEXT_VX(vdiv_vx_d, 8, 8) | ||
1296 | +GEN_VEXT_VX(vremu_vx_b, 1, 1) | ||
1297 | +GEN_VEXT_VX(vremu_vx_h, 2, 2) | ||
1298 | +GEN_VEXT_VX(vremu_vx_w, 4, 4) | ||
1299 | +GEN_VEXT_VX(vremu_vx_d, 8, 8) | ||
1300 | +GEN_VEXT_VX(vrem_vx_b, 1, 1) | ||
1301 | +GEN_VEXT_VX(vrem_vx_h, 2, 2) | ||
1302 | +GEN_VEXT_VX(vrem_vx_w, 4, 4) | ||
1303 | +GEN_VEXT_VX(vrem_vx_d, 8, 8) | ||
1304 | |||
1305 | /* Vector Widening Integer Multiply Instructions */ | ||
1306 | RVVCALL(OPIVV2, vwmul_vv_b, WOP_SSS_B, H2, H1, H1, DO_MUL) | ||
1307 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vwmulu_vv_w, WOP_UUU_W, H8, H4, H4, DO_MUL) | ||
1308 | RVVCALL(OPIVV2, vwmulsu_vv_b, WOP_SUS_B, H2, H1, H1, DO_MUL) | ||
1309 | RVVCALL(OPIVV2, vwmulsu_vv_h, WOP_SUS_H, H4, H2, H2, DO_MUL) | ||
1310 | RVVCALL(OPIVV2, vwmulsu_vv_w, WOP_SUS_W, H8, H4, H4, DO_MUL) | ||
1311 | -GEN_VEXT_VV(vwmul_vv_b, 1, 2, clearh) | ||
1312 | -GEN_VEXT_VV(vwmul_vv_h, 2, 4, clearl) | ||
1313 | -GEN_VEXT_VV(vwmul_vv_w, 4, 8, clearq) | ||
1314 | -GEN_VEXT_VV(vwmulu_vv_b, 1, 2, clearh) | ||
1315 | -GEN_VEXT_VV(vwmulu_vv_h, 2, 4, clearl) | ||
1316 | -GEN_VEXT_VV(vwmulu_vv_w, 4, 8, clearq) | ||
1317 | -GEN_VEXT_VV(vwmulsu_vv_b, 1, 2, clearh) | ||
1318 | -GEN_VEXT_VV(vwmulsu_vv_h, 2, 4, clearl) | ||
1319 | -GEN_VEXT_VV(vwmulsu_vv_w, 4, 8, clearq) | ||
1320 | +GEN_VEXT_VV(vwmul_vv_b, 1, 2) | ||
1321 | +GEN_VEXT_VV(vwmul_vv_h, 2, 4) | ||
1322 | +GEN_VEXT_VV(vwmul_vv_w, 4, 8) | ||
1323 | +GEN_VEXT_VV(vwmulu_vv_b, 1, 2) | ||
1324 | +GEN_VEXT_VV(vwmulu_vv_h, 2, 4) | ||
1325 | +GEN_VEXT_VV(vwmulu_vv_w, 4, 8) | ||
1326 | +GEN_VEXT_VV(vwmulsu_vv_b, 1, 2) | ||
1327 | +GEN_VEXT_VV(vwmulsu_vv_h, 2, 4) | ||
1328 | +GEN_VEXT_VV(vwmulsu_vv_w, 4, 8) | ||
1329 | |||
1330 | RVVCALL(OPIVX2, vwmul_vx_b, WOP_SSS_B, H2, H1, DO_MUL) | ||
1331 | RVVCALL(OPIVX2, vwmul_vx_h, WOP_SSS_H, H4, H2, DO_MUL) | ||
1332 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwmulu_vx_w, WOP_UUU_W, H8, H4, DO_MUL) | ||
1333 | RVVCALL(OPIVX2, vwmulsu_vx_b, WOP_SUS_B, H2, H1, DO_MUL) | ||
1334 | RVVCALL(OPIVX2, vwmulsu_vx_h, WOP_SUS_H, H4, H2, DO_MUL) | ||
1335 | RVVCALL(OPIVX2, vwmulsu_vx_w, WOP_SUS_W, H8, H4, DO_MUL) | ||
1336 | -GEN_VEXT_VX(vwmul_vx_b, 1, 2, clearh) | ||
1337 | -GEN_VEXT_VX(vwmul_vx_h, 2, 4, clearl) | ||
1338 | -GEN_VEXT_VX(vwmul_vx_w, 4, 8, clearq) | ||
1339 | -GEN_VEXT_VX(vwmulu_vx_b, 1, 2, clearh) | ||
1340 | -GEN_VEXT_VX(vwmulu_vx_h, 2, 4, clearl) | ||
1341 | -GEN_VEXT_VX(vwmulu_vx_w, 4, 8, clearq) | ||
1342 | -GEN_VEXT_VX(vwmulsu_vx_b, 1, 2, clearh) | ||
1343 | -GEN_VEXT_VX(vwmulsu_vx_h, 2, 4, clearl) | ||
1344 | -GEN_VEXT_VX(vwmulsu_vx_w, 4, 8, clearq) | ||
1345 | +GEN_VEXT_VX(vwmul_vx_b, 1, 2) | ||
1346 | +GEN_VEXT_VX(vwmul_vx_h, 2, 4) | ||
1347 | +GEN_VEXT_VX(vwmul_vx_w, 4, 8) | ||
1348 | +GEN_VEXT_VX(vwmulu_vx_b, 1, 2) | ||
1349 | +GEN_VEXT_VX(vwmulu_vx_h, 2, 4) | ||
1350 | +GEN_VEXT_VX(vwmulu_vx_w, 4, 8) | ||
1351 | +GEN_VEXT_VX(vwmulsu_vx_b, 1, 2) | ||
1352 | +GEN_VEXT_VX(vwmulsu_vx_h, 2, 4) | ||
1353 | +GEN_VEXT_VX(vwmulsu_vx_w, 4, 8) | ||
1354 | |||
1355 | /* Vector Single-Width Integer Multiply-Add Instructions */ | ||
1356 | #define OPIVV3(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ | ||
1357 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV3, vnmsub_vv_b, OP_SSS_B, H1, H1, H1, DO_NMSUB) | ||
1358 | RVVCALL(OPIVV3, vnmsub_vv_h, OP_SSS_H, H2, H2, H2, DO_NMSUB) | ||
1359 | RVVCALL(OPIVV3, vnmsub_vv_w, OP_SSS_W, H4, H4, H4, DO_NMSUB) | ||
1360 | RVVCALL(OPIVV3, vnmsub_vv_d, OP_SSS_D, H8, H8, H8, DO_NMSUB) | ||
1361 | -GEN_VEXT_VV(vmacc_vv_b, 1, 1, clearb) | ||
1362 | -GEN_VEXT_VV(vmacc_vv_h, 2, 2, clearh) | ||
1363 | -GEN_VEXT_VV(vmacc_vv_w, 4, 4, clearl) | ||
1364 | -GEN_VEXT_VV(vmacc_vv_d, 8, 8, clearq) | ||
1365 | -GEN_VEXT_VV(vnmsac_vv_b, 1, 1, clearb) | ||
1366 | -GEN_VEXT_VV(vnmsac_vv_h, 2, 2, clearh) | ||
1367 | -GEN_VEXT_VV(vnmsac_vv_w, 4, 4, clearl) | ||
1368 | -GEN_VEXT_VV(vnmsac_vv_d, 8, 8, clearq) | ||
1369 | -GEN_VEXT_VV(vmadd_vv_b, 1, 1, clearb) | ||
1370 | -GEN_VEXT_VV(vmadd_vv_h, 2, 2, clearh) | ||
1371 | -GEN_VEXT_VV(vmadd_vv_w, 4, 4, clearl) | ||
1372 | -GEN_VEXT_VV(vmadd_vv_d, 8, 8, clearq) | ||
1373 | -GEN_VEXT_VV(vnmsub_vv_b, 1, 1, clearb) | ||
1374 | -GEN_VEXT_VV(vnmsub_vv_h, 2, 2, clearh) | ||
1375 | -GEN_VEXT_VV(vnmsub_vv_w, 4, 4, clearl) | ||
1376 | -GEN_VEXT_VV(vnmsub_vv_d, 8, 8, clearq) | ||
1377 | +GEN_VEXT_VV(vmacc_vv_b, 1, 1) | ||
1378 | +GEN_VEXT_VV(vmacc_vv_h, 2, 2) | ||
1379 | +GEN_VEXT_VV(vmacc_vv_w, 4, 4) | ||
1380 | +GEN_VEXT_VV(vmacc_vv_d, 8, 8) | ||
1381 | +GEN_VEXT_VV(vnmsac_vv_b, 1, 1) | ||
1382 | +GEN_VEXT_VV(vnmsac_vv_h, 2, 2) | ||
1383 | +GEN_VEXT_VV(vnmsac_vv_w, 4, 4) | ||
1384 | +GEN_VEXT_VV(vnmsac_vv_d, 8, 8) | ||
1385 | +GEN_VEXT_VV(vmadd_vv_b, 1, 1) | ||
1386 | +GEN_VEXT_VV(vmadd_vv_h, 2, 2) | ||
1387 | +GEN_VEXT_VV(vmadd_vv_w, 4, 4) | ||
1388 | +GEN_VEXT_VV(vmadd_vv_d, 8, 8) | ||
1389 | +GEN_VEXT_VV(vnmsub_vv_b, 1, 1) | ||
1390 | +GEN_VEXT_VV(vnmsub_vv_h, 2, 2) | ||
1391 | +GEN_VEXT_VV(vnmsub_vv_w, 4, 4) | ||
1392 | +GEN_VEXT_VV(vnmsub_vv_d, 8, 8) | ||
1393 | |||
1394 | #define OPIVX3(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
1395 | static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \ | ||
1396 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX3, vnmsub_vx_b, OP_SSS_B, H1, H1, DO_NMSUB) | ||
1397 | RVVCALL(OPIVX3, vnmsub_vx_h, OP_SSS_H, H2, H2, DO_NMSUB) | ||
1398 | RVVCALL(OPIVX3, vnmsub_vx_w, OP_SSS_W, H4, H4, DO_NMSUB) | ||
1399 | RVVCALL(OPIVX3, vnmsub_vx_d, OP_SSS_D, H8, H8, DO_NMSUB) | ||
1400 | -GEN_VEXT_VX(vmacc_vx_b, 1, 1, clearb) | ||
1401 | -GEN_VEXT_VX(vmacc_vx_h, 2, 2, clearh) | ||
1402 | -GEN_VEXT_VX(vmacc_vx_w, 4, 4, clearl) | ||
1403 | -GEN_VEXT_VX(vmacc_vx_d, 8, 8, clearq) | ||
1404 | -GEN_VEXT_VX(vnmsac_vx_b, 1, 1, clearb) | ||
1405 | -GEN_VEXT_VX(vnmsac_vx_h, 2, 2, clearh) | ||
1406 | -GEN_VEXT_VX(vnmsac_vx_w, 4, 4, clearl) | ||
1407 | -GEN_VEXT_VX(vnmsac_vx_d, 8, 8, clearq) | ||
1408 | -GEN_VEXT_VX(vmadd_vx_b, 1, 1, clearb) | ||
1409 | -GEN_VEXT_VX(vmadd_vx_h, 2, 2, clearh) | ||
1410 | -GEN_VEXT_VX(vmadd_vx_w, 4, 4, clearl) | ||
1411 | -GEN_VEXT_VX(vmadd_vx_d, 8, 8, clearq) | ||
1412 | -GEN_VEXT_VX(vnmsub_vx_b, 1, 1, clearb) | ||
1413 | -GEN_VEXT_VX(vnmsub_vx_h, 2, 2, clearh) | ||
1414 | -GEN_VEXT_VX(vnmsub_vx_w, 4, 4, clearl) | ||
1415 | -GEN_VEXT_VX(vnmsub_vx_d, 8, 8, clearq) | ||
1416 | +GEN_VEXT_VX(vmacc_vx_b, 1, 1) | ||
1417 | +GEN_VEXT_VX(vmacc_vx_h, 2, 2) | ||
1418 | +GEN_VEXT_VX(vmacc_vx_w, 4, 4) | ||
1419 | +GEN_VEXT_VX(vmacc_vx_d, 8, 8) | ||
1420 | +GEN_VEXT_VX(vnmsac_vx_b, 1, 1) | ||
1421 | +GEN_VEXT_VX(vnmsac_vx_h, 2, 2) | ||
1422 | +GEN_VEXT_VX(vnmsac_vx_w, 4, 4) | ||
1423 | +GEN_VEXT_VX(vnmsac_vx_d, 8, 8) | ||
1424 | +GEN_VEXT_VX(vmadd_vx_b, 1, 1) | ||
1425 | +GEN_VEXT_VX(vmadd_vx_h, 2, 2) | ||
1426 | +GEN_VEXT_VX(vmadd_vx_w, 4, 4) | ||
1427 | +GEN_VEXT_VX(vmadd_vx_d, 8, 8) | ||
1428 | +GEN_VEXT_VX(vnmsub_vx_b, 1, 1) | ||
1429 | +GEN_VEXT_VX(vnmsub_vx_h, 2, 2) | ||
1430 | +GEN_VEXT_VX(vnmsub_vx_w, 4, 4) | ||
1431 | +GEN_VEXT_VX(vnmsub_vx_d, 8, 8) | ||
1432 | |||
1433 | /* Vector Widening Integer Multiply-Add Instructions */ | ||
1434 | RVVCALL(OPIVV3, vwmaccu_vv_b, WOP_UUU_B, H2, H1, H1, DO_MACC) | ||
1435 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV3, vwmacc_vv_w, WOP_SSS_W, H8, H4, H4, DO_MACC) | ||
1436 | RVVCALL(OPIVV3, vwmaccsu_vv_b, WOP_SSU_B, H2, H1, H1, DO_MACC) | ||
1437 | RVVCALL(OPIVV3, vwmaccsu_vv_h, WOP_SSU_H, H4, H2, H2, DO_MACC) | ||
1438 | RVVCALL(OPIVV3, vwmaccsu_vv_w, WOP_SSU_W, H8, H4, H4, DO_MACC) | ||
1439 | -GEN_VEXT_VV(vwmaccu_vv_b, 1, 2, clearh) | ||
1440 | -GEN_VEXT_VV(vwmaccu_vv_h, 2, 4, clearl) | ||
1441 | -GEN_VEXT_VV(vwmaccu_vv_w, 4, 8, clearq) | ||
1442 | -GEN_VEXT_VV(vwmacc_vv_b, 1, 2, clearh) | ||
1443 | -GEN_VEXT_VV(vwmacc_vv_h, 2, 4, clearl) | ||
1444 | -GEN_VEXT_VV(vwmacc_vv_w, 4, 8, clearq) | ||
1445 | -GEN_VEXT_VV(vwmaccsu_vv_b, 1, 2, clearh) | ||
1446 | -GEN_VEXT_VV(vwmaccsu_vv_h, 2, 4, clearl) | ||
1447 | -GEN_VEXT_VV(vwmaccsu_vv_w, 4, 8, clearq) | ||
1448 | +GEN_VEXT_VV(vwmaccu_vv_b, 1, 2) | ||
1449 | +GEN_VEXT_VV(vwmaccu_vv_h, 2, 4) | ||
1450 | +GEN_VEXT_VV(vwmaccu_vv_w, 4, 8) | ||
1451 | +GEN_VEXT_VV(vwmacc_vv_b, 1, 2) | ||
1452 | +GEN_VEXT_VV(vwmacc_vv_h, 2, 4) | ||
1453 | +GEN_VEXT_VV(vwmacc_vv_w, 4, 8) | ||
1454 | +GEN_VEXT_VV(vwmaccsu_vv_b, 1, 2) | ||
1455 | +GEN_VEXT_VV(vwmaccsu_vv_h, 2, 4) | ||
1456 | +GEN_VEXT_VV(vwmaccsu_vv_w, 4, 8) | ||
1457 | |||
1458 | RVVCALL(OPIVX3, vwmaccu_vx_b, WOP_UUU_B, H2, H1, DO_MACC) | ||
1459 | RVVCALL(OPIVX3, vwmaccu_vx_h, WOP_UUU_H, H4, H2, DO_MACC) | ||
1460 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX3, vwmaccsu_vx_w, WOP_SSU_W, H8, H4, DO_MACC) | ||
1461 | RVVCALL(OPIVX3, vwmaccus_vx_b, WOP_SUS_B, H2, H1, DO_MACC) | ||
1462 | RVVCALL(OPIVX3, vwmaccus_vx_h, WOP_SUS_H, H4, H2, DO_MACC) | ||
1463 | RVVCALL(OPIVX3, vwmaccus_vx_w, WOP_SUS_W, H8, H4, DO_MACC) | ||
1464 | -GEN_VEXT_VX(vwmaccu_vx_b, 1, 2, clearh) | ||
1465 | -GEN_VEXT_VX(vwmaccu_vx_h, 2, 4, clearl) | ||
1466 | -GEN_VEXT_VX(vwmaccu_vx_w, 4, 8, clearq) | ||
1467 | -GEN_VEXT_VX(vwmacc_vx_b, 1, 2, clearh) | ||
1468 | -GEN_VEXT_VX(vwmacc_vx_h, 2, 4, clearl) | ||
1469 | -GEN_VEXT_VX(vwmacc_vx_w, 4, 8, clearq) | ||
1470 | -GEN_VEXT_VX(vwmaccsu_vx_b, 1, 2, clearh) | ||
1471 | -GEN_VEXT_VX(vwmaccsu_vx_h, 2, 4, clearl) | ||
1472 | -GEN_VEXT_VX(vwmaccsu_vx_w, 4, 8, clearq) | ||
1473 | -GEN_VEXT_VX(vwmaccus_vx_b, 1, 2, clearh) | ||
1474 | -GEN_VEXT_VX(vwmaccus_vx_h, 2, 4, clearl) | ||
1475 | -GEN_VEXT_VX(vwmaccus_vx_w, 4, 8, clearq) | ||
1476 | +GEN_VEXT_VX(vwmaccu_vx_b, 1, 2) | ||
1477 | +GEN_VEXT_VX(vwmaccu_vx_h, 2, 4) | ||
1478 | +GEN_VEXT_VX(vwmaccu_vx_w, 4, 8) | ||
1479 | +GEN_VEXT_VX(vwmacc_vx_b, 1, 2) | ||
1480 | +GEN_VEXT_VX(vwmacc_vx_h, 2, 4) | ||
1481 | +GEN_VEXT_VX(vwmacc_vx_w, 4, 8) | ||
1482 | +GEN_VEXT_VX(vwmaccsu_vx_b, 1, 2) | ||
1483 | +GEN_VEXT_VX(vwmaccsu_vx_h, 2, 4) | ||
1484 | +GEN_VEXT_VX(vwmaccsu_vx_w, 4, 8) | ||
1485 | +GEN_VEXT_VX(vwmaccus_vx_b, 1, 2) | ||
1486 | +GEN_VEXT_VX(vwmaccus_vx_h, 2, 4) | ||
1487 | +GEN_VEXT_VX(vwmaccus_vx_w, 4, 8) | ||
1488 | |||
1489 | /* Vector Integer Merge and Move Instructions */ | ||
1490 | -#define GEN_VEXT_VMV_VV(NAME, ETYPE, H, CLEAR_FN) \ | ||
1491 | +#define GEN_VEXT_VMV_VV(NAME, ETYPE, H) \ | ||
1492 | void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env, \ | ||
1493 | uint32_t desc) \ | ||
1494 | { \ | ||
1495 | uint32_t vl = env->vl; \ | ||
1496 | - uint32_t esz = sizeof(ETYPE); \ | ||
1497 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
1498 | uint32_t i; \ | ||
1499 | \ | ||
1500 | for (i = 0; i < vl; i++) { \ | ||
1501 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
1502 | *((ETYPE *)vd + H(i)) = s1; \ | ||
1503 | } \ | ||
1504 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
1505 | } | ||
1506 | |||
1507 | -GEN_VEXT_VMV_VV(vmv_v_v_b, int8_t, H1, clearb) | ||
1508 | -GEN_VEXT_VMV_VV(vmv_v_v_h, int16_t, H2, clearh) | ||
1509 | -GEN_VEXT_VMV_VV(vmv_v_v_w, int32_t, H4, clearl) | ||
1510 | -GEN_VEXT_VMV_VV(vmv_v_v_d, int64_t, H8, clearq) | ||
1511 | +GEN_VEXT_VMV_VV(vmv_v_v_b, int8_t, H1) | ||
1512 | +GEN_VEXT_VMV_VV(vmv_v_v_h, int16_t, H2) | ||
1513 | +GEN_VEXT_VMV_VV(vmv_v_v_w, int32_t, H4) | ||
1514 | +GEN_VEXT_VMV_VV(vmv_v_v_d, int64_t, H8) | ||
1515 | |||
1516 | -#define GEN_VEXT_VMV_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
1517 | +#define GEN_VEXT_VMV_VX(NAME, ETYPE, H) \ | ||
1518 | void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env, \ | ||
1519 | uint32_t desc) \ | ||
1520 | { \ | ||
1521 | uint32_t vl = env->vl; \ | ||
1522 | - uint32_t esz = sizeof(ETYPE); \ | ||
1523 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
1524 | uint32_t i; \ | ||
1525 | \ | ||
1526 | for (i = 0; i < vl; i++) { \ | ||
1527 | *((ETYPE *)vd + H(i)) = (ETYPE)s1; \ | ||
1528 | } \ | ||
1529 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
1530 | } | ||
1531 | |||
1532 | -GEN_VEXT_VMV_VX(vmv_v_x_b, int8_t, H1, clearb) | ||
1533 | -GEN_VEXT_VMV_VX(vmv_v_x_h, int16_t, H2, clearh) | ||
1534 | -GEN_VEXT_VMV_VX(vmv_v_x_w, int32_t, H4, clearl) | ||
1535 | -GEN_VEXT_VMV_VX(vmv_v_x_d, int64_t, H8, clearq) | ||
1536 | +GEN_VEXT_VMV_VX(vmv_v_x_b, int8_t, H1) | ||
1537 | +GEN_VEXT_VMV_VX(vmv_v_x_h, int16_t, H2) | ||
1538 | +GEN_VEXT_VMV_VX(vmv_v_x_w, int32_t, H4) | ||
1539 | +GEN_VEXT_VMV_VX(vmv_v_x_d, int64_t, H8) | ||
1540 | |||
1541 | -#define GEN_VEXT_VMERGE_VV(NAME, ETYPE, H, CLEAR_FN) \ | ||
1542 | +#define GEN_VEXT_VMERGE_VV(NAME, ETYPE, H) \ | ||
1543 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
1544 | CPURISCVState *env, uint32_t desc) \ | ||
1545 | { \ | ||
1546 | uint32_t vl = env->vl; \ | ||
1547 | - uint32_t esz = sizeof(ETYPE); \ | ||
1548 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
1549 | uint32_t i; \ | ||
1550 | \ | ||
1551 | for (i = 0; i < vl; i++) { \ | ||
1552 | ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \ | ||
1553 | *((ETYPE *)vd + H(i)) = *(vt + H(i)); \ | ||
1554 | } \ | ||
1555 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
1556 | } | ||
1557 | |||
1558 | -GEN_VEXT_VMERGE_VV(vmerge_vvm_b, int8_t, H1, clearb) | ||
1559 | -GEN_VEXT_VMERGE_VV(vmerge_vvm_h, int16_t, H2, clearh) | ||
1560 | -GEN_VEXT_VMERGE_VV(vmerge_vvm_w, int32_t, H4, clearl) | ||
1561 | -GEN_VEXT_VMERGE_VV(vmerge_vvm_d, int64_t, H8, clearq) | ||
1562 | +GEN_VEXT_VMERGE_VV(vmerge_vvm_b, int8_t, H1) | ||
1563 | +GEN_VEXT_VMERGE_VV(vmerge_vvm_h, int16_t, H2) | ||
1564 | +GEN_VEXT_VMERGE_VV(vmerge_vvm_w, int32_t, H4) | ||
1565 | +GEN_VEXT_VMERGE_VV(vmerge_vvm_d, int64_t, H8) | ||
1566 | |||
1567 | -#define GEN_VEXT_VMERGE_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
1568 | +#define GEN_VEXT_VMERGE_VX(NAME, ETYPE, H) \ | ||
1569 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
1570 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
1571 | { \ | ||
1572 | uint32_t vl = env->vl; \ | ||
1573 | - uint32_t esz = sizeof(ETYPE); \ | ||
1574 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
1575 | uint32_t i; \ | ||
1576 | \ | ||
1577 | for (i = 0; i < vl; i++) { \ | ||
1578 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
1579 | (ETYPE)(target_long)s1); \ | ||
1580 | *((ETYPE *)vd + H(i)) = d; \ | ||
1581 | } \ | ||
1582 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
1583 | } | ||
1584 | |||
1585 | -GEN_VEXT_VMERGE_VX(vmerge_vxm_b, int8_t, H1, clearb) | ||
1586 | -GEN_VEXT_VMERGE_VX(vmerge_vxm_h, int16_t, H2, clearh) | ||
1587 | -GEN_VEXT_VMERGE_VX(vmerge_vxm_w, int32_t, H4, clearl) | ||
1588 | -GEN_VEXT_VMERGE_VX(vmerge_vxm_d, int64_t, H8, clearq) | ||
1589 | +GEN_VEXT_VMERGE_VX(vmerge_vxm_b, int8_t, H1) | ||
1590 | +GEN_VEXT_VMERGE_VX(vmerge_vxm_h, int16_t, H2) | ||
1591 | +GEN_VEXT_VMERGE_VX(vmerge_vxm_w, int32_t, H4) | ||
1592 | +GEN_VEXT_VMERGE_VX(vmerge_vxm_d, int64_t, H8) | ||
1593 | |||
1594 | /* | ||
1595 | *** Vector Fixed-Point Arithmetic Instructions | ||
1596 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
1597 | vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2, | ||
1598 | CPURISCVState *env, | ||
1599 | uint32_t desc, uint32_t esz, uint32_t dsz, | ||
1600 | - opivv2_rm_fn *fn, clear_fn *clearfn) | ||
1601 | + opivv2_rm_fn *fn) | ||
1602 | { | ||
1603 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
1604 | uint32_t vm = vext_vm(desc); | ||
1605 | uint32_t vl = env->vl; | ||
1606 | |||
1607 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2, | ||
1608 | env, vl, vm, 3, fn); | ||
1609 | break; | ||
1610 | } | ||
1611 | - | ||
1612 | - clearfn(vd, vl, vl * dsz, vlmax * dsz); | ||
1613 | } | ||
1614 | |||
1615 | /* generate helpers for fixed point instructions with OPIVV format */ | ||
1616 | -#define GEN_VEXT_VV_RM(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
1617 | +#define GEN_VEXT_VV_RM(NAME, ESZ, DSZ) \ | ||
1618 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
1619 | CPURISCVState *env, uint32_t desc) \ | ||
1620 | { \ | ||
1621 | vext_vv_rm_2(vd, v0, vs1, vs2, env, desc, ESZ, DSZ, \ | ||
1622 | - do_##NAME, CLEAR_FN); \ | ||
1623 | + do_##NAME); \ | ||
1624 | } | ||
1625 | |||
1626 | static inline uint8_t saddu8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b) | ||
1627 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vsaddu_vv_b, OP_UUU_B, H1, H1, H1, saddu8) | ||
1628 | RVVCALL(OPIVV2_RM, vsaddu_vv_h, OP_UUU_H, H2, H2, H2, saddu16) | ||
1629 | RVVCALL(OPIVV2_RM, vsaddu_vv_w, OP_UUU_W, H4, H4, H4, saddu32) | ||
1630 | RVVCALL(OPIVV2_RM, vsaddu_vv_d, OP_UUU_D, H8, H8, H8, saddu64) | ||
1631 | -GEN_VEXT_VV_RM(vsaddu_vv_b, 1, 1, clearb) | ||
1632 | -GEN_VEXT_VV_RM(vsaddu_vv_h, 2, 2, clearh) | ||
1633 | -GEN_VEXT_VV_RM(vsaddu_vv_w, 4, 4, clearl) | ||
1634 | -GEN_VEXT_VV_RM(vsaddu_vv_d, 8, 8, clearq) | ||
1635 | +GEN_VEXT_VV_RM(vsaddu_vv_b, 1, 1) | ||
1636 | +GEN_VEXT_VV_RM(vsaddu_vv_h, 2, 2) | ||
1637 | +GEN_VEXT_VV_RM(vsaddu_vv_w, 4, 4) | ||
1638 | +GEN_VEXT_VV_RM(vsaddu_vv_d, 8, 8) | ||
1639 | |||
1640 | typedef void opivx2_rm_fn(void *vd, target_long s1, void *vs2, int i, | ||
1641 | CPURISCVState *env, int vxrm); | ||
1642 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
1643 | vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, | ||
1644 | CPURISCVState *env, | ||
1645 | uint32_t desc, uint32_t esz, uint32_t dsz, | ||
1646 | - opivx2_rm_fn *fn, clear_fn *clearfn) | ||
1647 | + opivx2_rm_fn *fn) | ||
1648 | { | ||
1649 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
1650 | uint32_t vm = vext_vm(desc); | ||
1651 | uint32_t vl = env->vl; | ||
1652 | |||
1653 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, | ||
1654 | env, vl, vm, 3, fn); | ||
1655 | break; | ||
1656 | } | ||
1657 | - | ||
1658 | - clearfn(vd, vl, vl * dsz, vlmax * dsz); | ||
1659 | } | ||
1660 | |||
1661 | /* generate helpers for fixed point instructions with OPIVX format */ | ||
1662 | -#define GEN_VEXT_VX_RM(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
1663 | +#define GEN_VEXT_VX_RM(NAME, ESZ, DSZ) \ | ||
1664 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
1665 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
1666 | { \ | ||
1667 | vext_vx_rm_2(vd, v0, s1, vs2, env, desc, ESZ, DSZ, \ | ||
1668 | - do_##NAME, CLEAR_FN); \ | ||
1669 | + do_##NAME); \ | ||
1670 | } | ||
1671 | |||
1672 | RVVCALL(OPIVX2_RM, vsaddu_vx_b, OP_UUU_B, H1, H1, saddu8) | ||
1673 | RVVCALL(OPIVX2_RM, vsaddu_vx_h, OP_UUU_H, H2, H2, saddu16) | ||
1674 | RVVCALL(OPIVX2_RM, vsaddu_vx_w, OP_UUU_W, H4, H4, saddu32) | ||
1675 | RVVCALL(OPIVX2_RM, vsaddu_vx_d, OP_UUU_D, H8, H8, saddu64) | ||
1676 | -GEN_VEXT_VX_RM(vsaddu_vx_b, 1, 1, clearb) | ||
1677 | -GEN_VEXT_VX_RM(vsaddu_vx_h, 2, 2, clearh) | ||
1678 | -GEN_VEXT_VX_RM(vsaddu_vx_w, 4, 4, clearl) | ||
1679 | -GEN_VEXT_VX_RM(vsaddu_vx_d, 8, 8, clearq) | ||
1680 | +GEN_VEXT_VX_RM(vsaddu_vx_b, 1, 1) | ||
1681 | +GEN_VEXT_VX_RM(vsaddu_vx_h, 2, 2) | ||
1682 | +GEN_VEXT_VX_RM(vsaddu_vx_w, 4, 4) | ||
1683 | +GEN_VEXT_VX_RM(vsaddu_vx_d, 8, 8) | ||
1684 | |||
1685 | static inline int8_t sadd8(CPURISCVState *env, int vxrm, int8_t a, int8_t b) | ||
1686 | { | ||
1687 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vsadd_vv_b, OP_SSS_B, H1, H1, H1, sadd8) | ||
1688 | RVVCALL(OPIVV2_RM, vsadd_vv_h, OP_SSS_H, H2, H2, H2, sadd16) | ||
1689 | RVVCALL(OPIVV2_RM, vsadd_vv_w, OP_SSS_W, H4, H4, H4, sadd32) | ||
1690 | RVVCALL(OPIVV2_RM, vsadd_vv_d, OP_SSS_D, H8, H8, H8, sadd64) | ||
1691 | -GEN_VEXT_VV_RM(vsadd_vv_b, 1, 1, clearb) | ||
1692 | -GEN_VEXT_VV_RM(vsadd_vv_h, 2, 2, clearh) | ||
1693 | -GEN_VEXT_VV_RM(vsadd_vv_w, 4, 4, clearl) | ||
1694 | -GEN_VEXT_VV_RM(vsadd_vv_d, 8, 8, clearq) | ||
1695 | +GEN_VEXT_VV_RM(vsadd_vv_b, 1, 1) | ||
1696 | +GEN_VEXT_VV_RM(vsadd_vv_h, 2, 2) | ||
1697 | +GEN_VEXT_VV_RM(vsadd_vv_w, 4, 4) | ||
1698 | +GEN_VEXT_VV_RM(vsadd_vv_d, 8, 8) | ||
1699 | |||
1700 | RVVCALL(OPIVX2_RM, vsadd_vx_b, OP_SSS_B, H1, H1, sadd8) | ||
1701 | RVVCALL(OPIVX2_RM, vsadd_vx_h, OP_SSS_H, H2, H2, sadd16) | ||
1702 | RVVCALL(OPIVX2_RM, vsadd_vx_w, OP_SSS_W, H4, H4, sadd32) | ||
1703 | RVVCALL(OPIVX2_RM, vsadd_vx_d, OP_SSS_D, H8, H8, sadd64) | ||
1704 | -GEN_VEXT_VX_RM(vsadd_vx_b, 1, 1, clearb) | ||
1705 | -GEN_VEXT_VX_RM(vsadd_vx_h, 2, 2, clearh) | ||
1706 | -GEN_VEXT_VX_RM(vsadd_vx_w, 4, 4, clearl) | ||
1707 | -GEN_VEXT_VX_RM(vsadd_vx_d, 8, 8, clearq) | ||
1708 | +GEN_VEXT_VX_RM(vsadd_vx_b, 1, 1) | ||
1709 | +GEN_VEXT_VX_RM(vsadd_vx_h, 2, 2) | ||
1710 | +GEN_VEXT_VX_RM(vsadd_vx_w, 4, 4) | ||
1711 | +GEN_VEXT_VX_RM(vsadd_vx_d, 8, 8) | ||
1712 | |||
1713 | static inline uint8_t ssubu8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b) | ||
1714 | { | ||
1715 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vssubu_vv_b, OP_UUU_B, H1, H1, H1, ssubu8) | ||
1716 | RVVCALL(OPIVV2_RM, vssubu_vv_h, OP_UUU_H, H2, H2, H2, ssubu16) | ||
1717 | RVVCALL(OPIVV2_RM, vssubu_vv_w, OP_UUU_W, H4, H4, H4, ssubu32) | ||
1718 | RVVCALL(OPIVV2_RM, vssubu_vv_d, OP_UUU_D, H8, H8, H8, ssubu64) | ||
1719 | -GEN_VEXT_VV_RM(vssubu_vv_b, 1, 1, clearb) | ||
1720 | -GEN_VEXT_VV_RM(vssubu_vv_h, 2, 2, clearh) | ||
1721 | -GEN_VEXT_VV_RM(vssubu_vv_w, 4, 4, clearl) | ||
1722 | -GEN_VEXT_VV_RM(vssubu_vv_d, 8, 8, clearq) | ||
1723 | +GEN_VEXT_VV_RM(vssubu_vv_b, 1, 1) | ||
1724 | +GEN_VEXT_VV_RM(vssubu_vv_h, 2, 2) | ||
1725 | +GEN_VEXT_VV_RM(vssubu_vv_w, 4, 4) | ||
1726 | +GEN_VEXT_VV_RM(vssubu_vv_d, 8, 8) | ||
1727 | |||
1728 | RVVCALL(OPIVX2_RM, vssubu_vx_b, OP_UUU_B, H1, H1, ssubu8) | ||
1729 | RVVCALL(OPIVX2_RM, vssubu_vx_h, OP_UUU_H, H2, H2, ssubu16) | ||
1730 | RVVCALL(OPIVX2_RM, vssubu_vx_w, OP_UUU_W, H4, H4, ssubu32) | ||
1731 | RVVCALL(OPIVX2_RM, vssubu_vx_d, OP_UUU_D, H8, H8, ssubu64) | ||
1732 | -GEN_VEXT_VX_RM(vssubu_vx_b, 1, 1, clearb) | ||
1733 | -GEN_VEXT_VX_RM(vssubu_vx_h, 2, 2, clearh) | ||
1734 | -GEN_VEXT_VX_RM(vssubu_vx_w, 4, 4, clearl) | ||
1735 | -GEN_VEXT_VX_RM(vssubu_vx_d, 8, 8, clearq) | ||
1736 | +GEN_VEXT_VX_RM(vssubu_vx_b, 1, 1) | ||
1737 | +GEN_VEXT_VX_RM(vssubu_vx_h, 2, 2) | ||
1738 | +GEN_VEXT_VX_RM(vssubu_vx_w, 4, 4) | ||
1739 | +GEN_VEXT_VX_RM(vssubu_vx_d, 8, 8) | ||
1740 | |||
1741 | static inline int8_t ssub8(CPURISCVState *env, int vxrm, int8_t a, int8_t b) | ||
1742 | { | ||
1743 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vssub_vv_b, OP_SSS_B, H1, H1, H1, ssub8) | ||
1744 | RVVCALL(OPIVV2_RM, vssub_vv_h, OP_SSS_H, H2, H2, H2, ssub16) | ||
1745 | RVVCALL(OPIVV2_RM, vssub_vv_w, OP_SSS_W, H4, H4, H4, ssub32) | ||
1746 | RVVCALL(OPIVV2_RM, vssub_vv_d, OP_SSS_D, H8, H8, H8, ssub64) | ||
1747 | -GEN_VEXT_VV_RM(vssub_vv_b, 1, 1, clearb) | ||
1748 | -GEN_VEXT_VV_RM(vssub_vv_h, 2, 2, clearh) | ||
1749 | -GEN_VEXT_VV_RM(vssub_vv_w, 4, 4, clearl) | ||
1750 | -GEN_VEXT_VV_RM(vssub_vv_d, 8, 8, clearq) | ||
1751 | +GEN_VEXT_VV_RM(vssub_vv_b, 1, 1) | ||
1752 | +GEN_VEXT_VV_RM(vssub_vv_h, 2, 2) | ||
1753 | +GEN_VEXT_VV_RM(vssub_vv_w, 4, 4) | ||
1754 | +GEN_VEXT_VV_RM(vssub_vv_d, 8, 8) | ||
1755 | |||
1756 | RVVCALL(OPIVX2_RM, vssub_vx_b, OP_SSS_B, H1, H1, ssub8) | ||
1757 | RVVCALL(OPIVX2_RM, vssub_vx_h, OP_SSS_H, H2, H2, ssub16) | ||
1758 | RVVCALL(OPIVX2_RM, vssub_vx_w, OP_SSS_W, H4, H4, ssub32) | ||
1759 | RVVCALL(OPIVX2_RM, vssub_vx_d, OP_SSS_D, H8, H8, ssub64) | ||
1760 | -GEN_VEXT_VX_RM(vssub_vx_b, 1, 1, clearb) | ||
1761 | -GEN_VEXT_VX_RM(vssub_vx_h, 2, 2, clearh) | ||
1762 | -GEN_VEXT_VX_RM(vssub_vx_w, 4, 4, clearl) | ||
1763 | -GEN_VEXT_VX_RM(vssub_vx_d, 8, 8, clearq) | ||
1764 | +GEN_VEXT_VX_RM(vssub_vx_b, 1, 1) | ||
1765 | +GEN_VEXT_VX_RM(vssub_vx_h, 2, 2) | ||
1766 | +GEN_VEXT_VX_RM(vssub_vx_w, 4, 4) | ||
1767 | +GEN_VEXT_VX_RM(vssub_vx_d, 8, 8) | ||
1768 | |||
1769 | /* Vector Single-Width Averaging Add and Subtract */ | ||
1770 | static inline uint8_t get_round(int vxrm, uint64_t v, uint8_t shift) | ||
1771 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vaadd_vv_b, OP_SSS_B, H1, H1, H1, aadd32) | ||
1772 | RVVCALL(OPIVV2_RM, vaadd_vv_h, OP_SSS_H, H2, H2, H2, aadd32) | ||
1773 | RVVCALL(OPIVV2_RM, vaadd_vv_w, OP_SSS_W, H4, H4, H4, aadd32) | ||
1774 | RVVCALL(OPIVV2_RM, vaadd_vv_d, OP_SSS_D, H8, H8, H8, aadd64) | ||
1775 | -GEN_VEXT_VV_RM(vaadd_vv_b, 1, 1, clearb) | ||
1776 | -GEN_VEXT_VV_RM(vaadd_vv_h, 2, 2, clearh) | ||
1777 | -GEN_VEXT_VV_RM(vaadd_vv_w, 4, 4, clearl) | ||
1778 | -GEN_VEXT_VV_RM(vaadd_vv_d, 8, 8, clearq) | ||
1779 | +GEN_VEXT_VV_RM(vaadd_vv_b, 1, 1) | ||
1780 | +GEN_VEXT_VV_RM(vaadd_vv_h, 2, 2) | ||
1781 | +GEN_VEXT_VV_RM(vaadd_vv_w, 4, 4) | ||
1782 | +GEN_VEXT_VV_RM(vaadd_vv_d, 8, 8) | ||
1783 | |||
1784 | RVVCALL(OPIVX2_RM, vaadd_vx_b, OP_SSS_B, H1, H1, aadd32) | ||
1785 | RVVCALL(OPIVX2_RM, vaadd_vx_h, OP_SSS_H, H2, H2, aadd32) | ||
1786 | RVVCALL(OPIVX2_RM, vaadd_vx_w, OP_SSS_W, H4, H4, aadd32) | ||
1787 | RVVCALL(OPIVX2_RM, vaadd_vx_d, OP_SSS_D, H8, H8, aadd64) | ||
1788 | -GEN_VEXT_VX_RM(vaadd_vx_b, 1, 1, clearb) | ||
1789 | -GEN_VEXT_VX_RM(vaadd_vx_h, 2, 2, clearh) | ||
1790 | -GEN_VEXT_VX_RM(vaadd_vx_w, 4, 4, clearl) | ||
1791 | -GEN_VEXT_VX_RM(vaadd_vx_d, 8, 8, clearq) | ||
1792 | +GEN_VEXT_VX_RM(vaadd_vx_b, 1, 1) | ||
1793 | +GEN_VEXT_VX_RM(vaadd_vx_h, 2, 2) | ||
1794 | +GEN_VEXT_VX_RM(vaadd_vx_w, 4, 4) | ||
1795 | +GEN_VEXT_VX_RM(vaadd_vx_d, 8, 8) | ||
1796 | |||
1797 | static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t b) | ||
1798 | { | ||
1799 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vasub_vv_b, OP_SSS_B, H1, H1, H1, asub32) | ||
1800 | RVVCALL(OPIVV2_RM, vasub_vv_h, OP_SSS_H, H2, H2, H2, asub32) | ||
1801 | RVVCALL(OPIVV2_RM, vasub_vv_w, OP_SSS_W, H4, H4, H4, asub32) | ||
1802 | RVVCALL(OPIVV2_RM, vasub_vv_d, OP_SSS_D, H8, H8, H8, asub64) | ||
1803 | -GEN_VEXT_VV_RM(vasub_vv_b, 1, 1, clearb) | ||
1804 | -GEN_VEXT_VV_RM(vasub_vv_h, 2, 2, clearh) | ||
1805 | -GEN_VEXT_VV_RM(vasub_vv_w, 4, 4, clearl) | ||
1806 | -GEN_VEXT_VV_RM(vasub_vv_d, 8, 8, clearq) | ||
1807 | +GEN_VEXT_VV_RM(vasub_vv_b, 1, 1) | ||
1808 | +GEN_VEXT_VV_RM(vasub_vv_h, 2, 2) | ||
1809 | +GEN_VEXT_VV_RM(vasub_vv_w, 4, 4) | ||
1810 | +GEN_VEXT_VV_RM(vasub_vv_d, 8, 8) | ||
1811 | |||
1812 | RVVCALL(OPIVX2_RM, vasub_vx_b, OP_SSS_B, H1, H1, asub32) | ||
1813 | RVVCALL(OPIVX2_RM, vasub_vx_h, OP_SSS_H, H2, H2, asub32) | ||
1814 | RVVCALL(OPIVX2_RM, vasub_vx_w, OP_SSS_W, H4, H4, asub32) | ||
1815 | RVVCALL(OPIVX2_RM, vasub_vx_d, OP_SSS_D, H8, H8, asub64) | ||
1816 | -GEN_VEXT_VX_RM(vasub_vx_b, 1, 1, clearb) | ||
1817 | -GEN_VEXT_VX_RM(vasub_vx_h, 2, 2, clearh) | ||
1818 | -GEN_VEXT_VX_RM(vasub_vx_w, 4, 4, clearl) | ||
1819 | -GEN_VEXT_VX_RM(vasub_vx_d, 8, 8, clearq) | ||
1820 | +GEN_VEXT_VX_RM(vasub_vx_b, 1, 1) | ||
1821 | +GEN_VEXT_VX_RM(vasub_vx_h, 2, 2) | ||
1822 | +GEN_VEXT_VX_RM(vasub_vx_w, 4, 4) | ||
1823 | +GEN_VEXT_VX_RM(vasub_vx_d, 8, 8) | ||
1824 | |||
1825 | /* Vector Single-Width Fractional Multiply with Rounding and Saturation */ | ||
1826 | static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b) | ||
1827 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vsmul_vv_b, OP_SSS_B, H1, H1, H1, vsmul8) | ||
1828 | RVVCALL(OPIVV2_RM, vsmul_vv_h, OP_SSS_H, H2, H2, H2, vsmul16) | ||
1829 | RVVCALL(OPIVV2_RM, vsmul_vv_w, OP_SSS_W, H4, H4, H4, vsmul32) | ||
1830 | RVVCALL(OPIVV2_RM, vsmul_vv_d, OP_SSS_D, H8, H8, H8, vsmul64) | ||
1831 | -GEN_VEXT_VV_RM(vsmul_vv_b, 1, 1, clearb) | ||
1832 | -GEN_VEXT_VV_RM(vsmul_vv_h, 2, 2, clearh) | ||
1833 | -GEN_VEXT_VV_RM(vsmul_vv_w, 4, 4, clearl) | ||
1834 | -GEN_VEXT_VV_RM(vsmul_vv_d, 8, 8, clearq) | ||
1835 | +GEN_VEXT_VV_RM(vsmul_vv_b, 1, 1) | ||
1836 | +GEN_VEXT_VV_RM(vsmul_vv_h, 2, 2) | ||
1837 | +GEN_VEXT_VV_RM(vsmul_vv_w, 4, 4) | ||
1838 | +GEN_VEXT_VV_RM(vsmul_vv_d, 8, 8) | ||
1839 | |||
1840 | RVVCALL(OPIVX2_RM, vsmul_vx_b, OP_SSS_B, H1, H1, vsmul8) | ||
1841 | RVVCALL(OPIVX2_RM, vsmul_vx_h, OP_SSS_H, H2, H2, vsmul16) | ||
1842 | RVVCALL(OPIVX2_RM, vsmul_vx_w, OP_SSS_W, H4, H4, vsmul32) | ||
1843 | RVVCALL(OPIVX2_RM, vsmul_vx_d, OP_SSS_D, H8, H8, vsmul64) | ||
1844 | -GEN_VEXT_VX_RM(vsmul_vx_b, 1, 1, clearb) | ||
1845 | -GEN_VEXT_VX_RM(vsmul_vx_h, 2, 2, clearh) | ||
1846 | -GEN_VEXT_VX_RM(vsmul_vx_w, 4, 4, clearl) | ||
1847 | -GEN_VEXT_VX_RM(vsmul_vx_d, 8, 8, clearq) | ||
1848 | +GEN_VEXT_VX_RM(vsmul_vx_b, 1, 1) | ||
1849 | +GEN_VEXT_VX_RM(vsmul_vx_h, 2, 2) | ||
1850 | +GEN_VEXT_VX_RM(vsmul_vx_w, 4, 4) | ||
1851 | +GEN_VEXT_VX_RM(vsmul_vx_d, 8, 8) | ||
1852 | |||
1853 | /* Vector Widening Saturating Scaled Multiply-Add */ | ||
1854 | static inline uint16_t | ||
1855 | @@ -XXX,XX +XXX,XX @@ do_##NAME(void *vd, void *vs1, void *vs2, int i, \ | ||
1856 | RVVCALL(OPIVV3_RM, vwsmaccu_vv_b, WOP_UUU_B, H2, H1, H1, vwsmaccu8) | ||
1857 | RVVCALL(OPIVV3_RM, vwsmaccu_vv_h, WOP_UUU_H, H4, H2, H2, vwsmaccu16) | ||
1858 | RVVCALL(OPIVV3_RM, vwsmaccu_vv_w, WOP_UUU_W, H8, H4, H4, vwsmaccu32) | ||
1859 | -GEN_VEXT_VV_RM(vwsmaccu_vv_b, 1, 2, clearh) | ||
1860 | -GEN_VEXT_VV_RM(vwsmaccu_vv_h, 2, 4, clearl) | ||
1861 | -GEN_VEXT_VV_RM(vwsmaccu_vv_w, 4, 8, clearq) | ||
1862 | +GEN_VEXT_VV_RM(vwsmaccu_vv_b, 1, 2) | ||
1863 | +GEN_VEXT_VV_RM(vwsmaccu_vv_h, 2, 4) | ||
1864 | +GEN_VEXT_VV_RM(vwsmaccu_vv_w, 4, 8) | ||
1865 | |||
1866 | #define OPIVX3_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
1867 | static inline void \ | ||
1868 | @@ -XXX,XX +XXX,XX @@ do_##NAME(void *vd, target_long s1, void *vs2, int i, \ | ||
1869 | RVVCALL(OPIVX3_RM, vwsmaccu_vx_b, WOP_UUU_B, H2, H1, vwsmaccu8) | ||
1870 | RVVCALL(OPIVX3_RM, vwsmaccu_vx_h, WOP_UUU_H, H4, H2, vwsmaccu16) | ||
1871 | RVVCALL(OPIVX3_RM, vwsmaccu_vx_w, WOP_UUU_W, H8, H4, vwsmaccu32) | ||
1872 | -GEN_VEXT_VX_RM(vwsmaccu_vx_b, 1, 2, clearh) | ||
1873 | -GEN_VEXT_VX_RM(vwsmaccu_vx_h, 2, 4, clearl) | ||
1874 | -GEN_VEXT_VX_RM(vwsmaccu_vx_w, 4, 8, clearq) | ||
1875 | +GEN_VEXT_VX_RM(vwsmaccu_vx_b, 1, 2) | ||
1876 | +GEN_VEXT_VX_RM(vwsmaccu_vx_h, 2, 4) | ||
1877 | +GEN_VEXT_VX_RM(vwsmaccu_vx_w, 4, 8) | ||
1878 | |||
1879 | static inline int16_t | ||
1880 | vwsmacc8(CPURISCVState *env, int vxrm, int8_t a, int8_t b, int16_t c) | ||
1881 | @@ -XXX,XX +XXX,XX @@ vwsmacc32(CPURISCVState *env, int vxrm, int32_t a, int32_t b, int64_t c) | ||
1882 | RVVCALL(OPIVV3_RM, vwsmacc_vv_b, WOP_SSS_B, H2, H1, H1, vwsmacc8) | ||
1883 | RVVCALL(OPIVV3_RM, vwsmacc_vv_h, WOP_SSS_H, H4, H2, H2, vwsmacc16) | ||
1884 | RVVCALL(OPIVV3_RM, vwsmacc_vv_w, WOP_SSS_W, H8, H4, H4, vwsmacc32) | ||
1885 | -GEN_VEXT_VV_RM(vwsmacc_vv_b, 1, 2, clearh) | ||
1886 | -GEN_VEXT_VV_RM(vwsmacc_vv_h, 2, 4, clearl) | ||
1887 | -GEN_VEXT_VV_RM(vwsmacc_vv_w, 4, 8, clearq) | ||
1888 | +GEN_VEXT_VV_RM(vwsmacc_vv_b, 1, 2) | ||
1889 | +GEN_VEXT_VV_RM(vwsmacc_vv_h, 2, 4) | ||
1890 | +GEN_VEXT_VV_RM(vwsmacc_vv_w, 4, 8) | ||
1891 | RVVCALL(OPIVX3_RM, vwsmacc_vx_b, WOP_SSS_B, H2, H1, vwsmacc8) | ||
1892 | RVVCALL(OPIVX3_RM, vwsmacc_vx_h, WOP_SSS_H, H4, H2, vwsmacc16) | ||
1893 | RVVCALL(OPIVX3_RM, vwsmacc_vx_w, WOP_SSS_W, H8, H4, vwsmacc32) | ||
1894 | -GEN_VEXT_VX_RM(vwsmacc_vx_b, 1, 2, clearh) | ||
1895 | -GEN_VEXT_VX_RM(vwsmacc_vx_h, 2, 4, clearl) | ||
1896 | -GEN_VEXT_VX_RM(vwsmacc_vx_w, 4, 8, clearq) | ||
1897 | +GEN_VEXT_VX_RM(vwsmacc_vx_b, 1, 2) | ||
1898 | +GEN_VEXT_VX_RM(vwsmacc_vx_h, 2, 4) | ||
1899 | +GEN_VEXT_VX_RM(vwsmacc_vx_w, 4, 8) | ||
1900 | |||
1901 | static inline int16_t | ||
1902 | vwsmaccsu8(CPURISCVState *env, int vxrm, uint8_t a, int8_t b, int16_t c) | ||
1903 | @@ -XXX,XX +XXX,XX @@ vwsmaccsu32(CPURISCVState *env, int vxrm, uint32_t a, int32_t b, int64_t c) | ||
1904 | RVVCALL(OPIVV3_RM, vwsmaccsu_vv_b, WOP_SSU_B, H2, H1, H1, vwsmaccsu8) | ||
1905 | RVVCALL(OPIVV3_RM, vwsmaccsu_vv_h, WOP_SSU_H, H4, H2, H2, vwsmaccsu16) | ||
1906 | RVVCALL(OPIVV3_RM, vwsmaccsu_vv_w, WOP_SSU_W, H8, H4, H4, vwsmaccsu32) | ||
1907 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_b, 1, 2, clearh) | ||
1908 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_h, 2, 4, clearl) | ||
1909 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_w, 4, 8, clearq) | ||
1910 | +GEN_VEXT_VV_RM(vwsmaccsu_vv_b, 1, 2) | ||
1911 | +GEN_VEXT_VV_RM(vwsmaccsu_vv_h, 2, 4) | ||
1912 | +GEN_VEXT_VV_RM(vwsmaccsu_vv_w, 4, 8) | ||
1913 | RVVCALL(OPIVX3_RM, vwsmaccsu_vx_b, WOP_SSU_B, H2, H1, vwsmaccsu8) | ||
1914 | RVVCALL(OPIVX3_RM, vwsmaccsu_vx_h, WOP_SSU_H, H4, H2, vwsmaccsu16) | ||
1915 | RVVCALL(OPIVX3_RM, vwsmaccsu_vx_w, WOP_SSU_W, H8, H4, vwsmaccsu32) | ||
1916 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_b, 1, 2, clearh) | ||
1917 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_h, 2, 4, clearl) | ||
1918 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_w, 4, 8, clearq) | ||
1919 | +GEN_VEXT_VX_RM(vwsmaccsu_vx_b, 1, 2) | ||
1920 | +GEN_VEXT_VX_RM(vwsmaccsu_vx_h, 2, 4) | ||
1921 | +GEN_VEXT_VX_RM(vwsmaccsu_vx_w, 4, 8) | ||
1922 | |||
1923 | static inline int16_t | ||
1924 | vwsmaccus8(CPURISCVState *env, int vxrm, int8_t a, uint8_t b, int16_t c) | ||
1925 | @@ -XXX,XX +XXX,XX @@ vwsmaccus32(CPURISCVState *env, int vxrm, int32_t a, uint32_t b, int64_t c) | ||
1926 | RVVCALL(OPIVX3_RM, vwsmaccus_vx_b, WOP_SUS_B, H2, H1, vwsmaccus8) | ||
1927 | RVVCALL(OPIVX3_RM, vwsmaccus_vx_h, WOP_SUS_H, H4, H2, vwsmaccus16) | ||
1928 | RVVCALL(OPIVX3_RM, vwsmaccus_vx_w, WOP_SUS_W, H8, H4, vwsmaccus32) | ||
1929 | -GEN_VEXT_VX_RM(vwsmaccus_vx_b, 1, 2, clearh) | ||
1930 | -GEN_VEXT_VX_RM(vwsmaccus_vx_h, 2, 4, clearl) | ||
1931 | -GEN_VEXT_VX_RM(vwsmaccus_vx_w, 4, 8, clearq) | ||
1932 | +GEN_VEXT_VX_RM(vwsmaccus_vx_b, 1, 2) | ||
1933 | +GEN_VEXT_VX_RM(vwsmaccus_vx_h, 2, 4) | ||
1934 | +GEN_VEXT_VX_RM(vwsmaccus_vx_w, 4, 8) | ||
1935 | |||
1936 | /* Vector Single-Width Scaling Shift Instructions */ | ||
1937 | static inline uint8_t | ||
1938 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vssrl_vv_b, OP_UUU_B, H1, H1, H1, vssrl8) | ||
1939 | RVVCALL(OPIVV2_RM, vssrl_vv_h, OP_UUU_H, H2, H2, H2, vssrl16) | ||
1940 | RVVCALL(OPIVV2_RM, vssrl_vv_w, OP_UUU_W, H4, H4, H4, vssrl32) | ||
1941 | RVVCALL(OPIVV2_RM, vssrl_vv_d, OP_UUU_D, H8, H8, H8, vssrl64) | ||
1942 | -GEN_VEXT_VV_RM(vssrl_vv_b, 1, 1, clearb) | ||
1943 | -GEN_VEXT_VV_RM(vssrl_vv_h, 2, 2, clearh) | ||
1944 | -GEN_VEXT_VV_RM(vssrl_vv_w, 4, 4, clearl) | ||
1945 | -GEN_VEXT_VV_RM(vssrl_vv_d, 8, 8, clearq) | ||
1946 | +GEN_VEXT_VV_RM(vssrl_vv_b, 1, 1) | ||
1947 | +GEN_VEXT_VV_RM(vssrl_vv_h, 2, 2) | ||
1948 | +GEN_VEXT_VV_RM(vssrl_vv_w, 4, 4) | ||
1949 | +GEN_VEXT_VV_RM(vssrl_vv_d, 8, 8) | ||
1950 | |||
1951 | RVVCALL(OPIVX2_RM, vssrl_vx_b, OP_UUU_B, H1, H1, vssrl8) | ||
1952 | RVVCALL(OPIVX2_RM, vssrl_vx_h, OP_UUU_H, H2, H2, vssrl16) | ||
1953 | RVVCALL(OPIVX2_RM, vssrl_vx_w, OP_UUU_W, H4, H4, vssrl32) | ||
1954 | RVVCALL(OPIVX2_RM, vssrl_vx_d, OP_UUU_D, H8, H8, vssrl64) | ||
1955 | -GEN_VEXT_VX_RM(vssrl_vx_b, 1, 1, clearb) | ||
1956 | -GEN_VEXT_VX_RM(vssrl_vx_h, 2, 2, clearh) | ||
1957 | -GEN_VEXT_VX_RM(vssrl_vx_w, 4, 4, clearl) | ||
1958 | -GEN_VEXT_VX_RM(vssrl_vx_d, 8, 8, clearq) | ||
1959 | +GEN_VEXT_VX_RM(vssrl_vx_b, 1, 1) | ||
1960 | +GEN_VEXT_VX_RM(vssrl_vx_h, 2, 2) | ||
1961 | +GEN_VEXT_VX_RM(vssrl_vx_w, 4, 4) | ||
1962 | +GEN_VEXT_VX_RM(vssrl_vx_d, 8, 8) | ||
1963 | |||
1964 | static inline int8_t | ||
1965 | vssra8(CPURISCVState *env, int vxrm, int8_t a, int8_t b) | ||
1966 | @@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2_RM, vssra_vv_b, OP_SSS_B, H1, H1, H1, vssra8) | ||
1967 | RVVCALL(OPIVV2_RM, vssra_vv_h, OP_SSS_H, H2, H2, H2, vssra16) | ||
1968 | RVVCALL(OPIVV2_RM, vssra_vv_w, OP_SSS_W, H4, H4, H4, vssra32) | ||
1969 | RVVCALL(OPIVV2_RM, vssra_vv_d, OP_SSS_D, H8, H8, H8, vssra64) | ||
1970 | -GEN_VEXT_VV_RM(vssra_vv_b, 1, 1, clearb) | ||
1971 | -GEN_VEXT_VV_RM(vssra_vv_h, 2, 2, clearh) | ||
1972 | -GEN_VEXT_VV_RM(vssra_vv_w, 4, 4, clearl) | ||
1973 | -GEN_VEXT_VV_RM(vssra_vv_d, 8, 8, clearq) | ||
1974 | +GEN_VEXT_VV_RM(vssra_vv_b, 1, 1) | ||
1975 | +GEN_VEXT_VV_RM(vssra_vv_h, 2, 2) | ||
1976 | +GEN_VEXT_VV_RM(vssra_vv_w, 4, 4) | ||
1977 | +GEN_VEXT_VV_RM(vssra_vv_d, 8, 8) | ||
1978 | |||
1979 | RVVCALL(OPIVX2_RM, vssra_vx_b, OP_SSS_B, H1, H1, vssra8) | ||
1980 | RVVCALL(OPIVX2_RM, vssra_vx_h, OP_SSS_H, H2, H2, vssra16) | ||
1981 | RVVCALL(OPIVX2_RM, vssra_vx_w, OP_SSS_W, H4, H4, vssra32) | ||
1982 | RVVCALL(OPIVX2_RM, vssra_vx_d, OP_SSS_D, H8, H8, vssra64) | ||
1983 | -GEN_VEXT_VX_RM(vssra_vx_b, 1, 1, clearb) | ||
1984 | -GEN_VEXT_VX_RM(vssra_vx_h, 2, 2, clearh) | ||
1985 | -GEN_VEXT_VX_RM(vssra_vx_w, 4, 4, clearl) | ||
1986 | -GEN_VEXT_VX_RM(vssra_vx_d, 8, 8, clearq) | ||
1987 | +GEN_VEXT_VX_RM(vssra_vx_b, 1, 1) | ||
1988 | +GEN_VEXT_VX_RM(vssra_vx_h, 2, 2) | ||
1989 | +GEN_VEXT_VX_RM(vssra_vx_w, 4, 4) | ||
1990 | +GEN_VEXT_VX_RM(vssra_vx_d, 8, 8) | ||
1991 | |||
1992 | /* Vector Narrowing Fixed-Point Clip Instructions */ | ||
1993 | static inline int8_t | ||
1994 | @@ -XXX,XX +XXX,XX @@ vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b) | ||
1995 | RVVCALL(OPIVV2_RM, vnclip_vv_b, NOP_SSS_B, H1, H2, H1, vnclip8) | ||
1996 | RVVCALL(OPIVV2_RM, vnclip_vv_h, NOP_SSS_H, H2, H4, H2, vnclip16) | ||
1997 | RVVCALL(OPIVV2_RM, vnclip_vv_w, NOP_SSS_W, H4, H8, H4, vnclip32) | ||
1998 | -GEN_VEXT_VV_RM(vnclip_vv_b, 1, 1, clearb) | ||
1999 | -GEN_VEXT_VV_RM(vnclip_vv_h, 2, 2, clearh) | ||
2000 | -GEN_VEXT_VV_RM(vnclip_vv_w, 4, 4, clearl) | ||
2001 | +GEN_VEXT_VV_RM(vnclip_vv_b, 1, 1) | ||
2002 | +GEN_VEXT_VV_RM(vnclip_vv_h, 2, 2) | ||
2003 | +GEN_VEXT_VV_RM(vnclip_vv_w, 4, 4) | ||
2004 | |||
2005 | RVVCALL(OPIVX2_RM, vnclip_vx_b, NOP_SSS_B, H1, H2, vnclip8) | ||
2006 | RVVCALL(OPIVX2_RM, vnclip_vx_h, NOP_SSS_H, H2, H4, vnclip16) | ||
2007 | RVVCALL(OPIVX2_RM, vnclip_vx_w, NOP_SSS_W, H4, H8, vnclip32) | ||
2008 | -GEN_VEXT_VX_RM(vnclip_vx_b, 1, 1, clearb) | ||
2009 | -GEN_VEXT_VX_RM(vnclip_vx_h, 2, 2, clearh) | ||
2010 | -GEN_VEXT_VX_RM(vnclip_vx_w, 4, 4, clearl) | ||
2011 | +GEN_VEXT_VX_RM(vnclip_vx_b, 1, 1) | ||
2012 | +GEN_VEXT_VX_RM(vnclip_vx_h, 2, 2) | ||
2013 | +GEN_VEXT_VX_RM(vnclip_vx_w, 4, 4) | ||
2014 | |||
2015 | static inline uint8_t | ||
2016 | vnclipu8(CPURISCVState *env, int vxrm, uint16_t a, uint8_t b) | ||
2017 | @@ -XXX,XX +XXX,XX @@ vnclipu32(CPURISCVState *env, int vxrm, uint64_t a, uint32_t b) | ||
2018 | RVVCALL(OPIVV2_RM, vnclipu_vv_b, NOP_UUU_B, H1, H2, H1, vnclipu8) | ||
2019 | RVVCALL(OPIVV2_RM, vnclipu_vv_h, NOP_UUU_H, H2, H4, H2, vnclipu16) | ||
2020 | RVVCALL(OPIVV2_RM, vnclipu_vv_w, NOP_UUU_W, H4, H8, H4, vnclipu32) | ||
2021 | -GEN_VEXT_VV_RM(vnclipu_vv_b, 1, 1, clearb) | ||
2022 | -GEN_VEXT_VV_RM(vnclipu_vv_h, 2, 2, clearh) | ||
2023 | -GEN_VEXT_VV_RM(vnclipu_vv_w, 4, 4, clearl) | ||
2024 | +GEN_VEXT_VV_RM(vnclipu_vv_b, 1, 1) | ||
2025 | +GEN_VEXT_VV_RM(vnclipu_vv_h, 2, 2) | ||
2026 | +GEN_VEXT_VV_RM(vnclipu_vv_w, 4, 4) | ||
2027 | |||
2028 | RVVCALL(OPIVX2_RM, vnclipu_vx_b, NOP_UUU_B, H1, H2, vnclipu8) | ||
2029 | RVVCALL(OPIVX2_RM, vnclipu_vx_h, NOP_UUU_H, H2, H4, vnclipu16) | ||
2030 | RVVCALL(OPIVX2_RM, vnclipu_vx_w, NOP_UUU_W, H4, H8, vnclipu32) | ||
2031 | -GEN_VEXT_VX_RM(vnclipu_vx_b, 1, 1, clearb) | ||
2032 | -GEN_VEXT_VX_RM(vnclipu_vx_h, 2, 2, clearh) | ||
2033 | -GEN_VEXT_VX_RM(vnclipu_vx_w, 4, 4, clearl) | ||
2034 | +GEN_VEXT_VX_RM(vnclipu_vx_b, 1, 1) | ||
2035 | +GEN_VEXT_VX_RM(vnclipu_vx_h, 2, 2) | ||
2036 | +GEN_VEXT_VX_RM(vnclipu_vx_w, 4, 4) | ||
2037 | |||
2038 | /* | ||
2039 | *** Vector Float Point Arithmetic Instructions | ||
2040 | @@ -XXX,XX +XXX,XX @@ static void do_##NAME(void *vd, void *vs1, void *vs2, int i, \ | ||
2041 | *((TD *)vd + HD(i)) = OP(s2, s1, &env->fp_status); \ | ||
2042 | } | ||
2043 | |||
2044 | -#define GEN_VEXT_VV_ENV(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
2045 | +#define GEN_VEXT_VV_ENV(NAME, ESZ, DSZ) \ | ||
2046 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2047 | void *vs2, CPURISCVState *env, \ | ||
2048 | uint32_t desc) \ | ||
2049 | { \ | ||
2050 | - uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
2051 | uint32_t vm = vext_vm(desc); \ | ||
2052 | uint32_t vl = env->vl; \ | ||
2053 | uint32_t i; \ | ||
2054 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2055 | } \ | ||
2056 | do_##NAME(vd, vs1, vs2, i, env); \ | ||
2057 | } \ | ||
2058 | - CLEAR_FN(vd, vl, vl * DSZ, vlmax * DSZ); \ | ||
2059 | } | ||
2060 | |||
2061 | RVVCALL(OPFVV2, vfadd_vv_h, OP_UUU_H, H2, H2, H2, float16_add) | ||
2062 | RVVCALL(OPFVV2, vfadd_vv_w, OP_UUU_W, H4, H4, H4, float32_add) | ||
2063 | RVVCALL(OPFVV2, vfadd_vv_d, OP_UUU_D, H8, H8, H8, float64_add) | ||
2064 | -GEN_VEXT_VV_ENV(vfadd_vv_h, 2, 2, clearh) | ||
2065 | -GEN_VEXT_VV_ENV(vfadd_vv_w, 4, 4, clearl) | ||
2066 | -GEN_VEXT_VV_ENV(vfadd_vv_d, 8, 8, clearq) | ||
2067 | +GEN_VEXT_VV_ENV(vfadd_vv_h, 2, 2) | ||
2068 | +GEN_VEXT_VV_ENV(vfadd_vv_w, 4, 4) | ||
2069 | +GEN_VEXT_VV_ENV(vfadd_vv_d, 8, 8) | ||
2070 | |||
2071 | #define OPFVF2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
2072 | static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \ | ||
2073 | @@ -XXX,XX +XXX,XX @@ static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \ | ||
2074 | *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, &env->fp_status);\ | ||
2075 | } | ||
2076 | |||
2077 | -#define GEN_VEXT_VF(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
2078 | +#define GEN_VEXT_VF(NAME, ESZ, DSZ) \ | ||
2079 | void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
2080 | void *vs2, CPURISCVState *env, \ | ||
2081 | uint32_t desc) \ | ||
2082 | { \ | ||
2083 | - uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
2084 | uint32_t vm = vext_vm(desc); \ | ||
2085 | uint32_t vl = env->vl; \ | ||
2086 | uint32_t i; \ | ||
2087 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
2088 | } \ | ||
2089 | do_##NAME(vd, s1, vs2, i, env); \ | ||
2090 | } \ | ||
2091 | - CLEAR_FN(vd, vl, vl * DSZ, vlmax * DSZ); \ | ||
2092 | } | ||
2093 | |||
2094 | RVVCALL(OPFVF2, vfadd_vf_h, OP_UUU_H, H2, H2, float16_add) | ||
2095 | RVVCALL(OPFVF2, vfadd_vf_w, OP_UUU_W, H4, H4, float32_add) | ||
2096 | RVVCALL(OPFVF2, vfadd_vf_d, OP_UUU_D, H8, H8, float64_add) | ||
2097 | -GEN_VEXT_VF(vfadd_vf_h, 2, 2, clearh) | ||
2098 | -GEN_VEXT_VF(vfadd_vf_w, 4, 4, clearl) | ||
2099 | -GEN_VEXT_VF(vfadd_vf_d, 8, 8, clearq) | ||
2100 | +GEN_VEXT_VF(vfadd_vf_h, 2, 2) | ||
2101 | +GEN_VEXT_VF(vfadd_vf_w, 4, 4) | ||
2102 | +GEN_VEXT_VF(vfadd_vf_d, 8, 8) | ||
2103 | |||
2104 | RVVCALL(OPFVV2, vfsub_vv_h, OP_UUU_H, H2, H2, H2, float16_sub) | ||
2105 | RVVCALL(OPFVV2, vfsub_vv_w, OP_UUU_W, H4, H4, H4, float32_sub) | ||
2106 | RVVCALL(OPFVV2, vfsub_vv_d, OP_UUU_D, H8, H8, H8, float64_sub) | ||
2107 | -GEN_VEXT_VV_ENV(vfsub_vv_h, 2, 2, clearh) | ||
2108 | -GEN_VEXT_VV_ENV(vfsub_vv_w, 4, 4, clearl) | ||
2109 | -GEN_VEXT_VV_ENV(vfsub_vv_d, 8, 8, clearq) | ||
2110 | +GEN_VEXT_VV_ENV(vfsub_vv_h, 2, 2) | ||
2111 | +GEN_VEXT_VV_ENV(vfsub_vv_w, 4, 4) | ||
2112 | +GEN_VEXT_VV_ENV(vfsub_vv_d, 8, 8) | ||
2113 | RVVCALL(OPFVF2, vfsub_vf_h, OP_UUU_H, H2, H2, float16_sub) | ||
2114 | RVVCALL(OPFVF2, vfsub_vf_w, OP_UUU_W, H4, H4, float32_sub) | ||
2115 | RVVCALL(OPFVF2, vfsub_vf_d, OP_UUU_D, H8, H8, float64_sub) | ||
2116 | -GEN_VEXT_VF(vfsub_vf_h, 2, 2, clearh) | ||
2117 | -GEN_VEXT_VF(vfsub_vf_w, 4, 4, clearl) | ||
2118 | -GEN_VEXT_VF(vfsub_vf_d, 8, 8, clearq) | ||
2119 | +GEN_VEXT_VF(vfsub_vf_h, 2, 2) | ||
2120 | +GEN_VEXT_VF(vfsub_vf_w, 4, 4) | ||
2121 | +GEN_VEXT_VF(vfsub_vf_d, 8, 8) | ||
2122 | |||
2123 | static uint16_t float16_rsub(uint16_t a, uint16_t b, float_status *s) | ||
2124 | { | ||
2125 | @@ -XXX,XX +XXX,XX @@ static uint64_t float64_rsub(uint64_t a, uint64_t b, float_status *s) | ||
2126 | RVVCALL(OPFVF2, vfrsub_vf_h, OP_UUU_H, H2, H2, float16_rsub) | ||
2127 | RVVCALL(OPFVF2, vfrsub_vf_w, OP_UUU_W, H4, H4, float32_rsub) | ||
2128 | RVVCALL(OPFVF2, vfrsub_vf_d, OP_UUU_D, H8, H8, float64_rsub) | ||
2129 | -GEN_VEXT_VF(vfrsub_vf_h, 2, 2, clearh) | ||
2130 | -GEN_VEXT_VF(vfrsub_vf_w, 4, 4, clearl) | ||
2131 | -GEN_VEXT_VF(vfrsub_vf_d, 8, 8, clearq) | ||
2132 | +GEN_VEXT_VF(vfrsub_vf_h, 2, 2) | ||
2133 | +GEN_VEXT_VF(vfrsub_vf_w, 4, 4) | ||
2134 | +GEN_VEXT_VF(vfrsub_vf_d, 8, 8) | ||
2135 | |||
2136 | /* Vector Widening Floating-Point Add/Subtract Instructions */ | ||
2137 | static uint32_t vfwadd16(uint16_t a, uint16_t b, float_status *s) | ||
2138 | @@ -XXX,XX +XXX,XX @@ static uint64_t vfwadd32(uint32_t a, uint32_t b, float_status *s) | ||
2139 | |||
2140 | RVVCALL(OPFVV2, vfwadd_vv_h, WOP_UUU_H, H4, H2, H2, vfwadd16) | ||
2141 | RVVCALL(OPFVV2, vfwadd_vv_w, WOP_UUU_W, H8, H4, H4, vfwadd32) | ||
2142 | -GEN_VEXT_VV_ENV(vfwadd_vv_h, 2, 4, clearl) | ||
2143 | -GEN_VEXT_VV_ENV(vfwadd_vv_w, 4, 8, clearq) | ||
2144 | +GEN_VEXT_VV_ENV(vfwadd_vv_h, 2, 4) | ||
2145 | +GEN_VEXT_VV_ENV(vfwadd_vv_w, 4, 8) | ||
2146 | RVVCALL(OPFVF2, vfwadd_vf_h, WOP_UUU_H, H4, H2, vfwadd16) | ||
2147 | RVVCALL(OPFVF2, vfwadd_vf_w, WOP_UUU_W, H8, H4, vfwadd32) | ||
2148 | -GEN_VEXT_VF(vfwadd_vf_h, 2, 4, clearl) | ||
2149 | -GEN_VEXT_VF(vfwadd_vf_w, 4, 8, clearq) | ||
2150 | +GEN_VEXT_VF(vfwadd_vf_h, 2, 4) | ||
2151 | +GEN_VEXT_VF(vfwadd_vf_w, 4, 8) | ||
2152 | |||
2153 | static uint32_t vfwsub16(uint16_t a, uint16_t b, float_status *s) | ||
2154 | { | ||
2155 | @@ -XXX,XX +XXX,XX @@ static uint64_t vfwsub32(uint32_t a, uint32_t b, float_status *s) | ||
2156 | |||
2157 | RVVCALL(OPFVV2, vfwsub_vv_h, WOP_UUU_H, H4, H2, H2, vfwsub16) | ||
2158 | RVVCALL(OPFVV2, vfwsub_vv_w, WOP_UUU_W, H8, H4, H4, vfwsub32) | ||
2159 | -GEN_VEXT_VV_ENV(vfwsub_vv_h, 2, 4, clearl) | ||
2160 | -GEN_VEXT_VV_ENV(vfwsub_vv_w, 4, 8, clearq) | ||
2161 | +GEN_VEXT_VV_ENV(vfwsub_vv_h, 2, 4) | ||
2162 | +GEN_VEXT_VV_ENV(vfwsub_vv_w, 4, 8) | ||
2163 | RVVCALL(OPFVF2, vfwsub_vf_h, WOP_UUU_H, H4, H2, vfwsub16) | ||
2164 | RVVCALL(OPFVF2, vfwsub_vf_w, WOP_UUU_W, H8, H4, vfwsub32) | ||
2165 | -GEN_VEXT_VF(vfwsub_vf_h, 2, 4, clearl) | ||
2166 | -GEN_VEXT_VF(vfwsub_vf_w, 4, 8, clearq) | ||
2167 | +GEN_VEXT_VF(vfwsub_vf_h, 2, 4) | ||
2168 | +GEN_VEXT_VF(vfwsub_vf_w, 4, 8) | ||
2169 | |||
2170 | static uint32_t vfwaddw16(uint32_t a, uint16_t b, float_status *s) | ||
2171 | { | ||
2172 | @@ -XXX,XX +XXX,XX @@ static uint64_t vfwaddw32(uint64_t a, uint32_t b, float_status *s) | ||
2173 | |||
2174 | RVVCALL(OPFVV2, vfwadd_wv_h, WOP_WUUU_H, H4, H2, H2, vfwaddw16) | ||
2175 | RVVCALL(OPFVV2, vfwadd_wv_w, WOP_WUUU_W, H8, H4, H4, vfwaddw32) | ||
2176 | -GEN_VEXT_VV_ENV(vfwadd_wv_h, 2, 4, clearl) | ||
2177 | -GEN_VEXT_VV_ENV(vfwadd_wv_w, 4, 8, clearq) | ||
2178 | +GEN_VEXT_VV_ENV(vfwadd_wv_h, 2, 4) | ||
2179 | +GEN_VEXT_VV_ENV(vfwadd_wv_w, 4, 8) | ||
2180 | RVVCALL(OPFVF2, vfwadd_wf_h, WOP_WUUU_H, H4, H2, vfwaddw16) | ||
2181 | RVVCALL(OPFVF2, vfwadd_wf_w, WOP_WUUU_W, H8, H4, vfwaddw32) | ||
2182 | -GEN_VEXT_VF(vfwadd_wf_h, 2, 4, clearl) | ||
2183 | -GEN_VEXT_VF(vfwadd_wf_w, 4, 8, clearq) | ||
2184 | +GEN_VEXT_VF(vfwadd_wf_h, 2, 4) | ||
2185 | +GEN_VEXT_VF(vfwadd_wf_w, 4, 8) | ||
2186 | |||
2187 | static uint32_t vfwsubw16(uint32_t a, uint16_t b, float_status *s) | ||
2188 | { | ||
2189 | @@ -XXX,XX +XXX,XX @@ static uint64_t vfwsubw32(uint64_t a, uint32_t b, float_status *s) | ||
2190 | |||
2191 | RVVCALL(OPFVV2, vfwsub_wv_h, WOP_WUUU_H, H4, H2, H2, vfwsubw16) | ||
2192 | RVVCALL(OPFVV2, vfwsub_wv_w, WOP_WUUU_W, H8, H4, H4, vfwsubw32) | ||
2193 | -GEN_VEXT_VV_ENV(vfwsub_wv_h, 2, 4, clearl) | ||
2194 | -GEN_VEXT_VV_ENV(vfwsub_wv_w, 4, 8, clearq) | ||
2195 | +GEN_VEXT_VV_ENV(vfwsub_wv_h, 2, 4) | ||
2196 | +GEN_VEXT_VV_ENV(vfwsub_wv_w, 4, 8) | ||
2197 | RVVCALL(OPFVF2, vfwsub_wf_h, WOP_WUUU_H, H4, H2, vfwsubw16) | ||
2198 | RVVCALL(OPFVF2, vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32) | ||
2199 | -GEN_VEXT_VF(vfwsub_wf_h, 2, 4, clearl) | ||
2200 | -GEN_VEXT_VF(vfwsub_wf_w, 4, 8, clearq) | ||
2201 | +GEN_VEXT_VF(vfwsub_wf_h, 2, 4) | ||
2202 | +GEN_VEXT_VF(vfwsub_wf_w, 4, 8) | ||
2203 | |||
2204 | /* Vector Single-Width Floating-Point Multiply/Divide Instructions */ | ||
2205 | RVVCALL(OPFVV2, vfmul_vv_h, OP_UUU_H, H2, H2, H2, float16_mul) | ||
2206 | RVVCALL(OPFVV2, vfmul_vv_w, OP_UUU_W, H4, H4, H4, float32_mul) | ||
2207 | RVVCALL(OPFVV2, vfmul_vv_d, OP_UUU_D, H8, H8, H8, float64_mul) | ||
2208 | -GEN_VEXT_VV_ENV(vfmul_vv_h, 2, 2, clearh) | ||
2209 | -GEN_VEXT_VV_ENV(vfmul_vv_w, 4, 4, clearl) | ||
2210 | -GEN_VEXT_VV_ENV(vfmul_vv_d, 8, 8, clearq) | ||
2211 | +GEN_VEXT_VV_ENV(vfmul_vv_h, 2, 2) | ||
2212 | +GEN_VEXT_VV_ENV(vfmul_vv_w, 4, 4) | ||
2213 | +GEN_VEXT_VV_ENV(vfmul_vv_d, 8, 8) | ||
2214 | RVVCALL(OPFVF2, vfmul_vf_h, OP_UUU_H, H2, H2, float16_mul) | ||
2215 | RVVCALL(OPFVF2, vfmul_vf_w, OP_UUU_W, H4, H4, float32_mul) | ||
2216 | RVVCALL(OPFVF2, vfmul_vf_d, OP_UUU_D, H8, H8, float64_mul) | ||
2217 | -GEN_VEXT_VF(vfmul_vf_h, 2, 2, clearh) | ||
2218 | -GEN_VEXT_VF(vfmul_vf_w, 4, 4, clearl) | ||
2219 | -GEN_VEXT_VF(vfmul_vf_d, 8, 8, clearq) | ||
2220 | +GEN_VEXT_VF(vfmul_vf_h, 2, 2) | ||
2221 | +GEN_VEXT_VF(vfmul_vf_w, 4, 4) | ||
2222 | +GEN_VEXT_VF(vfmul_vf_d, 8, 8) | ||
2223 | |||
2224 | RVVCALL(OPFVV2, vfdiv_vv_h, OP_UUU_H, H2, H2, H2, float16_div) | ||
2225 | RVVCALL(OPFVV2, vfdiv_vv_w, OP_UUU_W, H4, H4, H4, float32_div) | ||
2226 | RVVCALL(OPFVV2, vfdiv_vv_d, OP_UUU_D, H8, H8, H8, float64_div) | ||
2227 | -GEN_VEXT_VV_ENV(vfdiv_vv_h, 2, 2, clearh) | ||
2228 | -GEN_VEXT_VV_ENV(vfdiv_vv_w, 4, 4, clearl) | ||
2229 | -GEN_VEXT_VV_ENV(vfdiv_vv_d, 8, 8, clearq) | ||
2230 | +GEN_VEXT_VV_ENV(vfdiv_vv_h, 2, 2) | ||
2231 | +GEN_VEXT_VV_ENV(vfdiv_vv_w, 4, 4) | ||
2232 | +GEN_VEXT_VV_ENV(vfdiv_vv_d, 8, 8) | ||
2233 | RVVCALL(OPFVF2, vfdiv_vf_h, OP_UUU_H, H2, H2, float16_div) | ||
2234 | RVVCALL(OPFVF2, vfdiv_vf_w, OP_UUU_W, H4, H4, float32_div) | ||
2235 | RVVCALL(OPFVF2, vfdiv_vf_d, OP_UUU_D, H8, H8, float64_div) | ||
2236 | -GEN_VEXT_VF(vfdiv_vf_h, 2, 2, clearh) | ||
2237 | -GEN_VEXT_VF(vfdiv_vf_w, 4, 4, clearl) | ||
2238 | -GEN_VEXT_VF(vfdiv_vf_d, 8, 8, clearq) | ||
2239 | +GEN_VEXT_VF(vfdiv_vf_h, 2, 2) | ||
2240 | +GEN_VEXT_VF(vfdiv_vf_w, 4, 4) | ||
2241 | +GEN_VEXT_VF(vfdiv_vf_d, 8, 8) | ||
2242 | |||
2243 | static uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s) | ||
2244 | { | ||
2245 | @@ -XXX,XX +XXX,XX @@ static uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s) | ||
2246 | RVVCALL(OPFVF2, vfrdiv_vf_h, OP_UUU_H, H2, H2, float16_rdiv) | ||
2247 | RVVCALL(OPFVF2, vfrdiv_vf_w, OP_UUU_W, H4, H4, float32_rdiv) | ||
2248 | RVVCALL(OPFVF2, vfrdiv_vf_d, OP_UUU_D, H8, H8, float64_rdiv) | ||
2249 | -GEN_VEXT_VF(vfrdiv_vf_h, 2, 2, clearh) | ||
2250 | -GEN_VEXT_VF(vfrdiv_vf_w, 4, 4, clearl) | ||
2251 | -GEN_VEXT_VF(vfrdiv_vf_d, 8, 8, clearq) | ||
2252 | +GEN_VEXT_VF(vfrdiv_vf_h, 2, 2) | ||
2253 | +GEN_VEXT_VF(vfrdiv_vf_w, 4, 4) | ||
2254 | +GEN_VEXT_VF(vfrdiv_vf_d, 8, 8) | ||
2255 | |||
2256 | /* Vector Widening Floating-Point Multiply */ | ||
2257 | static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s) | ||
2258 | @@ -XXX,XX +XXX,XX @@ static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s) | ||
2259 | } | ||
2260 | RVVCALL(OPFVV2, vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16) | ||
2261 | RVVCALL(OPFVV2, vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32) | ||
2262 | -GEN_VEXT_VV_ENV(vfwmul_vv_h, 2, 4, clearl) | ||
2263 | -GEN_VEXT_VV_ENV(vfwmul_vv_w, 4, 8, clearq) | ||
2264 | +GEN_VEXT_VV_ENV(vfwmul_vv_h, 2, 4) | ||
2265 | +GEN_VEXT_VV_ENV(vfwmul_vv_w, 4, 8) | ||
2266 | RVVCALL(OPFVF2, vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16) | ||
2267 | RVVCALL(OPFVF2, vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32) | ||
2268 | -GEN_VEXT_VF(vfwmul_vf_h, 2, 4, clearl) | ||
2269 | -GEN_VEXT_VF(vfwmul_vf_w, 4, 8, clearq) | ||
2270 | +GEN_VEXT_VF(vfwmul_vf_h, 2, 4) | ||
2271 | +GEN_VEXT_VF(vfwmul_vf_w, 4, 8) | ||
2272 | |||
2273 | /* Vector Single-Width Floating-Point Fused Multiply-Add Instructions */ | ||
2274 | #define OPFVV3(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ | ||
2275 | @@ -XXX,XX +XXX,XX @@ static uint64_t fmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2276 | RVVCALL(OPFVV3, vfmacc_vv_h, OP_UUU_H, H2, H2, H2, fmacc16) | ||
2277 | RVVCALL(OPFVV3, vfmacc_vv_w, OP_UUU_W, H4, H4, H4, fmacc32) | ||
2278 | RVVCALL(OPFVV3, vfmacc_vv_d, OP_UUU_D, H8, H8, H8, fmacc64) | ||
2279 | -GEN_VEXT_VV_ENV(vfmacc_vv_h, 2, 2, clearh) | ||
2280 | -GEN_VEXT_VV_ENV(vfmacc_vv_w, 4, 4, clearl) | ||
2281 | -GEN_VEXT_VV_ENV(vfmacc_vv_d, 8, 8, clearq) | ||
2282 | +GEN_VEXT_VV_ENV(vfmacc_vv_h, 2, 2) | ||
2283 | +GEN_VEXT_VV_ENV(vfmacc_vv_w, 4, 4) | ||
2284 | +GEN_VEXT_VV_ENV(vfmacc_vv_d, 8, 8) | ||
2285 | |||
2286 | #define OPFVF3(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
2287 | static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \ | ||
2288 | @@ -XXX,XX +XXX,XX @@ static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \ | ||
2289 | RVVCALL(OPFVF3, vfmacc_vf_h, OP_UUU_H, H2, H2, fmacc16) | ||
2290 | RVVCALL(OPFVF3, vfmacc_vf_w, OP_UUU_W, H4, H4, fmacc32) | ||
2291 | RVVCALL(OPFVF3, vfmacc_vf_d, OP_UUU_D, H8, H8, fmacc64) | ||
2292 | -GEN_VEXT_VF(vfmacc_vf_h, 2, 2, clearh) | ||
2293 | -GEN_VEXT_VF(vfmacc_vf_w, 4, 4, clearl) | ||
2294 | -GEN_VEXT_VF(vfmacc_vf_d, 8, 8, clearq) | ||
2295 | +GEN_VEXT_VF(vfmacc_vf_h, 2, 2) | ||
2296 | +GEN_VEXT_VF(vfmacc_vf_w, 4, 4) | ||
2297 | +GEN_VEXT_VF(vfmacc_vf_d, 8, 8) | ||
2298 | |||
2299 | static uint16_t fnmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2300 | { | ||
2301 | @@ -XXX,XX +XXX,XX @@ static uint64_t fnmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2302 | RVVCALL(OPFVV3, vfnmacc_vv_h, OP_UUU_H, H2, H2, H2, fnmacc16) | ||
2303 | RVVCALL(OPFVV3, vfnmacc_vv_w, OP_UUU_W, H4, H4, H4, fnmacc32) | ||
2304 | RVVCALL(OPFVV3, vfnmacc_vv_d, OP_UUU_D, H8, H8, H8, fnmacc64) | ||
2305 | -GEN_VEXT_VV_ENV(vfnmacc_vv_h, 2, 2, clearh) | ||
2306 | -GEN_VEXT_VV_ENV(vfnmacc_vv_w, 4, 4, clearl) | ||
2307 | -GEN_VEXT_VV_ENV(vfnmacc_vv_d, 8, 8, clearq) | ||
2308 | +GEN_VEXT_VV_ENV(vfnmacc_vv_h, 2, 2) | ||
2309 | +GEN_VEXT_VV_ENV(vfnmacc_vv_w, 4, 4) | ||
2310 | +GEN_VEXT_VV_ENV(vfnmacc_vv_d, 8, 8) | ||
2311 | RVVCALL(OPFVF3, vfnmacc_vf_h, OP_UUU_H, H2, H2, fnmacc16) | ||
2312 | RVVCALL(OPFVF3, vfnmacc_vf_w, OP_UUU_W, H4, H4, fnmacc32) | ||
2313 | RVVCALL(OPFVF3, vfnmacc_vf_d, OP_UUU_D, H8, H8, fnmacc64) | ||
2314 | -GEN_VEXT_VF(vfnmacc_vf_h, 2, 2, clearh) | ||
2315 | -GEN_VEXT_VF(vfnmacc_vf_w, 4, 4, clearl) | ||
2316 | -GEN_VEXT_VF(vfnmacc_vf_d, 8, 8, clearq) | ||
2317 | +GEN_VEXT_VF(vfnmacc_vf_h, 2, 2) | ||
2318 | +GEN_VEXT_VF(vfnmacc_vf_w, 4, 4) | ||
2319 | +GEN_VEXT_VF(vfnmacc_vf_d, 8, 8) | ||
2320 | |||
2321 | static uint16_t fmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2322 | { | ||
2323 | @@ -XXX,XX +XXX,XX @@ static uint64_t fmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2324 | RVVCALL(OPFVV3, vfmsac_vv_h, OP_UUU_H, H2, H2, H2, fmsac16) | ||
2325 | RVVCALL(OPFVV3, vfmsac_vv_w, OP_UUU_W, H4, H4, H4, fmsac32) | ||
2326 | RVVCALL(OPFVV3, vfmsac_vv_d, OP_UUU_D, H8, H8, H8, fmsac64) | ||
2327 | -GEN_VEXT_VV_ENV(vfmsac_vv_h, 2, 2, clearh) | ||
2328 | -GEN_VEXT_VV_ENV(vfmsac_vv_w, 4, 4, clearl) | ||
2329 | -GEN_VEXT_VV_ENV(vfmsac_vv_d, 8, 8, clearq) | ||
2330 | +GEN_VEXT_VV_ENV(vfmsac_vv_h, 2, 2) | ||
2331 | +GEN_VEXT_VV_ENV(vfmsac_vv_w, 4, 4) | ||
2332 | +GEN_VEXT_VV_ENV(vfmsac_vv_d, 8, 8) | ||
2333 | RVVCALL(OPFVF3, vfmsac_vf_h, OP_UUU_H, H2, H2, fmsac16) | ||
2334 | RVVCALL(OPFVF3, vfmsac_vf_w, OP_UUU_W, H4, H4, fmsac32) | ||
2335 | RVVCALL(OPFVF3, vfmsac_vf_d, OP_UUU_D, H8, H8, fmsac64) | ||
2336 | -GEN_VEXT_VF(vfmsac_vf_h, 2, 2, clearh) | ||
2337 | -GEN_VEXT_VF(vfmsac_vf_w, 4, 4, clearl) | ||
2338 | -GEN_VEXT_VF(vfmsac_vf_d, 8, 8, clearq) | ||
2339 | +GEN_VEXT_VF(vfmsac_vf_h, 2, 2) | ||
2340 | +GEN_VEXT_VF(vfmsac_vf_w, 4, 4) | ||
2341 | +GEN_VEXT_VF(vfmsac_vf_d, 8, 8) | ||
2342 | |||
2343 | static uint16_t fnmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2344 | { | ||
2345 | @@ -XXX,XX +XXX,XX @@ static uint64_t fnmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2346 | RVVCALL(OPFVV3, vfnmsac_vv_h, OP_UUU_H, H2, H2, H2, fnmsac16) | ||
2347 | RVVCALL(OPFVV3, vfnmsac_vv_w, OP_UUU_W, H4, H4, H4, fnmsac32) | ||
2348 | RVVCALL(OPFVV3, vfnmsac_vv_d, OP_UUU_D, H8, H8, H8, fnmsac64) | ||
2349 | -GEN_VEXT_VV_ENV(vfnmsac_vv_h, 2, 2, clearh) | ||
2350 | -GEN_VEXT_VV_ENV(vfnmsac_vv_w, 4, 4, clearl) | ||
2351 | -GEN_VEXT_VV_ENV(vfnmsac_vv_d, 8, 8, clearq) | ||
2352 | +GEN_VEXT_VV_ENV(vfnmsac_vv_h, 2, 2) | ||
2353 | +GEN_VEXT_VV_ENV(vfnmsac_vv_w, 4, 4) | ||
2354 | +GEN_VEXT_VV_ENV(vfnmsac_vv_d, 8, 8) | ||
2355 | RVVCALL(OPFVF3, vfnmsac_vf_h, OP_UUU_H, H2, H2, fnmsac16) | ||
2356 | RVVCALL(OPFVF3, vfnmsac_vf_w, OP_UUU_W, H4, H4, fnmsac32) | ||
2357 | RVVCALL(OPFVF3, vfnmsac_vf_d, OP_UUU_D, H8, H8, fnmsac64) | ||
2358 | -GEN_VEXT_VF(vfnmsac_vf_h, 2, 2, clearh) | ||
2359 | -GEN_VEXT_VF(vfnmsac_vf_w, 4, 4, clearl) | ||
2360 | -GEN_VEXT_VF(vfnmsac_vf_d, 8, 8, clearq) | ||
2361 | +GEN_VEXT_VF(vfnmsac_vf_h, 2, 2) | ||
2362 | +GEN_VEXT_VF(vfnmsac_vf_w, 4, 4) | ||
2363 | +GEN_VEXT_VF(vfnmsac_vf_d, 8, 8) | ||
2364 | |||
2365 | static uint16_t fmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2366 | { | ||
2367 | @@ -XXX,XX +XXX,XX @@ static uint64_t fmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2368 | RVVCALL(OPFVV3, vfmadd_vv_h, OP_UUU_H, H2, H2, H2, fmadd16) | ||
2369 | RVVCALL(OPFVV3, vfmadd_vv_w, OP_UUU_W, H4, H4, H4, fmadd32) | ||
2370 | RVVCALL(OPFVV3, vfmadd_vv_d, OP_UUU_D, H8, H8, H8, fmadd64) | ||
2371 | -GEN_VEXT_VV_ENV(vfmadd_vv_h, 2, 2, clearh) | ||
2372 | -GEN_VEXT_VV_ENV(vfmadd_vv_w, 4, 4, clearl) | ||
2373 | -GEN_VEXT_VV_ENV(vfmadd_vv_d, 8, 8, clearq) | ||
2374 | +GEN_VEXT_VV_ENV(vfmadd_vv_h, 2, 2) | ||
2375 | +GEN_VEXT_VV_ENV(vfmadd_vv_w, 4, 4) | ||
2376 | +GEN_VEXT_VV_ENV(vfmadd_vv_d, 8, 8) | ||
2377 | RVVCALL(OPFVF3, vfmadd_vf_h, OP_UUU_H, H2, H2, fmadd16) | ||
2378 | RVVCALL(OPFVF3, vfmadd_vf_w, OP_UUU_W, H4, H4, fmadd32) | ||
2379 | RVVCALL(OPFVF3, vfmadd_vf_d, OP_UUU_D, H8, H8, fmadd64) | ||
2380 | -GEN_VEXT_VF(vfmadd_vf_h, 2, 2, clearh) | ||
2381 | -GEN_VEXT_VF(vfmadd_vf_w, 4, 4, clearl) | ||
2382 | -GEN_VEXT_VF(vfmadd_vf_d, 8, 8, clearq) | ||
2383 | +GEN_VEXT_VF(vfmadd_vf_h, 2, 2) | ||
2384 | +GEN_VEXT_VF(vfmadd_vf_w, 4, 4) | ||
2385 | +GEN_VEXT_VF(vfmadd_vf_d, 8, 8) | ||
2386 | |||
2387 | static uint16_t fnmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2388 | { | ||
2389 | @@ -XXX,XX +XXX,XX @@ static uint64_t fnmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2390 | RVVCALL(OPFVV3, vfnmadd_vv_h, OP_UUU_H, H2, H2, H2, fnmadd16) | ||
2391 | RVVCALL(OPFVV3, vfnmadd_vv_w, OP_UUU_W, H4, H4, H4, fnmadd32) | ||
2392 | RVVCALL(OPFVV3, vfnmadd_vv_d, OP_UUU_D, H8, H8, H8, fnmadd64) | ||
2393 | -GEN_VEXT_VV_ENV(vfnmadd_vv_h, 2, 2, clearh) | ||
2394 | -GEN_VEXT_VV_ENV(vfnmadd_vv_w, 4, 4, clearl) | ||
2395 | -GEN_VEXT_VV_ENV(vfnmadd_vv_d, 8, 8, clearq) | ||
2396 | +GEN_VEXT_VV_ENV(vfnmadd_vv_h, 2, 2) | ||
2397 | +GEN_VEXT_VV_ENV(vfnmadd_vv_w, 4, 4) | ||
2398 | +GEN_VEXT_VV_ENV(vfnmadd_vv_d, 8, 8) | ||
2399 | RVVCALL(OPFVF3, vfnmadd_vf_h, OP_UUU_H, H2, H2, fnmadd16) | ||
2400 | RVVCALL(OPFVF3, vfnmadd_vf_w, OP_UUU_W, H4, H4, fnmadd32) | ||
2401 | RVVCALL(OPFVF3, vfnmadd_vf_d, OP_UUU_D, H8, H8, fnmadd64) | ||
2402 | -GEN_VEXT_VF(vfnmadd_vf_h, 2, 2, clearh) | ||
2403 | -GEN_VEXT_VF(vfnmadd_vf_w, 4, 4, clearl) | ||
2404 | -GEN_VEXT_VF(vfnmadd_vf_d, 8, 8, clearq) | ||
2405 | +GEN_VEXT_VF(vfnmadd_vf_h, 2, 2) | ||
2406 | +GEN_VEXT_VF(vfnmadd_vf_w, 4, 4) | ||
2407 | +GEN_VEXT_VF(vfnmadd_vf_d, 8, 8) | ||
2408 | |||
2409 | static uint16_t fmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2410 | { | ||
2411 | @@ -XXX,XX +XXX,XX @@ static uint64_t fmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2412 | RVVCALL(OPFVV3, vfmsub_vv_h, OP_UUU_H, H2, H2, H2, fmsub16) | ||
2413 | RVVCALL(OPFVV3, vfmsub_vv_w, OP_UUU_W, H4, H4, H4, fmsub32) | ||
2414 | RVVCALL(OPFVV3, vfmsub_vv_d, OP_UUU_D, H8, H8, H8, fmsub64) | ||
2415 | -GEN_VEXT_VV_ENV(vfmsub_vv_h, 2, 2, clearh) | ||
2416 | -GEN_VEXT_VV_ENV(vfmsub_vv_w, 4, 4, clearl) | ||
2417 | -GEN_VEXT_VV_ENV(vfmsub_vv_d, 8, 8, clearq) | ||
2418 | +GEN_VEXT_VV_ENV(vfmsub_vv_h, 2, 2) | ||
2419 | +GEN_VEXT_VV_ENV(vfmsub_vv_w, 4, 4) | ||
2420 | +GEN_VEXT_VV_ENV(vfmsub_vv_d, 8, 8) | ||
2421 | RVVCALL(OPFVF3, vfmsub_vf_h, OP_UUU_H, H2, H2, fmsub16) | ||
2422 | RVVCALL(OPFVF3, vfmsub_vf_w, OP_UUU_W, H4, H4, fmsub32) | ||
2423 | RVVCALL(OPFVF3, vfmsub_vf_d, OP_UUU_D, H8, H8, fmsub64) | ||
2424 | -GEN_VEXT_VF(vfmsub_vf_h, 2, 2, clearh) | ||
2425 | -GEN_VEXT_VF(vfmsub_vf_w, 4, 4, clearl) | ||
2426 | -GEN_VEXT_VF(vfmsub_vf_d, 8, 8, clearq) | ||
2427 | +GEN_VEXT_VF(vfmsub_vf_h, 2, 2) | ||
2428 | +GEN_VEXT_VF(vfmsub_vf_w, 4, 4) | ||
2429 | +GEN_VEXT_VF(vfmsub_vf_d, 8, 8) | ||
2430 | |||
2431 | static uint16_t fnmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s) | ||
2432 | { | ||
2433 | @@ -XXX,XX +XXX,XX @@ static uint64_t fnmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s) | ||
2434 | RVVCALL(OPFVV3, vfnmsub_vv_h, OP_UUU_H, H2, H2, H2, fnmsub16) | ||
2435 | RVVCALL(OPFVV3, vfnmsub_vv_w, OP_UUU_W, H4, H4, H4, fnmsub32) | ||
2436 | RVVCALL(OPFVV3, vfnmsub_vv_d, OP_UUU_D, H8, H8, H8, fnmsub64) | ||
2437 | -GEN_VEXT_VV_ENV(vfnmsub_vv_h, 2, 2, clearh) | ||
2438 | -GEN_VEXT_VV_ENV(vfnmsub_vv_w, 4, 4, clearl) | ||
2439 | -GEN_VEXT_VV_ENV(vfnmsub_vv_d, 8, 8, clearq) | ||
2440 | +GEN_VEXT_VV_ENV(vfnmsub_vv_h, 2, 2) | ||
2441 | +GEN_VEXT_VV_ENV(vfnmsub_vv_w, 4, 4) | ||
2442 | +GEN_VEXT_VV_ENV(vfnmsub_vv_d, 8, 8) | ||
2443 | RVVCALL(OPFVF3, vfnmsub_vf_h, OP_UUU_H, H2, H2, fnmsub16) | ||
2444 | RVVCALL(OPFVF3, vfnmsub_vf_w, OP_UUU_W, H4, H4, fnmsub32) | ||
2445 | RVVCALL(OPFVF3, vfnmsub_vf_d, OP_UUU_D, H8, H8, fnmsub64) | ||
2446 | -GEN_VEXT_VF(vfnmsub_vf_h, 2, 2, clearh) | ||
2447 | -GEN_VEXT_VF(vfnmsub_vf_w, 4, 4, clearl) | ||
2448 | -GEN_VEXT_VF(vfnmsub_vf_d, 8, 8, clearq) | ||
2449 | +GEN_VEXT_VF(vfnmsub_vf_h, 2, 2) | ||
2450 | +GEN_VEXT_VF(vfnmsub_vf_w, 4, 4) | ||
2451 | +GEN_VEXT_VF(vfnmsub_vf_d, 8, 8) | ||
2452 | |||
2453 | /* Vector Widening Floating-Point Fused Multiply-Add Instructions */ | ||
2454 | static uint32_t fwmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s) | ||
2455 | @@ -XXX,XX +XXX,XX @@ static uint64_t fwmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s) | ||
2456 | |||
2457 | RVVCALL(OPFVV3, vfwmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwmacc16) | ||
2458 | RVVCALL(OPFVV3, vfwmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwmacc32) | ||
2459 | -GEN_VEXT_VV_ENV(vfwmacc_vv_h, 2, 4, clearl) | ||
2460 | -GEN_VEXT_VV_ENV(vfwmacc_vv_w, 4, 8, clearq) | ||
2461 | +GEN_VEXT_VV_ENV(vfwmacc_vv_h, 2, 4) | ||
2462 | +GEN_VEXT_VV_ENV(vfwmacc_vv_w, 4, 8) | ||
2463 | RVVCALL(OPFVF3, vfwmacc_vf_h, WOP_UUU_H, H4, H2, fwmacc16) | ||
2464 | RVVCALL(OPFVF3, vfwmacc_vf_w, WOP_UUU_W, H8, H4, fwmacc32) | ||
2465 | -GEN_VEXT_VF(vfwmacc_vf_h, 2, 4, clearl) | ||
2466 | -GEN_VEXT_VF(vfwmacc_vf_w, 4, 8, clearq) | ||
2467 | +GEN_VEXT_VF(vfwmacc_vf_h, 2, 4) | ||
2468 | +GEN_VEXT_VF(vfwmacc_vf_w, 4, 8) | ||
2469 | |||
2470 | static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s) | ||
2471 | { | ||
2472 | @@ -XXX,XX +XXX,XX @@ static uint64_t fwnmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s) | ||
2473 | |||
2474 | RVVCALL(OPFVV3, vfwnmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwnmacc16) | ||
2475 | RVVCALL(OPFVV3, vfwnmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwnmacc32) | ||
2476 | -GEN_VEXT_VV_ENV(vfwnmacc_vv_h, 2, 4, clearl) | ||
2477 | -GEN_VEXT_VV_ENV(vfwnmacc_vv_w, 4, 8, clearq) | ||
2478 | +GEN_VEXT_VV_ENV(vfwnmacc_vv_h, 2, 4) | ||
2479 | +GEN_VEXT_VV_ENV(vfwnmacc_vv_w, 4, 8) | ||
2480 | RVVCALL(OPFVF3, vfwnmacc_vf_h, WOP_UUU_H, H4, H2, fwnmacc16) | ||
2481 | RVVCALL(OPFVF3, vfwnmacc_vf_w, WOP_UUU_W, H8, H4, fwnmacc32) | ||
2482 | -GEN_VEXT_VF(vfwnmacc_vf_h, 2, 4, clearl) | ||
2483 | -GEN_VEXT_VF(vfwnmacc_vf_w, 4, 8, clearq) | ||
2484 | +GEN_VEXT_VF(vfwnmacc_vf_h, 2, 4) | ||
2485 | +GEN_VEXT_VF(vfwnmacc_vf_w, 4, 8) | ||
2486 | |||
2487 | static uint32_t fwmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s) | ||
2488 | { | ||
2489 | @@ -XXX,XX +XXX,XX @@ static uint64_t fwmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s) | ||
2490 | |||
2491 | RVVCALL(OPFVV3, vfwmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwmsac16) | ||
2492 | RVVCALL(OPFVV3, vfwmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwmsac32) | ||
2493 | -GEN_VEXT_VV_ENV(vfwmsac_vv_h, 2, 4, clearl) | ||
2494 | -GEN_VEXT_VV_ENV(vfwmsac_vv_w, 4, 8, clearq) | ||
2495 | +GEN_VEXT_VV_ENV(vfwmsac_vv_h, 2, 4) | ||
2496 | +GEN_VEXT_VV_ENV(vfwmsac_vv_w, 4, 8) | ||
2497 | RVVCALL(OPFVF3, vfwmsac_vf_h, WOP_UUU_H, H4, H2, fwmsac16) | ||
2498 | RVVCALL(OPFVF3, vfwmsac_vf_w, WOP_UUU_W, H8, H4, fwmsac32) | ||
2499 | -GEN_VEXT_VF(vfwmsac_vf_h, 2, 4, clearl) | ||
2500 | -GEN_VEXT_VF(vfwmsac_vf_w, 4, 8, clearq) | ||
2501 | +GEN_VEXT_VF(vfwmsac_vf_h, 2, 4) | ||
2502 | +GEN_VEXT_VF(vfwmsac_vf_w, 4, 8) | ||
2503 | |||
2504 | static uint32_t fwnmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s) | ||
2505 | { | ||
2506 | @@ -XXX,XX +XXX,XX @@ static uint64_t fwnmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s) | ||
2507 | |||
2508 | RVVCALL(OPFVV3, vfwnmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwnmsac16) | ||
2509 | RVVCALL(OPFVV3, vfwnmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwnmsac32) | ||
2510 | -GEN_VEXT_VV_ENV(vfwnmsac_vv_h, 2, 4, clearl) | ||
2511 | -GEN_VEXT_VV_ENV(vfwnmsac_vv_w, 4, 8, clearq) | ||
2512 | +GEN_VEXT_VV_ENV(vfwnmsac_vv_h, 2, 4) | ||
2513 | +GEN_VEXT_VV_ENV(vfwnmsac_vv_w, 4, 8) | ||
2514 | RVVCALL(OPFVF3, vfwnmsac_vf_h, WOP_UUU_H, H4, H2, fwnmsac16) | ||
2515 | RVVCALL(OPFVF3, vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32) | ||
2516 | -GEN_VEXT_VF(vfwnmsac_vf_h, 2, 4, clearl) | ||
2517 | -GEN_VEXT_VF(vfwnmsac_vf_w, 4, 8, clearq) | ||
2518 | +GEN_VEXT_VF(vfwnmsac_vf_h, 2, 4) | ||
2519 | +GEN_VEXT_VF(vfwnmsac_vf_w, 4, 8) | ||
2520 | |||
2521 | /* Vector Floating-Point Square-Root Instruction */ | ||
2522 | /* (TD, T2, TX2) */ | ||
2523 | @@ -XXX,XX +XXX,XX @@ static void do_##NAME(void *vd, void *vs2, int i, \ | ||
2524 | *((TD *)vd + HD(i)) = OP(s2, &env->fp_status); \ | ||
2525 | } | ||
2526 | |||
2527 | -#define GEN_VEXT_V_ENV(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
2528 | +#define GEN_VEXT_V_ENV(NAME, ESZ, DSZ) \ | ||
2529 | void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
2530 | CPURISCVState *env, uint32_t desc) \ | ||
2531 | { \ | ||
2532 | - uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
2533 | uint32_t vm = vext_vm(desc); \ | ||
2534 | uint32_t vl = env->vl; \ | ||
2535 | uint32_t i; \ | ||
2536 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
2537 | } \ | ||
2538 | do_##NAME(vd, vs2, i, env); \ | ||
2539 | } \ | ||
2540 | - CLEAR_FN(vd, vl, vl * DSZ, vlmax * DSZ); \ | ||
2541 | } | ||
2542 | |||
2543 | RVVCALL(OPFVV1, vfsqrt_v_h, OP_UU_H, H2, H2, float16_sqrt) | ||
2544 | RVVCALL(OPFVV1, vfsqrt_v_w, OP_UU_W, H4, H4, float32_sqrt) | ||
2545 | RVVCALL(OPFVV1, vfsqrt_v_d, OP_UU_D, H8, H8, float64_sqrt) | ||
2546 | -GEN_VEXT_V_ENV(vfsqrt_v_h, 2, 2, clearh) | ||
2547 | -GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4, clearl) | ||
2548 | -GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8, clearq) | ||
2549 | +GEN_VEXT_V_ENV(vfsqrt_v_h, 2, 2) | ||
2550 | +GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4) | ||
2551 | +GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8) | ||
2552 | |||
2553 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
2554 | RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum) | ||
2555 | RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum) | ||
2556 | RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum) | ||
2557 | -GEN_VEXT_VV_ENV(vfmin_vv_h, 2, 2, clearh) | ||
2558 | -GEN_VEXT_VV_ENV(vfmin_vv_w, 4, 4, clearl) | ||
2559 | -GEN_VEXT_VV_ENV(vfmin_vv_d, 8, 8, clearq) | ||
2560 | +GEN_VEXT_VV_ENV(vfmin_vv_h, 2, 2) | ||
2561 | +GEN_VEXT_VV_ENV(vfmin_vv_w, 4, 4) | ||
2562 | +GEN_VEXT_VV_ENV(vfmin_vv_d, 8, 8) | ||
2563 | RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum) | ||
2564 | RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum) | ||
2565 | RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum) | ||
2566 | -GEN_VEXT_VF(vfmin_vf_h, 2, 2, clearh) | ||
2567 | -GEN_VEXT_VF(vfmin_vf_w, 4, 4, clearl) | ||
2568 | -GEN_VEXT_VF(vfmin_vf_d, 8, 8, clearq) | ||
2569 | +GEN_VEXT_VF(vfmin_vf_h, 2, 2) | ||
2570 | +GEN_VEXT_VF(vfmin_vf_w, 4, 4) | ||
2571 | +GEN_VEXT_VF(vfmin_vf_d, 8, 8) | ||
2572 | |||
2573 | RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum) | ||
2574 | RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum) | ||
2575 | RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum) | ||
2576 | -GEN_VEXT_VV_ENV(vfmax_vv_h, 2, 2, clearh) | ||
2577 | -GEN_VEXT_VV_ENV(vfmax_vv_w, 4, 4, clearl) | ||
2578 | -GEN_VEXT_VV_ENV(vfmax_vv_d, 8, 8, clearq) | ||
2579 | +GEN_VEXT_VV_ENV(vfmax_vv_h, 2, 2) | ||
2580 | +GEN_VEXT_VV_ENV(vfmax_vv_w, 4, 4) | ||
2581 | +GEN_VEXT_VV_ENV(vfmax_vv_d, 8, 8) | ||
2582 | RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum) | ||
2583 | RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum) | ||
2584 | RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum) | ||
2585 | -GEN_VEXT_VF(vfmax_vf_h, 2, 2, clearh) | ||
2586 | -GEN_VEXT_VF(vfmax_vf_w, 4, 4, clearl) | ||
2587 | -GEN_VEXT_VF(vfmax_vf_d, 8, 8, clearq) | ||
2588 | +GEN_VEXT_VF(vfmax_vf_h, 2, 2) | ||
2589 | +GEN_VEXT_VF(vfmax_vf_w, 4, 4) | ||
2590 | +GEN_VEXT_VF(vfmax_vf_d, 8, 8) | ||
2591 | |||
2592 | /* Vector Floating-Point Sign-Injection Instructions */ | ||
2593 | static uint16_t fsgnj16(uint16_t a, uint16_t b, float_status *s) | ||
2594 | @@ -XXX,XX +XXX,XX @@ static uint64_t fsgnj64(uint64_t a, uint64_t b, float_status *s) | ||
2595 | RVVCALL(OPFVV2, vfsgnj_vv_h, OP_UUU_H, H2, H2, H2, fsgnj16) | ||
2596 | RVVCALL(OPFVV2, vfsgnj_vv_w, OP_UUU_W, H4, H4, H4, fsgnj32) | ||
2597 | RVVCALL(OPFVV2, vfsgnj_vv_d, OP_UUU_D, H8, H8, H8, fsgnj64) | ||
2598 | -GEN_VEXT_VV_ENV(vfsgnj_vv_h, 2, 2, clearh) | ||
2599 | -GEN_VEXT_VV_ENV(vfsgnj_vv_w, 4, 4, clearl) | ||
2600 | -GEN_VEXT_VV_ENV(vfsgnj_vv_d, 8, 8, clearq) | ||
2601 | +GEN_VEXT_VV_ENV(vfsgnj_vv_h, 2, 2) | ||
2602 | +GEN_VEXT_VV_ENV(vfsgnj_vv_w, 4, 4) | ||
2603 | +GEN_VEXT_VV_ENV(vfsgnj_vv_d, 8, 8) | ||
2604 | RVVCALL(OPFVF2, vfsgnj_vf_h, OP_UUU_H, H2, H2, fsgnj16) | ||
2605 | RVVCALL(OPFVF2, vfsgnj_vf_w, OP_UUU_W, H4, H4, fsgnj32) | ||
2606 | RVVCALL(OPFVF2, vfsgnj_vf_d, OP_UUU_D, H8, H8, fsgnj64) | ||
2607 | -GEN_VEXT_VF(vfsgnj_vf_h, 2, 2, clearh) | ||
2608 | -GEN_VEXT_VF(vfsgnj_vf_w, 4, 4, clearl) | ||
2609 | -GEN_VEXT_VF(vfsgnj_vf_d, 8, 8, clearq) | ||
2610 | +GEN_VEXT_VF(vfsgnj_vf_h, 2, 2) | ||
2611 | +GEN_VEXT_VF(vfsgnj_vf_w, 4, 4) | ||
2612 | +GEN_VEXT_VF(vfsgnj_vf_d, 8, 8) | ||
2613 | |||
2614 | static uint16_t fsgnjn16(uint16_t a, uint16_t b, float_status *s) | ||
2615 | { | ||
2616 | @@ -XXX,XX +XXX,XX @@ static uint64_t fsgnjn64(uint64_t a, uint64_t b, float_status *s) | ||
2617 | RVVCALL(OPFVV2, vfsgnjn_vv_h, OP_UUU_H, H2, H2, H2, fsgnjn16) | ||
2618 | RVVCALL(OPFVV2, vfsgnjn_vv_w, OP_UUU_W, H4, H4, H4, fsgnjn32) | ||
2619 | RVVCALL(OPFVV2, vfsgnjn_vv_d, OP_UUU_D, H8, H8, H8, fsgnjn64) | ||
2620 | -GEN_VEXT_VV_ENV(vfsgnjn_vv_h, 2, 2, clearh) | ||
2621 | -GEN_VEXT_VV_ENV(vfsgnjn_vv_w, 4, 4, clearl) | ||
2622 | -GEN_VEXT_VV_ENV(vfsgnjn_vv_d, 8, 8, clearq) | ||
2623 | +GEN_VEXT_VV_ENV(vfsgnjn_vv_h, 2, 2) | ||
2624 | +GEN_VEXT_VV_ENV(vfsgnjn_vv_w, 4, 4) | ||
2625 | +GEN_VEXT_VV_ENV(vfsgnjn_vv_d, 8, 8) | ||
2626 | RVVCALL(OPFVF2, vfsgnjn_vf_h, OP_UUU_H, H2, H2, fsgnjn16) | ||
2627 | RVVCALL(OPFVF2, vfsgnjn_vf_w, OP_UUU_W, H4, H4, fsgnjn32) | ||
2628 | RVVCALL(OPFVF2, vfsgnjn_vf_d, OP_UUU_D, H8, H8, fsgnjn64) | ||
2629 | -GEN_VEXT_VF(vfsgnjn_vf_h, 2, 2, clearh) | ||
2630 | -GEN_VEXT_VF(vfsgnjn_vf_w, 4, 4, clearl) | ||
2631 | -GEN_VEXT_VF(vfsgnjn_vf_d, 8, 8, clearq) | ||
2632 | +GEN_VEXT_VF(vfsgnjn_vf_h, 2, 2) | ||
2633 | +GEN_VEXT_VF(vfsgnjn_vf_w, 4, 4) | ||
2634 | +GEN_VEXT_VF(vfsgnjn_vf_d, 8, 8) | ||
2635 | |||
2636 | static uint16_t fsgnjx16(uint16_t a, uint16_t b, float_status *s) | ||
2637 | { | ||
2638 | @@ -XXX,XX +XXX,XX @@ static uint64_t fsgnjx64(uint64_t a, uint64_t b, float_status *s) | ||
2639 | RVVCALL(OPFVV2, vfsgnjx_vv_h, OP_UUU_H, H2, H2, H2, fsgnjx16) | ||
2640 | RVVCALL(OPFVV2, vfsgnjx_vv_w, OP_UUU_W, H4, H4, H4, fsgnjx32) | ||
2641 | RVVCALL(OPFVV2, vfsgnjx_vv_d, OP_UUU_D, H8, H8, H8, fsgnjx64) | ||
2642 | -GEN_VEXT_VV_ENV(vfsgnjx_vv_h, 2, 2, clearh) | ||
2643 | -GEN_VEXT_VV_ENV(vfsgnjx_vv_w, 4, 4, clearl) | ||
2644 | -GEN_VEXT_VV_ENV(vfsgnjx_vv_d, 8, 8, clearq) | ||
2645 | +GEN_VEXT_VV_ENV(vfsgnjx_vv_h, 2, 2) | ||
2646 | +GEN_VEXT_VV_ENV(vfsgnjx_vv_w, 4, 4) | ||
2647 | +GEN_VEXT_VV_ENV(vfsgnjx_vv_d, 8, 8) | ||
2648 | RVVCALL(OPFVF2, vfsgnjx_vf_h, OP_UUU_H, H2, H2, fsgnjx16) | ||
2649 | RVVCALL(OPFVF2, vfsgnjx_vf_w, OP_UUU_W, H4, H4, fsgnjx32) | ||
2650 | RVVCALL(OPFVF2, vfsgnjx_vf_d, OP_UUU_D, H8, H8, fsgnjx64) | ||
2651 | -GEN_VEXT_VF(vfsgnjx_vf_h, 2, 2, clearh) | ||
2652 | -GEN_VEXT_VF(vfsgnjx_vf_w, 4, 4, clearl) | ||
2653 | -GEN_VEXT_VF(vfsgnjx_vf_d, 8, 8, clearq) | ||
2654 | +GEN_VEXT_VF(vfsgnjx_vf_h, 2, 2) | ||
2655 | +GEN_VEXT_VF(vfsgnjx_vf_w, 4, 4) | ||
2656 | +GEN_VEXT_VF(vfsgnjx_vf_d, 8, 8) | ||
2657 | |||
2658 | /* Vector Floating-Point Compare Instructions */ | ||
2659 | #define GEN_VEXT_CMP_VV_ENV(NAME, ETYPE, H, DO_OP) \ | ||
2660 | @@ -XXX,XX +XXX,XX @@ static void do_##NAME(void *vd, void *vs2, int i) \ | ||
2661 | *((TD *)vd + HD(i)) = OP(s2); \ | ||
2662 | } | ||
2663 | |||
2664 | -#define GEN_VEXT_V(NAME, ESZ, DSZ, CLEAR_FN) \ | ||
2665 | +#define GEN_VEXT_V(NAME, ESZ, DSZ) \ | ||
2666 | void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
2667 | CPURISCVState *env, uint32_t desc) \ | ||
2668 | { \ | ||
2669 | - uint32_t vlmax = vext_maxsz(desc) / ESZ; \ | ||
2670 | uint32_t vm = vext_vm(desc); \ | ||
2671 | uint32_t vl = env->vl; \ | ||
2672 | uint32_t i; \ | ||
2673 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
2674 | } \ | ||
2675 | do_##NAME(vd, vs2, i); \ | ||
2676 | } \ | ||
2677 | - CLEAR_FN(vd, vl, vl * DSZ, vlmax * DSZ); \ | ||
2678 | } | ||
2679 | |||
2680 | target_ulong fclass_h(uint64_t frs1) | ||
2681 | @@ -XXX,XX +XXX,XX @@ target_ulong fclass_d(uint64_t frs1) | ||
2682 | RVVCALL(OPIVV1, vfclass_v_h, OP_UU_H, H2, H2, fclass_h) | ||
2683 | RVVCALL(OPIVV1, vfclass_v_w, OP_UU_W, H4, H4, fclass_s) | ||
2684 | RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d) | ||
2685 | -GEN_VEXT_V(vfclass_v_h, 2, 2, clearh) | ||
2686 | -GEN_VEXT_V(vfclass_v_w, 4, 4, clearl) | ||
2687 | -GEN_VEXT_V(vfclass_v_d, 8, 8, clearq) | ||
2688 | +GEN_VEXT_V(vfclass_v_h, 2, 2) | ||
2689 | +GEN_VEXT_V(vfclass_v_w, 4, 4) | ||
2690 | +GEN_VEXT_V(vfclass_v_d, 8, 8) | ||
2691 | |||
2692 | /* Vector Floating-Point Merge Instruction */ | ||
2693 | -#define GEN_VFMERGE_VF(NAME, ETYPE, H, CLEAR_FN) \ | ||
2694 | +#define GEN_VFMERGE_VF(NAME, ETYPE, H) \ | ||
2695 | void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
2696 | CPURISCVState *env, uint32_t desc) \ | ||
2697 | { \ | ||
2698 | uint32_t vm = vext_vm(desc); \ | ||
2699 | uint32_t vl = env->vl; \ | ||
2700 | - uint32_t esz = sizeof(ETYPE); \ | ||
2701 | - uint32_t vlmax = vext_maxsz(desc) / esz; \ | ||
2702 | uint32_t i; \ | ||
2703 | \ | ||
2704 | for (i = 0; i < vl; i++) { \ | ||
2705 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
2706 | *((ETYPE *)vd + H(i)) \ | ||
2707 | = (!vm && !vext_elem_mask(v0, i) ? s2 : s1); \ | ||
2708 | } \ | ||
2709 | - CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \ | ||
2710 | } | ||
2711 | |||
2712 | -GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2, clearh) | ||
2713 | -GEN_VFMERGE_VF(vfmerge_vfm_w, int32_t, H4, clearl) | ||
2714 | -GEN_VFMERGE_VF(vfmerge_vfm_d, int64_t, H8, clearq) | ||
2715 | +GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2) | ||
2716 | +GEN_VFMERGE_VF(vfmerge_vfm_w, int32_t, H4) | ||
2717 | +GEN_VFMERGE_VF(vfmerge_vfm_d, int64_t, H8) | ||
2718 | |||
2719 | /* Single-Width Floating-Point/Integer Type-Convert Instructions */ | ||
2720 | /* vfcvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */ | ||
2721 | RVVCALL(OPFVV1, vfcvt_xu_f_v_h, OP_UU_H, H2, H2, float16_to_uint16) | ||
2722 | RVVCALL(OPFVV1, vfcvt_xu_f_v_w, OP_UU_W, H4, H4, float32_to_uint32) | ||
2723 | RVVCALL(OPFVV1, vfcvt_xu_f_v_d, OP_UU_D, H8, H8, float64_to_uint64) | ||
2724 | -GEN_VEXT_V_ENV(vfcvt_xu_f_v_h, 2, 2, clearh) | ||
2725 | -GEN_VEXT_V_ENV(vfcvt_xu_f_v_w, 4, 4, clearl) | ||
2726 | -GEN_VEXT_V_ENV(vfcvt_xu_f_v_d, 8, 8, clearq) | ||
2727 | +GEN_VEXT_V_ENV(vfcvt_xu_f_v_h, 2, 2) | ||
2728 | +GEN_VEXT_V_ENV(vfcvt_xu_f_v_w, 4, 4) | ||
2729 | +GEN_VEXT_V_ENV(vfcvt_xu_f_v_d, 8, 8) | ||
2730 | |||
2731 | /* vfcvt.x.f.v vd, vs2, vm # Convert float to signed integer. */ | ||
2732 | RVVCALL(OPFVV1, vfcvt_x_f_v_h, OP_UU_H, H2, H2, float16_to_int16) | ||
2733 | RVVCALL(OPFVV1, vfcvt_x_f_v_w, OP_UU_W, H4, H4, float32_to_int32) | ||
2734 | RVVCALL(OPFVV1, vfcvt_x_f_v_d, OP_UU_D, H8, H8, float64_to_int64) | ||
2735 | -GEN_VEXT_V_ENV(vfcvt_x_f_v_h, 2, 2, clearh) | ||
2736 | -GEN_VEXT_V_ENV(vfcvt_x_f_v_w, 4, 4, clearl) | ||
2737 | -GEN_VEXT_V_ENV(vfcvt_x_f_v_d, 8, 8, clearq) | ||
2738 | +GEN_VEXT_V_ENV(vfcvt_x_f_v_h, 2, 2) | ||
2739 | +GEN_VEXT_V_ENV(vfcvt_x_f_v_w, 4, 4) | ||
2740 | +GEN_VEXT_V_ENV(vfcvt_x_f_v_d, 8, 8) | ||
2741 | |||
2742 | /* vfcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to float. */ | ||
2743 | RVVCALL(OPFVV1, vfcvt_f_xu_v_h, OP_UU_H, H2, H2, uint16_to_float16) | ||
2744 | RVVCALL(OPFVV1, vfcvt_f_xu_v_w, OP_UU_W, H4, H4, uint32_to_float32) | ||
2745 | RVVCALL(OPFVV1, vfcvt_f_xu_v_d, OP_UU_D, H8, H8, uint64_to_float64) | ||
2746 | -GEN_VEXT_V_ENV(vfcvt_f_xu_v_h, 2, 2, clearh) | ||
2747 | -GEN_VEXT_V_ENV(vfcvt_f_xu_v_w, 4, 4, clearl) | ||
2748 | -GEN_VEXT_V_ENV(vfcvt_f_xu_v_d, 8, 8, clearq) | ||
2749 | +GEN_VEXT_V_ENV(vfcvt_f_xu_v_h, 2, 2) | ||
2750 | +GEN_VEXT_V_ENV(vfcvt_f_xu_v_w, 4, 4) | ||
2751 | +GEN_VEXT_V_ENV(vfcvt_f_xu_v_d, 8, 8) | ||
2752 | |||
2753 | /* vfcvt.f.x.v vd, vs2, vm # Convert integer to float. */ | ||
2754 | RVVCALL(OPFVV1, vfcvt_f_x_v_h, OP_UU_H, H2, H2, int16_to_float16) | ||
2755 | RVVCALL(OPFVV1, vfcvt_f_x_v_w, OP_UU_W, H4, H4, int32_to_float32) | ||
2756 | RVVCALL(OPFVV1, vfcvt_f_x_v_d, OP_UU_D, H8, H8, int64_to_float64) | ||
2757 | -GEN_VEXT_V_ENV(vfcvt_f_x_v_h, 2, 2, clearh) | ||
2758 | -GEN_VEXT_V_ENV(vfcvt_f_x_v_w, 4, 4, clearl) | ||
2759 | -GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8, clearq) | ||
2760 | +GEN_VEXT_V_ENV(vfcvt_f_x_v_h, 2, 2) | ||
2761 | +GEN_VEXT_V_ENV(vfcvt_f_x_v_w, 4, 4) | ||
2762 | +GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8) | ||
2763 | |||
2764 | /* Widening Floating-Point/Integer Type-Convert Instructions */ | ||
2765 | /* (TD, T2, TX2) */ | ||
2766 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8, clearq) | ||
2767 | /* vfwcvt.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer.*/ | ||
2768 | RVVCALL(OPFVV1, vfwcvt_xu_f_v_h, WOP_UU_H, H4, H2, float16_to_uint32) | ||
2769 | RVVCALL(OPFVV1, vfwcvt_xu_f_v_w, WOP_UU_W, H8, H4, float32_to_uint64) | ||
2770 | -GEN_VEXT_V_ENV(vfwcvt_xu_f_v_h, 2, 4, clearl) | ||
2771 | -GEN_VEXT_V_ENV(vfwcvt_xu_f_v_w, 4, 8, clearq) | ||
2772 | +GEN_VEXT_V_ENV(vfwcvt_xu_f_v_h, 2, 4) | ||
2773 | +GEN_VEXT_V_ENV(vfwcvt_xu_f_v_w, 4, 8) | ||
2774 | |||
2775 | /* vfwcvt.x.f.v vd, vs2, vm # Convert float to double-width signed integer. */ | ||
2776 | RVVCALL(OPFVV1, vfwcvt_x_f_v_h, WOP_UU_H, H4, H2, float16_to_int32) | ||
2777 | RVVCALL(OPFVV1, vfwcvt_x_f_v_w, WOP_UU_W, H8, H4, float32_to_int64) | ||
2778 | -GEN_VEXT_V_ENV(vfwcvt_x_f_v_h, 2, 4, clearl) | ||
2779 | -GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 4, 8, clearq) | ||
2780 | +GEN_VEXT_V_ENV(vfwcvt_x_f_v_h, 2, 4) | ||
2781 | +GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 4, 8) | ||
2782 | |||
2783 | /* vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float */ | ||
2784 | RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32) | ||
2785 | RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64) | ||
2786 | -GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 2, 4, clearl) | ||
2787 | -GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 4, 8, clearq) | ||
2788 | +GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 2, 4) | ||
2789 | +GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 4, 8) | ||
2790 | |||
2791 | /* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */ | ||
2792 | RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32) | ||
2793 | RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64) | ||
2794 | -GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 2, 4, clearl) | ||
2795 | -GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 4, 8, clearq) | ||
2796 | +GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 2, 4) | ||
2797 | +GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 4, 8) | ||
2798 | |||
2799 | /* | ||
2800 | * vfwcvt.f.f.v vd, vs2, vm # | ||
2801 | @@ -XXX,XX +XXX,XX @@ static uint32_t vfwcvtffv16(uint16_t a, float_status *s) | ||
2802 | |||
2803 | RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, H2, vfwcvtffv16) | ||
2804 | RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64) | ||
2805 | -GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 2, 4, clearl) | ||
2806 | -GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8, clearq) | ||
2807 | +GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 2, 4) | ||
2808 | +GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8) | ||
2809 | |||
2810 | /* Narrowing Floating-Point/Integer Type-Convert Instructions */ | ||
2811 | /* (TD, T2, TX2) */ | ||
2812 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8, clearq) | ||
2813 | /* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */ | ||
2814 | RVVCALL(OPFVV1, vfncvt_xu_f_v_h, NOP_UU_H, H2, H4, float32_to_uint16) | ||
2815 | RVVCALL(OPFVV1, vfncvt_xu_f_v_w, NOP_UU_W, H4, H8, float64_to_uint32) | ||
2816 | -GEN_VEXT_V_ENV(vfncvt_xu_f_v_h, 2, 2, clearh) | ||
2817 | -GEN_VEXT_V_ENV(vfncvt_xu_f_v_w, 4, 4, clearl) | ||
2818 | +GEN_VEXT_V_ENV(vfncvt_xu_f_v_h, 2, 2) | ||
2819 | +GEN_VEXT_V_ENV(vfncvt_xu_f_v_w, 4, 4) | ||
2820 | |||
2821 | /* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */ | ||
2822 | RVVCALL(OPFVV1, vfncvt_x_f_v_h, NOP_UU_H, H2, H4, float32_to_int16) | ||
2823 | RVVCALL(OPFVV1, vfncvt_x_f_v_w, NOP_UU_W, H4, H8, float64_to_int32) | ||
2824 | -GEN_VEXT_V_ENV(vfncvt_x_f_v_h, 2, 2, clearh) | ||
2825 | -GEN_VEXT_V_ENV(vfncvt_x_f_v_w, 4, 4, clearl) | ||
2826 | +GEN_VEXT_V_ENV(vfncvt_x_f_v_h, 2, 2) | ||
2827 | +GEN_VEXT_V_ENV(vfncvt_x_f_v_w, 4, 4) | ||
2828 | |||
2829 | /* vfncvt.f.xu.v vd, vs2, vm # Convert double-width unsigned integer to float */ | ||
2830 | RVVCALL(OPFVV1, vfncvt_f_xu_v_h, NOP_UU_H, H2, H4, uint32_to_float16) | ||
2831 | RVVCALL(OPFVV1, vfncvt_f_xu_v_w, NOP_UU_W, H4, H8, uint64_to_float32) | ||
2832 | -GEN_VEXT_V_ENV(vfncvt_f_xu_v_h, 2, 2, clearh) | ||
2833 | -GEN_VEXT_V_ENV(vfncvt_f_xu_v_w, 4, 4, clearl) | ||
2834 | +GEN_VEXT_V_ENV(vfncvt_f_xu_v_h, 2, 2) | ||
2835 | +GEN_VEXT_V_ENV(vfncvt_f_xu_v_w, 4, 4) | ||
2836 | |||
2837 | /* vfncvt.f.x.v vd, vs2, vm # Convert double-width integer to float. */ | ||
2838 | RVVCALL(OPFVV1, vfncvt_f_x_v_h, NOP_UU_H, H2, H4, int32_to_float16) | ||
2839 | RVVCALL(OPFVV1, vfncvt_f_x_v_w, NOP_UU_W, H4, H8, int64_to_float32) | ||
2840 | -GEN_VEXT_V_ENV(vfncvt_f_x_v_h, 2, 2, clearh) | ||
2841 | -GEN_VEXT_V_ENV(vfncvt_f_x_v_w, 4, 4, clearl) | ||
2842 | +GEN_VEXT_V_ENV(vfncvt_f_x_v_h, 2, 2) | ||
2843 | +GEN_VEXT_V_ENV(vfncvt_f_x_v_w, 4, 4) | ||
2844 | |||
2845 | /* vfncvt.f.f.v vd, vs2, vm # Convert double float to single-width float. */ | ||
2846 | static uint16_t vfncvtffv16(uint32_t a, float_status *s) | ||
2847 | @@ -XXX,XX +XXX,XX @@ static uint16_t vfncvtffv16(uint32_t a, float_status *s) | ||
2848 | |||
2849 | RVVCALL(OPFVV1, vfncvt_f_f_v_h, NOP_UU_H, H2, H4, vfncvtffv16) | ||
2850 | RVVCALL(OPFVV1, vfncvt_f_f_v_w, NOP_UU_W, H4, H8, float64_to_float32) | ||
2851 | -GEN_VEXT_V_ENV(vfncvt_f_f_v_h, 2, 2, clearh) | ||
2852 | -GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4, clearl) | ||
2853 | +GEN_VEXT_V_ENV(vfncvt_f_f_v_h, 2, 2) | ||
2854 | +GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4) | ||
2855 | |||
2856 | /* | ||
2857 | *** Vector Reduction Operations | ||
2858 | */ | ||
2859 | /* Vector Single-Width Integer Reduction Instructions */ | ||
2860 | -#define GEN_VEXT_RED(NAME, TD, TS2, HD, HS2, OP, CLEAR_FN)\ | ||
2861 | +#define GEN_VEXT_RED(NAME, TD, TS2, HD, HS2, OP) \ | ||
2862 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2863 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
2864 | { \ | ||
2865 | uint32_t vm = vext_vm(desc); \ | ||
2866 | uint32_t vl = env->vl; \ | ||
2867 | uint32_t i; \ | ||
2868 | - uint32_t tot = env_archcpu(env)->cfg.vlen / 8; \ | ||
2869 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
2870 | \ | ||
2871 | for (i = 0; i < vl; i++) { \ | ||
2872 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2873 | s1 = OP(s1, (TD)s2); \ | ||
2874 | } \ | ||
2875 | *((TD *)vd + HD(0)) = s1; \ | ||
2876 | - CLEAR_FN(vd, 1, sizeof(TD), tot); \ | ||
2877 | } | ||
2878 | |||
2879 | /* vd[0] = sum(vs1[0], vs2[*]) */ | ||
2880 | -GEN_VEXT_RED(vredsum_vs_b, int8_t, int8_t, H1, H1, DO_ADD, clearb) | ||
2881 | -GEN_VEXT_RED(vredsum_vs_h, int16_t, int16_t, H2, H2, DO_ADD, clearh) | ||
2882 | -GEN_VEXT_RED(vredsum_vs_w, int32_t, int32_t, H4, H4, DO_ADD, clearl) | ||
2883 | -GEN_VEXT_RED(vredsum_vs_d, int64_t, int64_t, H8, H8, DO_ADD, clearq) | ||
2884 | +GEN_VEXT_RED(vredsum_vs_b, int8_t, int8_t, H1, H1, DO_ADD) | ||
2885 | +GEN_VEXT_RED(vredsum_vs_h, int16_t, int16_t, H2, H2, DO_ADD) | ||
2886 | +GEN_VEXT_RED(vredsum_vs_w, int32_t, int32_t, H4, H4, DO_ADD) | ||
2887 | +GEN_VEXT_RED(vredsum_vs_d, int64_t, int64_t, H8, H8, DO_ADD) | ||
2888 | |||
2889 | /* vd[0] = maxu(vs1[0], vs2[*]) */ | ||
2890 | -GEN_VEXT_RED(vredmaxu_vs_b, uint8_t, uint8_t, H1, H1, DO_MAX, clearb) | ||
2891 | -GEN_VEXT_RED(vredmaxu_vs_h, uint16_t, uint16_t, H2, H2, DO_MAX, clearh) | ||
2892 | -GEN_VEXT_RED(vredmaxu_vs_w, uint32_t, uint32_t, H4, H4, DO_MAX, clearl) | ||
2893 | -GEN_VEXT_RED(vredmaxu_vs_d, uint64_t, uint64_t, H8, H8, DO_MAX, clearq) | ||
2894 | +GEN_VEXT_RED(vredmaxu_vs_b, uint8_t, uint8_t, H1, H1, DO_MAX) | ||
2895 | +GEN_VEXT_RED(vredmaxu_vs_h, uint16_t, uint16_t, H2, H2, DO_MAX) | ||
2896 | +GEN_VEXT_RED(vredmaxu_vs_w, uint32_t, uint32_t, H4, H4, DO_MAX) | ||
2897 | +GEN_VEXT_RED(vredmaxu_vs_d, uint64_t, uint64_t, H8, H8, DO_MAX) | ||
2898 | |||
2899 | /* vd[0] = max(vs1[0], vs2[*]) */ | ||
2900 | -GEN_VEXT_RED(vredmax_vs_b, int8_t, int8_t, H1, H1, DO_MAX, clearb) | ||
2901 | -GEN_VEXT_RED(vredmax_vs_h, int16_t, int16_t, H2, H2, DO_MAX, clearh) | ||
2902 | -GEN_VEXT_RED(vredmax_vs_w, int32_t, int32_t, H4, H4, DO_MAX, clearl) | ||
2903 | -GEN_VEXT_RED(vredmax_vs_d, int64_t, int64_t, H8, H8, DO_MAX, clearq) | ||
2904 | +GEN_VEXT_RED(vredmax_vs_b, int8_t, int8_t, H1, H1, DO_MAX) | ||
2905 | +GEN_VEXT_RED(vredmax_vs_h, int16_t, int16_t, H2, H2, DO_MAX) | ||
2906 | +GEN_VEXT_RED(vredmax_vs_w, int32_t, int32_t, H4, H4, DO_MAX) | ||
2907 | +GEN_VEXT_RED(vredmax_vs_d, int64_t, int64_t, H8, H8, DO_MAX) | ||
2908 | |||
2909 | /* vd[0] = minu(vs1[0], vs2[*]) */ | ||
2910 | -GEN_VEXT_RED(vredminu_vs_b, uint8_t, uint8_t, H1, H1, DO_MIN, clearb) | ||
2911 | -GEN_VEXT_RED(vredminu_vs_h, uint16_t, uint16_t, H2, H2, DO_MIN, clearh) | ||
2912 | -GEN_VEXT_RED(vredminu_vs_w, uint32_t, uint32_t, H4, H4, DO_MIN, clearl) | ||
2913 | -GEN_VEXT_RED(vredminu_vs_d, uint64_t, uint64_t, H8, H8, DO_MIN, clearq) | ||
2914 | +GEN_VEXT_RED(vredminu_vs_b, uint8_t, uint8_t, H1, H1, DO_MIN) | ||
2915 | +GEN_VEXT_RED(vredminu_vs_h, uint16_t, uint16_t, H2, H2, DO_MIN) | ||
2916 | +GEN_VEXT_RED(vredminu_vs_w, uint32_t, uint32_t, H4, H4, DO_MIN) | ||
2917 | +GEN_VEXT_RED(vredminu_vs_d, uint64_t, uint64_t, H8, H8, DO_MIN) | ||
2918 | |||
2919 | /* vd[0] = min(vs1[0], vs2[*]) */ | ||
2920 | -GEN_VEXT_RED(vredmin_vs_b, int8_t, int8_t, H1, H1, DO_MIN, clearb) | ||
2921 | -GEN_VEXT_RED(vredmin_vs_h, int16_t, int16_t, H2, H2, DO_MIN, clearh) | ||
2922 | -GEN_VEXT_RED(vredmin_vs_w, int32_t, int32_t, H4, H4, DO_MIN, clearl) | ||
2923 | -GEN_VEXT_RED(vredmin_vs_d, int64_t, int64_t, H8, H8, DO_MIN, clearq) | ||
2924 | +GEN_VEXT_RED(vredmin_vs_b, int8_t, int8_t, H1, H1, DO_MIN) | ||
2925 | +GEN_VEXT_RED(vredmin_vs_h, int16_t, int16_t, H2, H2, DO_MIN) | ||
2926 | +GEN_VEXT_RED(vredmin_vs_w, int32_t, int32_t, H4, H4, DO_MIN) | ||
2927 | +GEN_VEXT_RED(vredmin_vs_d, int64_t, int64_t, H8, H8, DO_MIN) | ||
2928 | |||
2929 | /* vd[0] = and(vs1[0], vs2[*]) */ | ||
2930 | -GEN_VEXT_RED(vredand_vs_b, int8_t, int8_t, H1, H1, DO_AND, clearb) | ||
2931 | -GEN_VEXT_RED(vredand_vs_h, int16_t, int16_t, H2, H2, DO_AND, clearh) | ||
2932 | -GEN_VEXT_RED(vredand_vs_w, int32_t, int32_t, H4, H4, DO_AND, clearl) | ||
2933 | -GEN_VEXT_RED(vredand_vs_d, int64_t, int64_t, H8, H8, DO_AND, clearq) | ||
2934 | +GEN_VEXT_RED(vredand_vs_b, int8_t, int8_t, H1, H1, DO_AND) | ||
2935 | +GEN_VEXT_RED(vredand_vs_h, int16_t, int16_t, H2, H2, DO_AND) | ||
2936 | +GEN_VEXT_RED(vredand_vs_w, int32_t, int32_t, H4, H4, DO_AND) | ||
2937 | +GEN_VEXT_RED(vredand_vs_d, int64_t, int64_t, H8, H8, DO_AND) | ||
2938 | |||
2939 | /* vd[0] = or(vs1[0], vs2[*]) */ | ||
2940 | -GEN_VEXT_RED(vredor_vs_b, int8_t, int8_t, H1, H1, DO_OR, clearb) | ||
2941 | -GEN_VEXT_RED(vredor_vs_h, int16_t, int16_t, H2, H2, DO_OR, clearh) | ||
2942 | -GEN_VEXT_RED(vredor_vs_w, int32_t, int32_t, H4, H4, DO_OR, clearl) | ||
2943 | -GEN_VEXT_RED(vredor_vs_d, int64_t, int64_t, H8, H8, DO_OR, clearq) | ||
2944 | +GEN_VEXT_RED(vredor_vs_b, int8_t, int8_t, H1, H1, DO_OR) | ||
2945 | +GEN_VEXT_RED(vredor_vs_h, int16_t, int16_t, H2, H2, DO_OR) | ||
2946 | +GEN_VEXT_RED(vredor_vs_w, int32_t, int32_t, H4, H4, DO_OR) | ||
2947 | +GEN_VEXT_RED(vredor_vs_d, int64_t, int64_t, H8, H8, DO_OR) | ||
2948 | |||
2949 | /* vd[0] = xor(vs1[0], vs2[*]) */ | ||
2950 | -GEN_VEXT_RED(vredxor_vs_b, int8_t, int8_t, H1, H1, DO_XOR, clearb) | ||
2951 | -GEN_VEXT_RED(vredxor_vs_h, int16_t, int16_t, H2, H2, DO_XOR, clearh) | ||
2952 | -GEN_VEXT_RED(vredxor_vs_w, int32_t, int32_t, H4, H4, DO_XOR, clearl) | ||
2953 | -GEN_VEXT_RED(vredxor_vs_d, int64_t, int64_t, H8, H8, DO_XOR, clearq) | ||
2954 | +GEN_VEXT_RED(vredxor_vs_b, int8_t, int8_t, H1, H1, DO_XOR) | ||
2955 | +GEN_VEXT_RED(vredxor_vs_h, int16_t, int16_t, H2, H2, DO_XOR) | ||
2956 | +GEN_VEXT_RED(vredxor_vs_w, int32_t, int32_t, H4, H4, DO_XOR) | ||
2957 | +GEN_VEXT_RED(vredxor_vs_d, int64_t, int64_t, H8, H8, DO_XOR) | ||
2958 | |||
2959 | /* Vector Widening Integer Reduction Instructions */ | ||
2960 | /* signed sum reduction into double-width accumulator */ | ||
2961 | -GEN_VEXT_RED(vwredsum_vs_b, int16_t, int8_t, H2, H1, DO_ADD, clearh) | ||
2962 | -GEN_VEXT_RED(vwredsum_vs_h, int32_t, int16_t, H4, H2, DO_ADD, clearl) | ||
2963 | -GEN_VEXT_RED(vwredsum_vs_w, int64_t, int32_t, H8, H4, DO_ADD, clearq) | ||
2964 | +GEN_VEXT_RED(vwredsum_vs_b, int16_t, int8_t, H2, H1, DO_ADD) | ||
2965 | +GEN_VEXT_RED(vwredsum_vs_h, int32_t, int16_t, H4, H2, DO_ADD) | ||
2966 | +GEN_VEXT_RED(vwredsum_vs_w, int64_t, int32_t, H8, H4, DO_ADD) | ||
2967 | |||
2968 | /* Unsigned sum reduction into double-width accumulator */ | ||
2969 | -GEN_VEXT_RED(vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, DO_ADD, clearh) | ||
2970 | -GEN_VEXT_RED(vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, DO_ADD, clearl) | ||
2971 | -GEN_VEXT_RED(vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, DO_ADD, clearq) | ||
2972 | +GEN_VEXT_RED(vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, DO_ADD) | ||
2973 | +GEN_VEXT_RED(vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, DO_ADD) | ||
2974 | +GEN_VEXT_RED(vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, DO_ADD) | ||
2975 | |||
2976 | /* Vector Single-Width Floating-Point Reduction Instructions */ | ||
2977 | -#define GEN_VEXT_FRED(NAME, TD, TS2, HD, HS2, OP, CLEAR_FN)\ | ||
2978 | +#define GEN_VEXT_FRED(NAME, TD, TS2, HD, HS2, OP) \ | ||
2979 | void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2980 | void *vs2, CPURISCVState *env, \ | ||
2981 | uint32_t desc) \ | ||
2982 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2983 | uint32_t vm = vext_vm(desc); \ | ||
2984 | uint32_t vl = env->vl; \ | ||
2985 | uint32_t i; \ | ||
2986 | - uint32_t tot = env_archcpu(env)->cfg.vlen / 8; \ | ||
2987 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
2988 | \ | ||
2989 | for (i = 0; i < vl; i++) { \ | ||
2990 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
2991 | s1 = OP(s1, (TD)s2, &env->fp_status); \ | ||
2992 | } \ | ||
2993 | *((TD *)vd + HD(0)) = s1; \ | ||
2994 | - CLEAR_FN(vd, 1, sizeof(TD), tot); \ | ||
2995 | } | ||
2996 | |||
2997 | /* Unordered sum */ | ||
2998 | -GEN_VEXT_FRED(vfredsum_vs_h, uint16_t, uint16_t, H2, H2, float16_add, clearh) | ||
2999 | -GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, float32_add, clearl) | ||
3000 | -GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add, clearq) | ||
3001 | +GEN_VEXT_FRED(vfredsum_vs_h, uint16_t, uint16_t, H2, H2, float16_add) | ||
3002 | +GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, float32_add) | ||
3003 | +GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add) | ||
3004 | |||
3005 | /* Maximum value */ | ||
3006 | -GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum, clearh) | ||
3007 | -GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum, clearl) | ||
3008 | -GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum, clearq) | ||
3009 | +GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum) | ||
3010 | +GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum) | ||
3011 | +GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum) | ||
3012 | |||
3013 | /* Minimum value */ | ||
3014 | -GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum, clearh) | ||
3015 | -GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum, clearl) | ||
3016 | -GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum, clearq) | ||
3017 | +GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum) | ||
3018 | +GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum) | ||
3019 | +GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum) | ||
3020 | |||
3021 | /* Vector Widening Floating-Point Reduction Instructions */ | ||
3022 | /* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */ | ||
3023 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
3024 | uint32_t vm = vext_vm(desc); | ||
3025 | uint32_t vl = env->vl; | ||
3026 | uint32_t i; | ||
3027 | - uint32_t tot = env_archcpu(env)->cfg.vlen / 8; | ||
3028 | uint32_t s1 = *((uint32_t *)vs1 + H4(0)); | ||
3029 | |||
3030 | for (i = 0; i < vl; i++) { | ||
3031 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
3032 | &env->fp_status); | ||
3033 | } | ||
3034 | *((uint32_t *)vd + H4(0)) = s1; | ||
3035 | - clearl(vd, 1, sizeof(uint32_t), tot); | ||
3036 | } | ||
3037 | |||
3038 | void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
3039 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
3040 | uint32_t vm = vext_vm(desc); | ||
3041 | uint32_t vl = env->vl; | ||
3042 | uint32_t i; | ||
3043 | - uint32_t tot = env_archcpu(env)->cfg.vlen / 8; | ||
3044 | uint64_t s1 = *((uint64_t *)vs1); | ||
3045 | |||
3046 | for (i = 0; i < vl; i++) { | ||
3047 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
3048 | &env->fp_status); | ||
3049 | } | ||
3050 | *((uint64_t *)vd) = s1; | ||
3051 | - clearq(vd, 1, sizeof(uint64_t), tot); | ||
3052 | } | ||
3053 | |||
3054 | /* | ||
3055 | @@ -XXX,XX +XXX,XX @@ void HELPER(vmsof_m)(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
3056 | } | ||
3057 | |||
3058 | /* Vector Iota Instruction */ | ||
3059 | -#define GEN_VEXT_VIOTA_M(NAME, ETYPE, H, CLEAR_FN) \ | ||
3060 | +#define GEN_VEXT_VIOTA_M(NAME, ETYPE, H) \ | ||
3061 | void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
3062 | uint32_t desc) \ | ||
3063 | { \ | ||
3064 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3065 | uint32_t vm = vext_vm(desc); \ | ||
3066 | uint32_t vl = env->vl; \ | ||
3067 | uint32_t sum = 0; \ | ||
3068 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
3069 | sum++; \ | ||
3070 | } \ | ||
3071 | } \ | ||
3072 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3073 | } | ||
3074 | |||
3075 | -GEN_VEXT_VIOTA_M(viota_m_b, uint8_t, H1, clearb) | ||
3076 | -GEN_VEXT_VIOTA_M(viota_m_h, uint16_t, H2, clearh) | ||
3077 | -GEN_VEXT_VIOTA_M(viota_m_w, uint32_t, H4, clearl) | ||
3078 | -GEN_VEXT_VIOTA_M(viota_m_d, uint64_t, H8, clearq) | ||
3079 | +GEN_VEXT_VIOTA_M(viota_m_b, uint8_t, H1) | ||
3080 | +GEN_VEXT_VIOTA_M(viota_m_h, uint16_t, H2) | ||
3081 | +GEN_VEXT_VIOTA_M(viota_m_w, uint32_t, H4) | ||
3082 | +GEN_VEXT_VIOTA_M(viota_m_d, uint64_t, H8) | ||
3083 | |||
3084 | /* Vector Element Index Instruction */ | ||
3085 | -#define GEN_VEXT_VID_V(NAME, ETYPE, H, CLEAR_FN) \ | ||
3086 | +#define GEN_VEXT_VID_V(NAME, ETYPE, H) \ | ||
3087 | void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
3088 | { \ | ||
3089 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3090 | uint32_t vm = vext_vm(desc); \ | ||
3091 | uint32_t vl = env->vl; \ | ||
3092 | int i; \ | ||
3093 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
3094 | } \ | ||
3095 | *((ETYPE *)vd + H(i)) = i; \ | ||
3096 | } \ | ||
3097 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3098 | } | ||
3099 | |||
3100 | -GEN_VEXT_VID_V(vid_v_b, uint8_t, H1, clearb) | ||
3101 | -GEN_VEXT_VID_V(vid_v_h, uint16_t, H2, clearh) | ||
3102 | -GEN_VEXT_VID_V(vid_v_w, uint32_t, H4, clearl) | ||
3103 | -GEN_VEXT_VID_V(vid_v_d, uint64_t, H8, clearq) | ||
3104 | +GEN_VEXT_VID_V(vid_v_b, uint8_t, H1) | ||
3105 | +GEN_VEXT_VID_V(vid_v_h, uint16_t, H2) | ||
3106 | +GEN_VEXT_VID_V(vid_v_w, uint32_t, H4) | ||
3107 | +GEN_VEXT_VID_V(vid_v_d, uint64_t, H8) | ||
3108 | |||
3109 | /* | ||
3110 | *** Vector Permutation Instructions | ||
3111 | */ | ||
3112 | |||
3113 | /* Vector Slide Instructions */ | ||
3114 | -#define GEN_VEXT_VSLIDEUP_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
3115 | +#define GEN_VEXT_VSLIDEUP_VX(NAME, ETYPE, H) \ | ||
3116 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3117 | CPURISCVState *env, uint32_t desc) \ | ||
3118 | { \ | ||
3119 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3120 | uint32_t vm = vext_vm(desc); \ | ||
3121 | uint32_t vl = env->vl; \ | ||
3122 | target_ulong offset = s1, i; \ | ||
3123 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3124 | } \ | ||
3125 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \ | ||
3126 | } \ | ||
3127 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3128 | } | ||
3129 | |||
3130 | /* vslideup.vx vd, vs2, rs1, vm # vd[i+rs1] = vs2[i] */ | ||
3131 | -GEN_VEXT_VSLIDEUP_VX(vslideup_vx_b, uint8_t, H1, clearb) | ||
3132 | -GEN_VEXT_VSLIDEUP_VX(vslideup_vx_h, uint16_t, H2, clearh) | ||
3133 | -GEN_VEXT_VSLIDEUP_VX(vslideup_vx_w, uint32_t, H4, clearl) | ||
3134 | -GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8, clearq) | ||
3135 | +GEN_VEXT_VSLIDEUP_VX(vslideup_vx_b, uint8_t, H1) | ||
3136 | +GEN_VEXT_VSLIDEUP_VX(vslideup_vx_h, uint16_t, H2) | ||
3137 | +GEN_VEXT_VSLIDEUP_VX(vslideup_vx_w, uint32_t, H4) | ||
3138 | +GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8) | ||
3139 | |||
3140 | -#define GEN_VEXT_VSLIDEDOWN_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
3141 | +#define GEN_VEXT_VSLIDEDOWN_VX(NAME, ETYPE, H) \ | ||
3142 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3143 | CPURISCVState *env, uint32_t desc) \ | ||
3144 | { \ | ||
3145 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3146 | } \ | ||
3147 | *((ETYPE *)vd + H(i)) = j >= vlmax ? 0 : *((ETYPE *)vs2 + H(j)); \ | ||
3148 | } \ | ||
3149 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3150 | } | ||
3151 | |||
3152 | /* vslidedown.vx vd, vs2, rs1, vm # vd[i] = vs2[i+rs1] */ | ||
3153 | -GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_b, uint8_t, H1, clearb) | ||
3154 | -GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2, clearh) | ||
3155 | -GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4, clearl) | ||
3156 | -GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8, clearq) | ||
3157 | +GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_b, uint8_t, H1) | ||
3158 | +GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2) | ||
3159 | +GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4) | ||
3160 | +GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8) | ||
3161 | |||
3162 | -#define GEN_VEXT_VSLIDE1UP_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
3163 | +#define GEN_VEXT_VSLIDE1UP_VX(NAME, ETYPE, H) \ | ||
3164 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3165 | CPURISCVState *env, uint32_t desc) \ | ||
3166 | { \ | ||
3167 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3168 | uint32_t vm = vext_vm(desc); \ | ||
3169 | uint32_t vl = env->vl; \ | ||
3170 | uint32_t i; \ | ||
3171 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3172 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1)); \ | ||
3173 | } \ | ||
3174 | } \ | ||
3175 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3176 | } | ||
3177 | |||
3178 | /* vslide1up.vx vd, vs2, rs1, vm # vd[0]=x[rs1], vd[i+1] = vs2[i] */ | ||
3179 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_b, uint8_t, H1, clearb) | ||
3180 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_h, uint16_t, H2, clearh) | ||
3181 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, uint32_t, H4, clearl) | ||
3182 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, uint64_t, H8, clearq) | ||
3183 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_b, uint8_t, H1) | ||
3184 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_h, uint16_t, H2) | ||
3185 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, uint32_t, H4) | ||
3186 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, uint64_t, H8) | ||
3187 | |||
3188 | -#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
3189 | +#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, ETYPE, H) \ | ||
3190 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3191 | CPURISCVState *env, uint32_t desc) \ | ||
3192 | { \ | ||
3193 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3194 | uint32_t vm = vext_vm(desc); \ | ||
3195 | uint32_t vl = env->vl; \ | ||
3196 | uint32_t i; \ | ||
3197 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3198 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1)); \ | ||
3199 | } \ | ||
3200 | } \ | ||
3201 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3202 | } | ||
3203 | |||
3204 | /* vslide1down.vx vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=x[rs1] */ | ||
3205 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_b, uint8_t, H1, clearb) | ||
3206 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_h, uint16_t, H2, clearh) | ||
3207 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4, clearl) | ||
3208 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8, clearq) | ||
3209 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_b, uint8_t, H1) | ||
3210 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_h, uint16_t, H2) | ||
3211 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4) | ||
3212 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) | ||
3213 | |||
3214 | /* Vector Register Gather Instruction */ | ||
3215 | -#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H, CLEAR_FN) \ | ||
3216 | +#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H) \ | ||
3217 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
3218 | CPURISCVState *env, uint32_t desc) \ | ||
3219 | { \ | ||
3220 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
3221 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ | ||
3222 | } \ | ||
3223 | } \ | ||
3224 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3225 | } | ||
3226 | |||
3227 | /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */ | ||
3228 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, H1, clearb) | ||
3229 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, H2, clearh) | ||
3230 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, H4, clearl) | ||
3231 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8, clearq) | ||
3232 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, H1) | ||
3233 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, H2) | ||
3234 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, H4) | ||
3235 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8) | ||
3236 | |||
3237 | -#define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H, CLEAR_FN) \ | ||
3238 | +#define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H) \ | ||
3239 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3240 | CPURISCVState *env, uint32_t desc) \ | ||
3241 | { \ | ||
3242 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
3243 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ | ||
3244 | } \ | ||
3245 | } \ | ||
3246 | - CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3247 | } | ||
3248 | |||
3249 | /* vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[rs1] */ | ||
3250 | -GEN_VEXT_VRGATHER_VX(vrgather_vx_b, uint8_t, H1, clearb) | ||
3251 | -GEN_VEXT_VRGATHER_VX(vrgather_vx_h, uint16_t, H2, clearh) | ||
3252 | -GEN_VEXT_VRGATHER_VX(vrgather_vx_w, uint32_t, H4, clearl) | ||
3253 | -GEN_VEXT_VRGATHER_VX(vrgather_vx_d, uint64_t, H8, clearq) | ||
3254 | +GEN_VEXT_VRGATHER_VX(vrgather_vx_b, uint8_t, H1) | ||
3255 | +GEN_VEXT_VRGATHER_VX(vrgather_vx_h, uint16_t, H2) | ||
3256 | +GEN_VEXT_VRGATHER_VX(vrgather_vx_w, uint32_t, H4) | ||
3257 | +GEN_VEXT_VRGATHER_VX(vrgather_vx_d, uint64_t, H8) | ||
3258 | |||
3259 | /* Vector Compress Instruction */ | ||
3260 | -#define GEN_VEXT_VCOMPRESS_VM(NAME, ETYPE, H, CLEAR_FN) \ | ||
3261 | +#define GEN_VEXT_VCOMPRESS_VM(NAME, ETYPE, H) \ | ||
3262 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
3263 | CPURISCVState *env, uint32_t desc) \ | ||
3264 | { \ | ||
3265 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
3266 | uint32_t vl = env->vl; \ | ||
3267 | uint32_t num = 0, i; \ | ||
3268 | \ | ||
3269 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
3270 | *((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i)); \ | ||
3271 | num++; \ | ||
3272 | } \ | ||
3273 | - CLEAR_FN(vd, num, num * sizeof(ETYPE), vlmax * sizeof(ETYPE)); \ | ||
3274 | } | ||
3275 | |||
3276 | /* Compress into vd elements of vs2 where vs1 is enabled */ | ||
3277 | -GEN_VEXT_VCOMPRESS_VM(vcompress_vm_b, uint8_t, H1, clearb) | ||
3278 | -GEN_VEXT_VCOMPRESS_VM(vcompress_vm_h, uint16_t, H2, clearh) | ||
3279 | -GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4, clearl) | ||
3280 | -GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8, clearq) | ||
3281 | +GEN_VEXT_VCOMPRESS_VM(vcompress_vm_b, uint8_t, H1) | ||
3282 | +GEN_VEXT_VCOMPRESS_VM(vcompress_vm_h, uint16_t, H2) | ||
3283 | +GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4) | ||
3284 | +GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8) | ||
3285 | -- | ||
3286 | 2.31.1 | ||
3287 | |||
3288 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Update check functions with RVV 1.0 rules. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-16-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 715 +++++++++++++++++------- | ||
11 | 1 file changed, 507 insertions(+), 208 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
17 | @@ -XXX,XX +XXX,XX @@ | ||
18 | #include "tcg/tcg-gvec-desc.h" | ||
19 | #include "internals.h" | ||
20 | |||
21 | +static inline bool is_overlapped(const int8_t astart, int8_t asize, | ||
22 | + const int8_t bstart, int8_t bsize) | ||
23 | +{ | ||
24 | + const int8_t aend = astart + asize; | ||
25 | + const int8_t bend = bstart + bsize; | ||
26 | + | ||
27 | + return MAX(aend, bend) - MIN(astart, bstart) < asize + bsize; | ||
28 | +} | ||
29 | + | ||
30 | +static bool require_rvv(DisasContext *s) | ||
31 | +{ | ||
32 | + return s->mstatus_vs != 0; | ||
33 | +} | ||
34 | + | ||
35 | +static bool require_rvf(DisasContext *s) | ||
36 | +{ | ||
37 | + if (s->mstatus_fs == 0) { | ||
38 | + return false; | ||
39 | + } | ||
40 | + | ||
41 | + switch (s->sew) { | ||
42 | + case MO_16: | ||
43 | + case MO_32: | ||
44 | + return has_ext(s, RVF); | ||
45 | + case MO_64: | ||
46 | + return has_ext(s, RVD); | ||
47 | + default: | ||
48 | + return false; | ||
49 | + } | ||
50 | +} | ||
51 | + | ||
52 | +static bool require_scale_rvf(DisasContext *s) | ||
53 | +{ | ||
54 | + if (s->mstatus_fs == 0) { | ||
55 | + return false; | ||
56 | + } | ||
57 | + | ||
58 | + switch (s->sew) { | ||
59 | + case MO_8: | ||
60 | + case MO_16: | ||
61 | + return has_ext(s, RVF); | ||
62 | + case MO_32: | ||
63 | + return has_ext(s, RVD); | ||
64 | + default: | ||
65 | + return false; | ||
66 | + } | ||
67 | +} | ||
68 | + | ||
69 | +/* Destination vector register group cannot overlap source mask register. */ | ||
70 | +static bool require_vm(int vm, int vd) | ||
71 | +{ | ||
72 | + return (vm != 0 || vd != 0); | ||
73 | +} | ||
74 | + | ||
75 | +/* | ||
76 | + * Vector register should aligned with the passed-in LMUL (EMUL). | ||
77 | + * If LMUL < 0, i.e. fractional LMUL, any vector register is allowed. | ||
78 | + */ | ||
79 | +static bool require_align(const int8_t val, const int8_t lmul) | ||
80 | +{ | ||
81 | + return lmul <= 0 || extract32(val, 0, lmul) == 0; | ||
82 | +} | ||
83 | + | ||
84 | +/* | ||
85 | + * A destination vector register group can overlap a source vector | ||
86 | + * register group only if one of the following holds: | ||
87 | + * 1. The destination EEW equals the source EEW. | ||
88 | + * 2. The destination EEW is smaller than the source EEW and the overlap | ||
89 | + * is in the lowest-numbered part of the source register group. | ||
90 | + * 3. The destination EEW is greater than the source EEW, the source EMUL | ||
91 | + * is at least 1, and the overlap is in the highest-numbered part of | ||
92 | + * the destination register group. | ||
93 | + * (Section 5.2) | ||
94 | + * | ||
95 | + * This function returns true if one of the following holds: | ||
96 | + * * Destination vector register group does not overlap a source vector | ||
97 | + * register group. | ||
98 | + * * Rule 3 met. | ||
99 | + * For rule 1, overlap is allowed so this function doesn't need to be called. | ||
100 | + * For rule 2, (vd == vs). Caller has to check whether: (vd != vs) before | ||
101 | + * calling this function. | ||
102 | + */ | ||
103 | +static bool require_noover(const int8_t dst, const int8_t dst_lmul, | ||
104 | + const int8_t src, const int8_t src_lmul) | ||
105 | +{ | ||
106 | + int8_t dst_size = dst_lmul <= 0 ? 1 : 1 << dst_lmul; | ||
107 | + int8_t src_size = src_lmul <= 0 ? 1 : 1 << src_lmul; | ||
108 | + | ||
109 | + /* Destination EEW is greater than the source EEW, check rule 3. */ | ||
110 | + if (dst_size > src_size) { | ||
111 | + if (dst < src && | ||
112 | + src_lmul >= 0 && | ||
113 | + is_overlapped(dst, dst_size, src, src_size) && | ||
114 | + !is_overlapped(dst, dst_size, src + src_size, src_size)) { | ||
115 | + return true; | ||
116 | + } | ||
117 | + } | ||
118 | + | ||
119 | + return !is_overlapped(dst, dst_size, src, src_size); | ||
120 | +} | ||
121 | + | ||
122 | static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a) | ||
123 | { | ||
124 | TCGv s1, s2, dst; | ||
125 | |||
126 | - if (!has_ext(ctx, RVV)) { | ||
127 | + if (!require_rvv(ctx) || !has_ext(ctx, RVV)) { | ||
128 | return false; | ||
129 | } | ||
130 | |||
131 | @@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a) | ||
132 | { | ||
133 | TCGv s1, s2, dst; | ||
134 | |||
135 | - if (!has_ext(ctx, RVV)) { | ||
136 | + if (!require_rvv(ctx) || !has_ext(ctx, RVV)) { | ||
137 | return false; | ||
138 | } | ||
139 | |||
140 | @@ -XXX,XX +XXX,XX @@ static uint32_t vreg_ofs(DisasContext *s, int reg) | ||
141 | |||
142 | /* check functions */ | ||
143 | |||
144 | +static bool vext_check_ss(DisasContext *s, int vd, int vs, int vm) | ||
145 | +{ | ||
146 | + return require_vm(vm, vd) && | ||
147 | + require_align(vd, s->lmul) && | ||
148 | + require_align(vs, s->lmul); | ||
149 | +} | ||
150 | + | ||
151 | +/* | ||
152 | + * Check function for vector instruction with format: | ||
153 | + * single-width result and single-width sources (SEW = SEW op SEW) | ||
154 | + * | ||
155 | + * Rules to be checked here: | ||
156 | + * 1. Destination vector register group for a masked vector | ||
157 | + * instruction cannot overlap the source mask register (v0). | ||
158 | + * (Section 5.3) | ||
159 | + * 2. Destination vector register number is multiples of LMUL. | ||
160 | + * (Section 3.4.2) | ||
161 | + * 3. Source (vs2, vs1) vector register number are multiples of LMUL. | ||
162 | + * (Section 3.4.2) | ||
163 | + */ | ||
164 | +static bool vext_check_sss(DisasContext *s, int vd, int vs1, int vs2, int vm) | ||
165 | +{ | ||
166 | + return vext_check_ss(s, vd, vs2, vm) && | ||
167 | + require_align(vs1, s->lmul); | ||
168 | +} | ||
169 | + | ||
170 | +static bool vext_check_ms(DisasContext *s, int vd, int vs) | ||
171 | +{ | ||
172 | + bool ret = require_align(vs, s->lmul); | ||
173 | + if (vd != vs) { | ||
174 | + ret &= require_noover(vd, 0, vs, s->lmul); | ||
175 | + } | ||
176 | + return ret; | ||
177 | +} | ||
178 | + | ||
179 | +/* | ||
180 | + * Check function for maskable vector instruction with format: | ||
181 | + * single-width result and single-width sources (SEW = SEW op SEW) | ||
182 | + * | ||
183 | + * Rules to be checked here: | ||
184 | + * 1. Source (vs2, vs1) vector register number are multiples of LMUL. | ||
185 | + * (Section 3.4.2) | ||
186 | + * 2. Destination vector register cannot overlap a source vector | ||
187 | + * register (vs2, vs1) group. | ||
188 | + * (Section 5.2) | ||
189 | + * 3. The destination vector register group for a masked vector | ||
190 | + * instruction cannot overlap the source mask register (v0), | ||
191 | + * unless the destination vector register is being written | ||
192 | + * with a mask value (e.g., comparisons) or the scalar result | ||
193 | + * of a reduction. (Section 5.3) | ||
194 | + */ | ||
195 | +static bool vext_check_mss(DisasContext *s, int vd, int vs1, int vs2) | ||
196 | +{ | ||
197 | + bool ret = vext_check_ms(s, vd, vs2) && | ||
198 | + require_align(vs1, s->lmul); | ||
199 | + if (vd != vs1) { | ||
200 | + ret &= require_noover(vd, 0, vs1, s->lmul); | ||
201 | + } | ||
202 | + return ret; | ||
203 | +} | ||
204 | + | ||
205 | +/* | ||
206 | + * Common check function for vector widening instructions | ||
207 | + * of double-width result (2*SEW). | ||
208 | + * | ||
209 | + * Rules to be checked here: | ||
210 | + * 1. The largest vector register group used by an instruction | ||
211 | + * can not be greater than 8 vector registers (Section 5.2): | ||
212 | + * => LMUL < 8. | ||
213 | + * => SEW < 64. | ||
214 | + * 2. Destination vector register number is multiples of 2 * LMUL. | ||
215 | + * (Section 3.4.2) | ||
216 | + * 3. Destination vector register group for a masked vector | ||
217 | + * instruction cannot overlap the source mask register (v0). | ||
218 | + * (Section 5.3) | ||
219 | + */ | ||
220 | +static bool vext_wide_check_common(DisasContext *s, int vd, int vm) | ||
221 | +{ | ||
222 | + return (s->lmul <= 2) && | ||
223 | + (s->sew < MO_64) && | ||
224 | + require_align(vd, s->lmul + 1) && | ||
225 | + require_vm(vm, vd); | ||
226 | +} | ||
227 | + | ||
228 | +/* | ||
229 | + * Common check function for vector narrowing instructions | ||
230 | + * of single-width result (SEW) and double-width source (2*SEW). | ||
231 | + * | ||
232 | + * Rules to be checked here: | ||
233 | + * 1. The largest vector register group used by an instruction | ||
234 | + * can not be greater than 8 vector registers (Section 5.2): | ||
235 | + * => LMUL < 8. | ||
236 | + * => SEW < 64. | ||
237 | + * 2. Source vector register number is multiples of 2 * LMUL. | ||
238 | + * (Section 3.4.2) | ||
239 | + * 3. Destination vector register number is multiples of LMUL. | ||
240 | + * (Section 3.4.2) | ||
241 | + * 4. Destination vector register group for a masked vector | ||
242 | + * instruction cannot overlap the source mask register (v0). | ||
243 | + * (Section 5.3) | ||
244 | + */ | ||
245 | +static bool vext_narrow_check_common(DisasContext *s, int vd, int vs2, | ||
246 | + int vm) | ||
247 | +{ | ||
248 | + return (s->lmul <= 2) && | ||
249 | + (s->sew < MO_64) && | ||
250 | + require_align(vs2, s->lmul + 1) && | ||
251 | + require_align(vd, s->lmul) && | ||
252 | + require_vm(vm, vd); | ||
253 | +} | ||
254 | + | ||
255 | +static bool vext_check_ds(DisasContext *s, int vd, int vs, int vm) | ||
256 | +{ | ||
257 | + return vext_wide_check_common(s, vd, vm) && | ||
258 | + require_align(vs, s->lmul) && | ||
259 | + require_noover(vd, s->lmul + 1, vs, s->lmul); | ||
260 | +} | ||
261 | + | ||
262 | +static bool vext_check_dd(DisasContext *s, int vd, int vs, int vm) | ||
263 | +{ | ||
264 | + return vext_wide_check_common(s, vd, vm) && | ||
265 | + require_align(vs, s->lmul + 1); | ||
266 | +} | ||
267 | + | ||
268 | +/* | ||
269 | + * Check function for vector instruction with format: | ||
270 | + * double-width result and single-width sources (2*SEW = SEW op SEW) | ||
271 | + * | ||
272 | + * Rules to be checked here: | ||
273 | + * 1. All rules in defined in widen common rules are applied. | ||
274 | + * 2. Source (vs2, vs1) vector register number are multiples of LMUL. | ||
275 | + * (Section 3.4.2) | ||
276 | + * 3. Destination vector register cannot overlap a source vector | ||
277 | + * register (vs2, vs1) group. | ||
278 | + * (Section 5.2) | ||
279 | + */ | ||
280 | +static bool vext_check_dss(DisasContext *s, int vd, int vs1, int vs2, int vm) | ||
281 | +{ | ||
282 | + return vext_check_ds(s, vd, vs2, vm) && | ||
283 | + require_align(vs1, s->lmul) && | ||
284 | + require_noover(vd, s->lmul + 1, vs1, s->lmul); | ||
285 | +} | ||
286 | + | ||
287 | +/* | ||
288 | + * Check function for vector instruction with format: | ||
289 | + * double-width result and double-width source1 and single-width | ||
290 | + * source2 (2*SEW = 2*SEW op SEW) | ||
291 | + * | ||
292 | + * Rules to be checked here: | ||
293 | + * 1. All rules in defined in widen common rules are applied. | ||
294 | + * 2. Source 1 (vs2) vector register number is multiples of 2 * LMUL. | ||
295 | + * (Section 3.4.2) | ||
296 | + * 3. Source 2 (vs1) vector register number is multiples of LMUL. | ||
297 | + * (Section 3.4.2) | ||
298 | + * 4. Destination vector register cannot overlap a source vector | ||
299 | + * register (vs1) group. | ||
300 | + * (Section 5.2) | ||
301 | + */ | ||
302 | +static bool vext_check_dds(DisasContext *s, int vd, int vs1, int vs2, int vm) | ||
303 | +{ | ||
304 | + return vext_check_ds(s, vd, vs1, vm) && | ||
305 | + require_align(vs2, s->lmul + 1); | ||
306 | +} | ||
307 | + | ||
308 | +static bool vext_check_sd(DisasContext *s, int vd, int vs, int vm) | ||
309 | +{ | ||
310 | + bool ret = vext_narrow_check_common(s, vd, vs, vm); | ||
311 | + if (vd != vs) { | ||
312 | + ret &= require_noover(vd, s->lmul, vs, s->lmul + 1); | ||
313 | + } | ||
314 | + return ret; | ||
315 | +} | ||
316 | + | ||
317 | +/* | ||
318 | + * Check function for vector instruction with format: | ||
319 | + * single-width result and double-width source 1 and single-width | ||
320 | + * source 2 (SEW = 2*SEW op SEW) | ||
321 | + * | ||
322 | + * Rules to be checked here: | ||
323 | + * 1. All rules in defined in narrow common rules are applied. | ||
324 | + * 2. Destination vector register cannot overlap a source vector | ||
325 | + * register (vs2) group. | ||
326 | + * (Section 5.2) | ||
327 | + * 3. Source 2 (vs1) vector register number is multiples of LMUL. | ||
328 | + * (Section 3.4.2) | ||
329 | + */ | ||
330 | +static bool vext_check_sds(DisasContext *s, int vd, int vs1, int vs2, int vm) | ||
331 | +{ | ||
332 | + return vext_check_sd(s, vd, vs2, vm) && | ||
333 | + require_align(vs1, s->lmul); | ||
334 | +} | ||
335 | + | ||
336 | +/* | ||
337 | + * Check function for vector reduction instructions. | ||
338 | + * | ||
339 | + * Rules to be checked here: | ||
340 | + * 1. Source 1 (vs2) vector register number is multiples of LMUL. | ||
341 | + * (Section 3.4.2) | ||
342 | + */ | ||
343 | +static bool vext_check_reduction(DisasContext *s, int vs2) | ||
344 | +{ | ||
345 | + return require_align(vs2, s->lmul); | ||
346 | +} | ||
347 | + | ||
348 | +/* | ||
349 | + * Check function for vector slide instructions. | ||
350 | + * | ||
351 | + * Rules to be checked here: | ||
352 | + * 1. Source 1 (vs2) vector register number is multiples of LMUL. | ||
353 | + * (Section 3.4.2) | ||
354 | + * 2. Destination vector register number is multiples of LMUL. | ||
355 | + * (Section 3.4.2) | ||
356 | + * 3. Destination vector register group for a masked vector | ||
357 | + * instruction cannot overlap the source mask register (v0). | ||
358 | + * (Section 5.3) | ||
359 | + * 4. The destination vector register group for vslideup, vslide1up, | ||
360 | + * vfslide1up, cannot overlap the source vector register (vs2) group. | ||
361 | + * (Section 5.2, 16.3.1, 16.3.3) | ||
362 | + */ | ||
363 | +static bool vext_check_slide(DisasContext *s, int vd, int vs2, | ||
364 | + int vm, bool is_over) | ||
365 | +{ | ||
366 | + bool ret = require_align(vs2, s->lmul) && | ||
367 | + require_align(vd, s->lmul) && | ||
368 | + require_vm(vm, vd); | ||
369 | + if (is_over) { | ||
370 | + ret &= (vd != vs2); | ||
371 | + } | ||
372 | + return ret; | ||
373 | +} | ||
374 | + | ||
375 | /* | ||
376 | * In cpu_get_tb_cpu_state(), set VILL if RVV was not present. | ||
377 | * So RVV is also be checked in this function. | ||
378 | @@ -XXX,XX +XXX,XX @@ static inline bool vext_check_overlap_group(int rd, int dlen, int rs, int slen) | ||
379 | { | ||
380 | return ((rd >= rs + slen) || (rs >= rd + dlen)); | ||
381 | } | ||
382 | + | ||
383 | /* common translation macro */ | ||
384 | #define GEN_VEXT_TRANS(NAME, SEQ, ARGTYPE, OP, CHECK) \ | ||
385 | static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE *a)\ | ||
386 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_TRANS(vamomaxud_v, 17, rwdvm, amo_op, amo_check64) | ||
387 | |||
388 | static bool opivv_check(DisasContext *s, arg_rmrr *a) | ||
389 | { | ||
390 | - return (vext_check_isa_ill(s) && | ||
391 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
392 | - vext_check_reg(s, a->rd, false) && | ||
393 | - vext_check_reg(s, a->rs2, false) && | ||
394 | - vext_check_reg(s, a->rs1, false)); | ||
395 | + return require_rvv(s) && | ||
396 | + vext_check_isa_ill(s) && | ||
397 | + vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
398 | } | ||
399 | |||
400 | typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t, | ||
401 | @@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm, | ||
402 | |||
403 | static bool opivx_check(DisasContext *s, arg_rmrr *a) | ||
404 | { | ||
405 | - return (vext_check_isa_ill(s) && | ||
406 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
407 | - vext_check_reg(s, a->rd, false) && | ||
408 | - vext_check_reg(s, a->rs2, false)); | ||
409 | + return require_rvv(s) && | ||
410 | + vext_check_isa_ill(s) && | ||
411 | + vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
412 | } | ||
413 | |||
414 | typedef void GVecGen2sFn(unsigned, uint32_t, uint32_t, TCGv_i64, | ||
415 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi) | ||
416 | /* OPIVV with WIDEN */ | ||
417 | static bool opivv_widen_check(DisasContext *s, arg_rmrr *a) | ||
418 | { | ||
419 | - return (vext_check_isa_ill(s) && | ||
420 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
421 | - vext_check_reg(s, a->rd, true) && | ||
422 | - vext_check_reg(s, a->rs2, false) && | ||
423 | - vext_check_reg(s, a->rs1, false) && | ||
424 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, | ||
425 | - 1 << s->lmul) && | ||
426 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs1, | ||
427 | - 1 << s->lmul) && | ||
428 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
429 | + return require_rvv(s) && | ||
430 | + vext_check_isa_ill(s) && | ||
431 | + vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
432 | } | ||
433 | |||
434 | static bool do_opivv_widen(DisasContext *s, arg_rmrr *a, | ||
435 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_WIDEN_TRANS(vwsub_vv, opivv_widen_check) | ||
436 | /* OPIVX with WIDEN */ | ||
437 | static bool opivx_widen_check(DisasContext *s, arg_rmrr *a) | ||
438 | { | ||
439 | - return (vext_check_isa_ill(s) && | ||
440 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
441 | - vext_check_reg(s, a->rd, true) && | ||
442 | - vext_check_reg(s, a->rs2, false) && | ||
443 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, | ||
444 | - 1 << s->lmul) && | ||
445 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
446 | + return require_rvv(s) && | ||
447 | + vext_check_isa_ill(s) && | ||
448 | + vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
449 | } | ||
450 | |||
451 | static bool do_opivx_widen(DisasContext *s, arg_rmrr *a, | ||
452 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_WIDEN_TRANS(vwsub_vx) | ||
453 | /* WIDEN OPIVV with WIDEN */ | ||
454 | static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a) | ||
455 | { | ||
456 | - return (vext_check_isa_ill(s) && | ||
457 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
458 | - vext_check_reg(s, a->rd, true) && | ||
459 | - vext_check_reg(s, a->rs2, true) && | ||
460 | - vext_check_reg(s, a->rs1, false) && | ||
461 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs1, | ||
462 | - 1 << s->lmul) && | ||
463 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
464 | + return require_rvv(s) && | ||
465 | + vext_check_isa_ill(s) && | ||
466 | + vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm); | ||
467 | } | ||
468 | |||
469 | static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a, | ||
470 | @@ -XXX,XX +XXX,XX @@ GEN_OPIWV_WIDEN_TRANS(vwsub_wv) | ||
471 | /* WIDEN OPIVX with WIDEN */ | ||
472 | static bool opiwx_widen_check(DisasContext *s, arg_rmrr *a) | ||
473 | { | ||
474 | - return (vext_check_isa_ill(s) && | ||
475 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
476 | - vext_check_reg(s, a->rd, true) && | ||
477 | - vext_check_reg(s, a->rs2, true) && | ||
478 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
479 | + return require_rvv(s) && | ||
480 | + vext_check_isa_ill(s) && | ||
481 | + vext_check_dd(s, a->rd, a->rs2, a->vm); | ||
482 | } | ||
483 | |||
484 | static bool do_opiwx_widen(DisasContext *s, arg_rmrr *a, | ||
485 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
486 | */ | ||
487 | static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a) | ||
488 | { | ||
489 | - return (vext_check_isa_ill(s) && | ||
490 | - vext_check_reg(s, a->rd, false) && | ||
491 | - vext_check_reg(s, a->rs2, false) && | ||
492 | - vext_check_reg(s, a->rs1, false) && | ||
493 | - ((a->rd != 0) || (s->lmul == 0))); | ||
494 | + return require_rvv(s) && | ||
495 | + vext_check_isa_ill(s) && | ||
496 | + (a->rd != 0) && | ||
497 | + vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
498 | } | ||
499 | |||
500 | GEN_OPIVV_TRANS(vadc_vvm, opivv_vadc_check) | ||
501 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vsbc_vvm, opivv_vadc_check) | ||
502 | */ | ||
503 | static bool opivv_vmadc_check(DisasContext *s, arg_rmrr *a) | ||
504 | { | ||
505 | - return (vext_check_isa_ill(s) && | ||
506 | - vext_check_reg(s, a->rs2, false) && | ||
507 | - vext_check_reg(s, a->rs1, false) && | ||
508 | - vext_check_overlap_group(a->rd, 1, a->rs1, 1 << s->lmul) && | ||
509 | - vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul)); | ||
510 | + return require_rvv(s) && | ||
511 | + vext_check_isa_ill(s) && | ||
512 | + vext_check_mss(s, a->rd, a->rs1, a->rs2); | ||
513 | } | ||
514 | |||
515 | GEN_OPIVV_TRANS(vmadc_vvm, opivv_vmadc_check) | ||
516 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vmsbc_vvm, opivv_vmadc_check) | ||
517 | |||
518 | static bool opivx_vadc_check(DisasContext *s, arg_rmrr *a) | ||
519 | { | ||
520 | - return (vext_check_isa_ill(s) && | ||
521 | - vext_check_reg(s, a->rd, false) && | ||
522 | - vext_check_reg(s, a->rs2, false) && | ||
523 | - ((a->rd != 0) || (s->lmul == 0))); | ||
524 | + return require_rvv(s) && | ||
525 | + vext_check_isa_ill(s) && | ||
526 | + (a->rd != 0) && | ||
527 | + vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
528 | } | ||
529 | |||
530 | /* OPIVX without GVEC IR */ | ||
531 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vsbc_vxm, opivx_vadc_check) | ||
532 | |||
533 | static bool opivx_vmadc_check(DisasContext *s, arg_rmrr *a) | ||
534 | { | ||
535 | - return (vext_check_isa_ill(s) && | ||
536 | - vext_check_reg(s, a->rs2, false) && | ||
537 | - vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul)); | ||
538 | + return require_rvv(s) && | ||
539 | + vext_check_isa_ill(s) && | ||
540 | + vext_check_ms(s, a->rd, a->rs2); | ||
541 | } | ||
542 | |||
543 | GEN_OPIVX_TRANS(vmadc_vxm, opivx_vmadc_check) | ||
544 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_GVEC_TRANS(vsra_vi, 1, vsra_vx, sari) | ||
545 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
546 | static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
547 | { | ||
548 | - return (vext_check_isa_ill(s) && | ||
549 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
550 | - vext_check_reg(s, a->rd, false) && | ||
551 | - vext_check_reg(s, a->rs2, true) && | ||
552 | - vext_check_reg(s, a->rs1, false) && | ||
553 | - vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, | ||
554 | - 2 << s->lmul) && | ||
555 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
556 | + return require_rvv(s) && | ||
557 | + vext_check_isa_ill(s) && | ||
558 | + vext_check_sds(s, a->rd, a->rs1, a->rs2, a->vm); | ||
559 | } | ||
560 | |||
561 | /* OPIVV with NARROW */ | ||
562 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_NARROW_TRANS(vnsrl_vv) | ||
563 | |||
564 | static bool opivx_narrow_check(DisasContext *s, arg_rmrr *a) | ||
565 | { | ||
566 | - return (vext_check_isa_ill(s) && | ||
567 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
568 | - vext_check_reg(s, a->rd, false) && | ||
569 | - vext_check_reg(s, a->rs2, true) && | ||
570 | - vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, | ||
571 | - 2 << s->lmul) && | ||
572 | - (s->lmul < 0x3) && (s->sew < 0x3)); | ||
573 | + return require_rvv(s) && | ||
574 | + vext_check_isa_ill(s) && | ||
575 | + vext_check_sd(s, a->rd, a->rs2, a->vm); | ||
576 | } | ||
577 | |||
578 | /* OPIVX with NARROW */ | ||
579 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_NARROW_TRANS(vnsrl_vi, 1, vnsrl_vx) | ||
580 | */ | ||
581 | static bool opivv_cmp_check(DisasContext *s, arg_rmrr *a) | ||
582 | { | ||
583 | - return (vext_check_isa_ill(s) && | ||
584 | - vext_check_reg(s, a->rs2, false) && | ||
585 | - vext_check_reg(s, a->rs1, false) && | ||
586 | - ((vext_check_overlap_group(a->rd, 1, a->rs1, 1 << s->lmul) && | ||
587 | - vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul)) || | ||
588 | - (s->lmul == 0))); | ||
589 | + return require_rvv(s) && | ||
590 | + vext_check_isa_ill(s) && | ||
591 | + vext_check_mss(s, a->rd, a->rs1, a->rs2); | ||
592 | } | ||
593 | + | ||
594 | GEN_OPIVV_TRANS(vmseq_vv, opivv_cmp_check) | ||
595 | GEN_OPIVV_TRANS(vmsne_vv, opivv_cmp_check) | ||
596 | GEN_OPIVV_TRANS(vmsltu_vv, opivv_cmp_check) | ||
597 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vmsle_vv, opivv_cmp_check) | ||
598 | |||
599 | static bool opivx_cmp_check(DisasContext *s, arg_rmrr *a) | ||
600 | { | ||
601 | - return (vext_check_isa_ill(s) && | ||
602 | - vext_check_reg(s, a->rs2, false) && | ||
603 | - (vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul) || | ||
604 | - (s->lmul == 0))); | ||
605 | + return require_rvv(s) && | ||
606 | + vext_check_isa_ill(s) && | ||
607 | + vext_check_ms(s, a->rd, a->rs2); | ||
608 | } | ||
609 | |||
610 | GEN_OPIVX_TRANS(vmseq_vx, opivx_cmp_check) | ||
611 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx) | ||
612 | /* Vector Integer Merge and Move Instructions */ | ||
613 | static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a) | ||
614 | { | ||
615 | - if (vext_check_isa_ill(s) && | ||
616 | - vext_check_reg(s, a->rd, false) && | ||
617 | - vext_check_reg(s, a->rs1, false)) { | ||
618 | - | ||
619 | + if (require_rvv(s) && | ||
620 | + vext_check_isa_ill(s) && | ||
621 | + /* vmv.v.v has rs2 = 0 and vm = 1 */ | ||
622 | + vext_check_sss(s, a->rd, a->rs1, 0, 1)) { | ||
623 | if (s->vl_eq_vlmax) { | ||
624 | tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd), | ||
625 | vreg_ofs(s, a->rs1), | ||
626 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a) | ||
627 | typedef void gen_helper_vmv_vx(TCGv_ptr, TCGv_i64, TCGv_env, TCGv_i32); | ||
628 | static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a) | ||
629 | { | ||
630 | - if (vext_check_isa_ill(s) && | ||
631 | - vext_check_reg(s, a->rd, false)) { | ||
632 | - | ||
633 | + if (require_rvv(s) && | ||
634 | + vext_check_isa_ill(s) && | ||
635 | + /* vmv.v.x has rs2 = 0 and vm = 1 */ | ||
636 | + vext_check_ss(s, a->rd, 0, 1)) { | ||
637 | TCGv s1; | ||
638 | TCGLabel *over = gen_new_label(); | ||
639 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
640 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a) | ||
641 | |||
642 | static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a) | ||
643 | { | ||
644 | - if (vext_check_isa_ill(s) && | ||
645 | - vext_check_reg(s, a->rd, false)) { | ||
646 | - | ||
647 | + if (require_rvv(s) && | ||
648 | + vext_check_isa_ill(s) && | ||
649 | + /* vmv.v.i has rs2 = 0 and vm = 1 */ | ||
650 | + vext_check_ss(s, a->rd, 0, 1)) { | ||
651 | int64_t simm = sextract64(a->rs1, 0, 5); | ||
652 | if (s->vl_eq_vlmax) { | ||
653 | tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd), | ||
654 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_NARROW_TRANS(vnclip_vi, 1, vnclip_vx) | ||
655 | */ | ||
656 | static bool opfvv_check(DisasContext *s, arg_rmrr *a) | ||
657 | { | ||
658 | - return (vext_check_isa_ill(s) && | ||
659 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
660 | - vext_check_reg(s, a->rd, false) && | ||
661 | - vext_check_reg(s, a->rs2, false) && | ||
662 | - vext_check_reg(s, a->rs1, false) && | ||
663 | - (s->sew != 0)); | ||
664 | + return require_rvv(s) && | ||
665 | + require_rvf(s) && | ||
666 | + vext_check_isa_ill(s) && | ||
667 | + vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
668 | } | ||
669 | |||
670 | /* OPFVV without GVEC IR */ | ||
671 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
672 | return true; | ||
673 | } | ||
674 | |||
675 | -static bool opfvf_check(DisasContext *s, arg_rmrr *a) | ||
676 | -{ | ||
677 | /* | ||
678 | * If the current SEW does not correspond to a supported IEEE floating-point | ||
679 | * type, an illegal instruction exception is raised | ||
680 | */ | ||
681 | - return (vext_check_isa_ill(s) && | ||
682 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
683 | - vext_check_reg(s, a->rd, false) && | ||
684 | - vext_check_reg(s, a->rs2, false) && | ||
685 | - (s->sew != 0)); | ||
686 | +static bool opfvf_check(DisasContext *s, arg_rmrr *a) | ||
687 | +{ | ||
688 | + return require_rvv(s) && | ||
689 | + require_rvf(s) && | ||
690 | + vext_check_isa_ill(s) && | ||
691 | + vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
692 | } | ||
693 | |||
694 | /* OPFVF without GVEC IR */ | ||
695 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check) | ||
696 | /* Vector Widening Floating-Point Add/Subtract Instructions */ | ||
697 | static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) | ||
698 | { | ||
699 | - return (vext_check_isa_ill(s) && | ||
700 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
701 | - vext_check_reg(s, a->rd, true) && | ||
702 | - vext_check_reg(s, a->rs2, false) && | ||
703 | - vext_check_reg(s, a->rs1, false) && | ||
704 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, | ||
705 | - 1 << s->lmul) && | ||
706 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs1, | ||
707 | - 1 << s->lmul) && | ||
708 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
709 | + return require_rvv(s) && | ||
710 | + require_rvf(s) && | ||
711 | + vext_check_isa_ill(s) && | ||
712 | + vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm); | ||
713 | } | ||
714 | |||
715 | /* OPFVV with WIDEN */ | ||
716 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check) | ||
717 | |||
718 | static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a) | ||
719 | { | ||
720 | - return (vext_check_isa_ill(s) && | ||
721 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
722 | - vext_check_reg(s, a->rd, true) && | ||
723 | - vext_check_reg(s, a->rs2, false) && | ||
724 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, | ||
725 | - 1 << s->lmul) && | ||
726 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
727 | + return require_rvv(s) && | ||
728 | + require_rvf(s) && | ||
729 | + vext_check_isa_ill(s) && | ||
730 | + vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
731 | } | ||
732 | |||
733 | /* OPFVF with WIDEN */ | ||
734 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf) | ||
735 | |||
736 | static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a) | ||
737 | { | ||
738 | - return (vext_check_isa_ill(s) && | ||
739 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
740 | - vext_check_reg(s, a->rd, true) && | ||
741 | - vext_check_reg(s, a->rs2, true) && | ||
742 | - vext_check_reg(s, a->rs1, false) && | ||
743 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs1, | ||
744 | - 1 << s->lmul) && | ||
745 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
746 | + return require_rvv(s) && | ||
747 | + require_rvf(s) && | ||
748 | + vext_check_isa_ill(s) && | ||
749 | + vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm); | ||
750 | } | ||
751 | |||
752 | /* WIDEN OPFVV with WIDEN */ | ||
753 | @@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv) | ||
754 | |||
755 | static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a) | ||
756 | { | ||
757 | - return (vext_check_isa_ill(s) && | ||
758 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
759 | - vext_check_reg(s, a->rd, true) && | ||
760 | - vext_check_reg(s, a->rs2, true) && | ||
761 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
762 | + return require_rvv(s) && | ||
763 | + require_rvf(s) && | ||
764 | + vext_check_isa_ill(s) && | ||
765 | + vext_check_dd(s, a->rd, a->rs2, a->vm); | ||
766 | } | ||
767 | |||
768 | /* WIDEN OPFVF with WIDEN */ | ||
769 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf) | ||
770 | */ | ||
771 | static bool opfv_check(DisasContext *s, arg_rmr *a) | ||
772 | { | ||
773 | - return (vext_check_isa_ill(s) && | ||
774 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
775 | - vext_check_reg(s, a->rd, false) && | ||
776 | - vext_check_reg(s, a->rs2, false) && | ||
777 | - (s->sew != 0)); | ||
778 | + return require_rvv(s) && | ||
779 | + require_rvf(s) && | ||
780 | + vext_check_isa_ill(s) && | ||
781 | + /* OPFV instructions ignore vs1 check */ | ||
782 | + vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
783 | } | ||
784 | |||
785 | #define GEN_OPFV_TRANS(NAME, CHECK) \ | ||
786 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfsgnjx_vf, opfvf_check) | ||
787 | /* Vector Floating-Point Compare Instructions */ | ||
788 | static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a) | ||
789 | { | ||
790 | - return (vext_check_isa_ill(s) && | ||
791 | - vext_check_reg(s, a->rs2, false) && | ||
792 | - vext_check_reg(s, a->rs1, false) && | ||
793 | - (s->sew != 0) && | ||
794 | - ((vext_check_overlap_group(a->rd, 1, a->rs1, 1 << s->lmul) && | ||
795 | - vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul)) || | ||
796 | - (s->lmul == 0))); | ||
797 | + return require_rvv(s) && | ||
798 | + require_rvf(s) && | ||
799 | + vext_check_isa_ill(s) && | ||
800 | + vext_check_mss(s, a->rd, a->rs1, a->rs2); | ||
801 | } | ||
802 | |||
803 | GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check) | ||
804 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vmford_vv, opfvv_cmp_check) | ||
805 | |||
806 | static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a) | ||
807 | { | ||
808 | - return (vext_check_isa_ill(s) && | ||
809 | - vext_check_reg(s, a->rs2, false) && | ||
810 | - (s->sew != 0) && | ||
811 | - (vext_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul) || | ||
812 | - (s->lmul == 0))); | ||
813 | + return require_rvv(s) && | ||
814 | + require_rvf(s) && | ||
815 | + vext_check_isa_ill(s) && | ||
816 | + vext_check_ms(s, a->rd, a->rs2); | ||
817 | } | ||
818 | |||
819 | GEN_OPFVF_TRANS(vmfeq_vf, opfvf_cmp_check) | ||
820 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfmerge_vfm, opfvf_check) | ||
821 | |||
822 | static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
823 | { | ||
824 | - if (vext_check_isa_ill(s) && | ||
825 | - vext_check_reg(s, a->rd, false) && | ||
826 | - (s->sew != 0)) { | ||
827 | - | ||
828 | + if (require_rvv(s) && | ||
829 | + require_rvf(s) && | ||
830 | + vext_check_isa_ill(s) && | ||
831 | + require_align(a->rd, s->lmul)) { | ||
832 | if (s->vl_eq_vlmax) { | ||
833 | tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd), | ||
834 | MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]); | ||
835 | @@ -XXX,XX +XXX,XX @@ GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check) | ||
836 | */ | ||
837 | static bool opfv_widen_check(DisasContext *s, arg_rmr *a) | ||
838 | { | ||
839 | - return (vext_check_isa_ill(s) && | ||
840 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
841 | - vext_check_reg(s, a->rd, true) && | ||
842 | - vext_check_reg(s, a->rs2, false) && | ||
843 | - vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2, | ||
844 | - 1 << s->lmul) && | ||
845 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
846 | + return require_rvv(s) && | ||
847 | + require_scale_rvf(s) && | ||
848 | + (s->sew != MO_8) && | ||
849 | + vext_check_isa_ill(s) && | ||
850 | + vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
851 | } | ||
852 | |||
853 | #define GEN_OPFV_WIDEN_TRANS(NAME) \ | ||
854 | @@ -XXX,XX +XXX,XX @@ GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v) | ||
855 | */ | ||
856 | static bool opfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
857 | { | ||
858 | - return (vext_check_isa_ill(s) && | ||
859 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
860 | - vext_check_reg(s, a->rd, false) && | ||
861 | - vext_check_reg(s, a->rs2, true) && | ||
862 | - vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, | ||
863 | - 2 << s->lmul) && | ||
864 | - (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0)); | ||
865 | + return require_rvv(s) && | ||
866 | + require_rvf(s) && | ||
867 | + (s->sew != MO_64) && | ||
868 | + vext_check_isa_ill(s) && | ||
869 | + /* OPFV narrowing instructions ignore vs1 check */ | ||
870 | + vext_check_sd(s, a->rd, a->rs2, a->vm); | ||
871 | } | ||
872 | |||
873 | #define GEN_OPFV_NARROW_TRANS(NAME) \ | ||
874 | @@ -XXX,XX +XXX,XX @@ GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v) | ||
875 | /* Vector Single-Width Integer Reduction Instructions */ | ||
876 | static bool reduction_check(DisasContext *s, arg_rmrr *a) | ||
877 | { | ||
878 | - return vext_check_isa_ill(s) && vext_check_reg(s, a->rs2, false); | ||
879 | + return require_rvv(s) && | ||
880 | + vext_check_isa_ill(s) && | ||
881 | + vext_check_reduction(s, a->rs2); | ||
882 | } | ||
883 | |||
884 | GEN_OPIVV_TRANS(vredsum_vs, reduction_check) | ||
885 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vredor_vs, reduction_check) | ||
886 | GEN_OPIVV_TRANS(vredxor_vs, reduction_check) | ||
887 | |||
888 | /* Vector Widening Integer Reduction Instructions */ | ||
889 | -GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_check) | ||
890 | -GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_check) | ||
891 | +static bool reduction_widen_check(DisasContext *s, arg_rmrr *a) | ||
892 | +{ | ||
893 | + return reduction_check(s, a) && (s->sew < MO_64); | ||
894 | +} | ||
895 | + | ||
896 | +GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check) | ||
897 | +GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check) | ||
898 | |||
899 | /* Vector Single-Width Floating-Point Reduction Instructions */ | ||
900 | GEN_OPFVV_TRANS(vfredsum_vs, reduction_check) | ||
901 | @@ -XXX,XX +XXX,XX @@ GEN_MM_TRANS(vmxnor_mm) | ||
902 | /* Vector mask population count vmpopc */ | ||
903 | static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a) | ||
904 | { | ||
905 | - if (vext_check_isa_ill(s)) { | ||
906 | + if (require_rvv(s) && | ||
907 | + vext_check_isa_ill(s)) { | ||
908 | TCGv_ptr src2, mask; | ||
909 | TCGv dst; | ||
910 | TCGv_i32 desc; | ||
911 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a) | ||
912 | /* vmfirst find-first-set mask bit */ | ||
913 | static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a) | ||
914 | { | ||
915 | - if (vext_check_isa_ill(s)) { | ||
916 | + if (require_rvv(s) && | ||
917 | + vext_check_isa_ill(s)) { | ||
918 | TCGv_ptr src2, mask; | ||
919 | TCGv dst; | ||
920 | TCGv_i32 desc; | ||
921 | @@ -XXX,XX +XXX,XX @@ GEN_M_TRANS(vmsof_m) | ||
922 | /* Vector Iota Instruction */ | ||
923 | static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
924 | { | ||
925 | - if (vext_check_isa_ill(s) && | ||
926 | - vext_check_reg(s, a->rd, false) && | ||
927 | - vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, 1) && | ||
928 | - (a->vm != 0 || a->rd != 0)) { | ||
929 | + if (require_rvv(s) && | ||
930 | + vext_check_isa_ill(s) && | ||
931 | + require_noover(a->rd, s->lmul, a->rs2, 0) && | ||
932 | + require_vm(a->vm, a->rd) && | ||
933 | + require_align(a->rd, s->lmul)) { | ||
934 | uint32_t data = 0; | ||
935 | TCGLabel *over = gen_new_label(); | ||
936 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
937 | @@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
938 | /* Vector Element Index Instruction */ | ||
939 | static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
940 | { | ||
941 | - if (vext_check_isa_ill(s) && | ||
942 | - vext_check_reg(s, a->rd, false) && | ||
943 | - vext_check_overlap_mask(s, a->rd, a->vm, false)) { | ||
944 | + if (require_rvv(s) && | ||
945 | + vext_check_isa_ill(s) && | ||
946 | + require_align(a->rd, s->lmul) && | ||
947 | + require_vm(a->vm, a->rd)) { | ||
948 | uint32_t data = 0; | ||
949 | TCGLabel *over = gen_new_label(); | ||
950 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
951 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
952 | /* Vector Slide Instructions */ | ||
953 | static bool slideup_check(DisasContext *s, arg_rmrr *a) | ||
954 | { | ||
955 | - return (vext_check_isa_ill(s) && | ||
956 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
957 | - vext_check_reg(s, a->rd, false) && | ||
958 | - vext_check_reg(s, a->rs2, false) && | ||
959 | - (a->rd != a->rs2)); | ||
960 | + return require_rvv(s) && | ||
961 | + vext_check_isa_ill(s) && | ||
962 | + vext_check_slide(s, a->rd, a->rs2, a->vm, true); | ||
963 | } | ||
964 | |||
965 | GEN_OPIVX_TRANS(vslideup_vx, slideup_check) | ||
966 | GEN_OPIVX_TRANS(vslide1up_vx, slideup_check) | ||
967 | GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check) | ||
968 | |||
969 | -GEN_OPIVX_TRANS(vslidedown_vx, opivx_check) | ||
970 | -GEN_OPIVX_TRANS(vslide1down_vx, opivx_check) | ||
971 | -GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check) | ||
972 | +static bool slidedown_check(DisasContext *s, arg_rmrr *a) | ||
973 | +{ | ||
974 | + return require_rvv(s) && | ||
975 | + vext_check_isa_ill(s) && | ||
976 | + vext_check_slide(s, a->rd, a->rs2, a->vm, false); | ||
977 | +} | ||
978 | + | ||
979 | +GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check) | ||
980 | +GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check) | ||
981 | +GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, slidedown_check) | ||
982 | |||
983 | /* Vector Register Gather Instruction */ | ||
984 | static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a) | ||
985 | { | ||
986 | - return (vext_check_isa_ill(s) && | ||
987 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
988 | - vext_check_reg(s, a->rd, false) && | ||
989 | - vext_check_reg(s, a->rs1, false) && | ||
990 | - vext_check_reg(s, a->rs2, false) && | ||
991 | - (a->rd != a->rs2) && (a->rd != a->rs1)); | ||
992 | + return require_rvv(s) && | ||
993 | + vext_check_isa_ill(s) && | ||
994 | + require_align(a->rd, s->lmul) && | ||
995 | + require_align(a->rs1, s->lmul) && | ||
996 | + require_align(a->rs2, s->lmul) && | ||
997 | + (a->rd != a->rs2 && a->rd != a->rs1) && | ||
998 | + require_vm(a->vm, a->rd); | ||
999 | } | ||
1000 | |||
1001 | GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check) | ||
1002 | |||
1003 | static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a) | ||
1004 | { | ||
1005 | - return (vext_check_isa_ill(s) && | ||
1006 | - vext_check_overlap_mask(s, a->rd, a->vm, true) && | ||
1007 | - vext_check_reg(s, a->rd, false) && | ||
1008 | - vext_check_reg(s, a->rs2, false) && | ||
1009 | - (a->rd != a->rs2)); | ||
1010 | + return require_rvv(s) && | ||
1011 | + vext_check_isa_ill(s) && | ||
1012 | + require_align(a->rd, s->lmul) && | ||
1013 | + require_align(a->rs2, s->lmul) && | ||
1014 | + (a->rd != a->rs2) && | ||
1015 | + require_vm(a->vm, a->rd); | ||
1016 | } | ||
1017 | |||
1018 | /* vrgather.vx vd, vs2, rs1, vm # vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[rs1] */ | ||
1019 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) | ||
1020 | return true; | ||
1021 | } | ||
1022 | |||
1023 | -/* Vector Compress Instruction */ | ||
1024 | +/* | ||
1025 | + * Vector Compress Instruction | ||
1026 | + * | ||
1027 | + * The destination vector register group cannot overlap the | ||
1028 | + * source vector register group or the source mask register. | ||
1029 | + */ | ||
1030 | static bool vcompress_vm_check(DisasContext *s, arg_r *a) | ||
1031 | { | ||
1032 | - return (vext_check_isa_ill(s) && | ||
1033 | - vext_check_reg(s, a->rd, false) && | ||
1034 | - vext_check_reg(s, a->rs2, false) && | ||
1035 | - vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs1, 1) && | ||
1036 | - (a->rd != a->rs2)); | ||
1037 | + return require_rvv(s) && | ||
1038 | + vext_check_isa_ill(s) && | ||
1039 | + require_align(a->rd, s->lmul) && | ||
1040 | + require_align(a->rs2, s->lmul) && | ||
1041 | + (a->rd != a->rs2) && | ||
1042 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs1, 1); | ||
1043 | } | ||
1044 | |||
1045 | static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
1046 | -- | ||
1047 | 2.31.1 | ||
1048 | |||
1049 | |||
1050 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Immediate value in translator function is extended not only | ||
4 | zero-extended and sign-extended but with more modes to be applicable | ||
5 | with multiple formats of vector instructions. | ||
6 | |||
7 | * IMM_ZX: Zero-extended | ||
8 | * IMM_SX: Sign-extended | ||
9 | * IMM_TRUNC_SEW: Truncate to log(SEW) bit | ||
10 | * IMM_TRUNC_2SEW: Truncate to log(2*SEW) bit | ||
11 | |||
12 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
13 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | Message-Id: <20211210075704.23951-17-frank.chang@sifive.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | --- | ||
18 | target/riscv/insn_trans/trans_rvv.c.inc | 115 ++++++++++++++---------- | ||
19 | 1 file changed, 66 insertions(+), 49 deletions(-) | ||
20 | |||
21 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
24 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
25 | @@ -XXX,XX +XXX,XX @@ static void tcg_gen_gvec_rsubs(unsigned vece, uint32_t dofs, uint32_t aofs, | ||
26 | |||
27 | GEN_OPIVX_GVEC_TRANS(vrsub_vx, rsubs) | ||
28 | |||
29 | +typedef enum { | ||
30 | + IMM_ZX, /* Zero-extended */ | ||
31 | + IMM_SX, /* Sign-extended */ | ||
32 | + IMM_TRUNC_SEW, /* Truncate to log(SEW) bits */ | ||
33 | + IMM_TRUNC_2SEW, /* Truncate to log(2*SEW) bits */ | ||
34 | +} imm_mode_t; | ||
35 | + | ||
36 | +static int64_t extract_imm(DisasContext *s, uint32_t imm, imm_mode_t imm_mode) | ||
37 | +{ | ||
38 | + switch (imm_mode) { | ||
39 | + case IMM_ZX: | ||
40 | + return extract64(imm, 0, 5); | ||
41 | + case IMM_SX: | ||
42 | + return sextract64(imm, 0, 5); | ||
43 | + case IMM_TRUNC_SEW: | ||
44 | + return extract64(imm, 0, s->sew + 3); | ||
45 | + case IMM_TRUNC_2SEW: | ||
46 | + return extract64(imm, 0, s->sew + 4); | ||
47 | + default: | ||
48 | + g_assert_not_reached(); | ||
49 | + } | ||
50 | +} | ||
51 | + | ||
52 | static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
53 | - gen_helper_opivx *fn, DisasContext *s, int zx) | ||
54 | + gen_helper_opivx *fn, DisasContext *s, | ||
55 | + imm_mode_t imm_mode) | ||
56 | { | ||
57 | TCGv_ptr dest, src2, mask; | ||
58 | TCGv src1; | ||
59 | @@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
60 | dest = tcg_temp_new_ptr(); | ||
61 | mask = tcg_temp_new_ptr(); | ||
62 | src2 = tcg_temp_new_ptr(); | ||
63 | - if (zx) { | ||
64 | - src1 = tcg_constant_tl(imm); | ||
65 | - } else { | ||
66 | - src1 = tcg_constant_tl(sextract64(imm, 0, 5)); | ||
67 | - } | ||
68 | + src1 = tcg_constant_tl(extract_imm(s, imm, imm_mode)); | ||
69 | + | ||
70 | data = FIELD_DP32(data, VDATA, VM, vm); | ||
71 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
72 | desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
73 | @@ -XXX,XX +XXX,XX @@ typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t, | ||
74 | |||
75 | static inline bool | ||
76 | do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn, | ||
77 | - gen_helper_opivx *fn, int zx) | ||
78 | + gen_helper_opivx *fn, imm_mode_t imm_mode) | ||
79 | { | ||
80 | if (!opivx_check(s, a)) { | ||
81 | return false; | ||
82 | } | ||
83 | |||
84 | if (a->vm && s->vl_eq_vlmax) { | ||
85 | - if (zx) { | ||
86 | - gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), | ||
87 | - extract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s)); | ||
88 | - } else { | ||
89 | - gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), | ||
90 | - sextract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s)); | ||
91 | - } | ||
92 | + gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), | ||
93 | + extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s)); | ||
94 | mark_vs_dirty(s); | ||
95 | return true; | ||
96 | } | ||
97 | - return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, zx); | ||
98 | + return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode); | ||
99 | } | ||
100 | |||
101 | /* OPIVI with GVEC IR */ | ||
102 | -#define GEN_OPIVI_GVEC_TRANS(NAME, ZX, OPIVX, SUF) \ | ||
103 | +#define GEN_OPIVI_GVEC_TRANS(NAME, IMM_MODE, OPIVX, SUF) \ | ||
104 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
105 | { \ | ||
106 | static gen_helper_opivx * const fns[4] = { \ | ||
107 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
108 | gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \ | ||
109 | }; \ | ||
110 | return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \ | ||
111 | - fns[s->sew], ZX); \ | ||
112 | + fns[s->sew], IMM_MODE); \ | ||
113 | } | ||
114 | |||
115 | -GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi) | ||
116 | +GEN_OPIVI_GVEC_TRANS(vadd_vi, IMM_SX, vadd_vx, addi) | ||
117 | |||
118 | static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs, | ||
119 | int64_t c, uint32_t oprsz, uint32_t maxsz) | ||
120 | @@ -XXX,XX +XXX,XX @@ static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs, | ||
121 | tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz); | ||
122 | } | ||
123 | |||
124 | -GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi) | ||
125 | +GEN_OPIVI_GVEC_TRANS(vrsub_vi, IMM_SX, vrsub_vx, rsubi) | ||
126 | |||
127 | /* Vector Widening Integer Add/Subtract */ | ||
128 | |||
129 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vmadc_vxm, opivx_vmadc_check) | ||
130 | GEN_OPIVX_TRANS(vmsbc_vxm, opivx_vmadc_check) | ||
131 | |||
132 | /* OPIVI without GVEC IR */ | ||
133 | -#define GEN_OPIVI_TRANS(NAME, ZX, OPIVX, CHECK) \ | ||
134 | +#define GEN_OPIVI_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \ | ||
135 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
136 | { \ | ||
137 | if (CHECK(s, a)) { \ | ||
138 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
139 | gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \ | ||
140 | }; \ | ||
141 | return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, \ | ||
142 | - fns[s->sew], s, ZX); \ | ||
143 | + fns[s->sew], s, IMM_MODE); \ | ||
144 | } \ | ||
145 | return false; \ | ||
146 | } | ||
147 | |||
148 | -GEN_OPIVI_TRANS(vadc_vim, 0, vadc_vxm, opivx_vadc_check) | ||
149 | -GEN_OPIVI_TRANS(vmadc_vim, 0, vmadc_vxm, opivx_vmadc_check) | ||
150 | +GEN_OPIVI_TRANS(vadc_vim, IMM_SX, vadc_vxm, opivx_vadc_check) | ||
151 | +GEN_OPIVI_TRANS(vmadc_vim, IMM_SX, vmadc_vxm, opivx_vmadc_check) | ||
152 | |||
153 | /* Vector Bitwise Logical Instructions */ | ||
154 | GEN_OPIVV_GVEC_TRANS(vand_vv, and) | ||
155 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_GVEC_TRANS(vxor_vv, xor) | ||
156 | GEN_OPIVX_GVEC_TRANS(vand_vx, ands) | ||
157 | GEN_OPIVX_GVEC_TRANS(vor_vx, ors) | ||
158 | GEN_OPIVX_GVEC_TRANS(vxor_vx, xors) | ||
159 | -GEN_OPIVI_GVEC_TRANS(vand_vi, 0, vand_vx, andi) | ||
160 | -GEN_OPIVI_GVEC_TRANS(vor_vi, 0, vor_vx, ori) | ||
161 | -GEN_OPIVI_GVEC_TRANS(vxor_vi, 0, vxor_vx, xori) | ||
162 | +GEN_OPIVI_GVEC_TRANS(vand_vi, IMM_SX, vand_vx, andi) | ||
163 | +GEN_OPIVI_GVEC_TRANS(vor_vi, IMM_SX, vor_vx, ori) | ||
164 | +GEN_OPIVI_GVEC_TRANS(vxor_vi, IMM_SX, vxor_vx, xori) | ||
165 | |||
166 | /* Vector Single-Width Bit Shift Instructions */ | ||
167 | GEN_OPIVV_GVEC_TRANS(vsll_vv, shlv) | ||
168 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_SHIFT_TRANS(vsll_vx, shls) | ||
169 | GEN_OPIVX_GVEC_SHIFT_TRANS(vsrl_vx, shrs) | ||
170 | GEN_OPIVX_GVEC_SHIFT_TRANS(vsra_vx, sars) | ||
171 | |||
172 | -GEN_OPIVI_GVEC_TRANS(vsll_vi, 1, vsll_vx, shli) | ||
173 | -GEN_OPIVI_GVEC_TRANS(vsrl_vi, 1, vsrl_vx, shri) | ||
174 | -GEN_OPIVI_GVEC_TRANS(vsra_vi, 1, vsra_vx, sari) | ||
175 | +GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_ZX, vsll_vx, shli) | ||
176 | +GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_ZX, vsrl_vx, shri) | ||
177 | +GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_ZX, vsra_vx, sari) | ||
178 | |||
179 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
180 | static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
181 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_NARROW_TRANS(vnsra_vx) | ||
182 | GEN_OPIVX_NARROW_TRANS(vnsrl_vx) | ||
183 | |||
184 | /* OPIVI with NARROW */ | ||
185 | -#define GEN_OPIVI_NARROW_TRANS(NAME, ZX, OPIVX) \ | ||
186 | +#define GEN_OPIVI_NARROW_TRANS(NAME, IMM_MODE, OPIVX) \ | ||
187 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
188 | { \ | ||
189 | if (opivx_narrow_check(s, a)) { \ | ||
190 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
191 | gen_helper_##OPIVX##_w, \ | ||
192 | }; \ | ||
193 | return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, \ | ||
194 | - fns[s->sew], s, ZX); \ | ||
195 | + fns[s->sew], s, IMM_MODE); \ | ||
196 | } \ | ||
197 | return false; \ | ||
198 | } | ||
199 | |||
200 | -GEN_OPIVI_NARROW_TRANS(vnsra_vi, 1, vnsra_vx) | ||
201 | -GEN_OPIVI_NARROW_TRANS(vnsrl_vi, 1, vnsrl_vx) | ||
202 | +GEN_OPIVI_NARROW_TRANS(vnsra_vi, IMM_ZX, vnsra_vx) | ||
203 | +GEN_OPIVI_NARROW_TRANS(vnsrl_vi, IMM_ZX, vnsrl_vx) | ||
204 | |||
205 | /* Vector Integer Comparison Instructions */ | ||
206 | /* | ||
207 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vmsle_vx, opivx_cmp_check) | ||
208 | GEN_OPIVX_TRANS(vmsgtu_vx, opivx_cmp_check) | ||
209 | GEN_OPIVX_TRANS(vmsgt_vx, opivx_cmp_check) | ||
210 | |||
211 | -GEN_OPIVI_TRANS(vmseq_vi, 0, vmseq_vx, opivx_cmp_check) | ||
212 | -GEN_OPIVI_TRANS(vmsne_vi, 0, vmsne_vx, opivx_cmp_check) | ||
213 | -GEN_OPIVI_TRANS(vmsleu_vi, 1, vmsleu_vx, opivx_cmp_check) | ||
214 | -GEN_OPIVI_TRANS(vmsle_vi, 0, vmsle_vx, opivx_cmp_check) | ||
215 | -GEN_OPIVI_TRANS(vmsgtu_vi, 1, vmsgtu_vx, opivx_cmp_check) | ||
216 | -GEN_OPIVI_TRANS(vmsgt_vi, 0, vmsgt_vx, opivx_cmp_check) | ||
217 | +GEN_OPIVI_TRANS(vmseq_vi, IMM_SX, vmseq_vx, opivx_cmp_check) | ||
218 | +GEN_OPIVI_TRANS(vmsne_vi, IMM_SX, vmsne_vx, opivx_cmp_check) | ||
219 | +GEN_OPIVI_TRANS(vmsleu_vi, IMM_ZX, vmsleu_vx, opivx_cmp_check) | ||
220 | +GEN_OPIVI_TRANS(vmsle_vi, IMM_SX, vmsle_vx, opivx_cmp_check) | ||
221 | +GEN_OPIVI_TRANS(vmsgtu_vi, IMM_ZX, vmsgtu_vx, opivx_cmp_check) | ||
222 | +GEN_OPIVI_TRANS(vmsgt_vi, IMM_SX, vmsgt_vx, opivx_cmp_check) | ||
223 | |||
224 | /* Vector Integer Min/Max Instructions */ | ||
225 | GEN_OPIVV_GVEC_TRANS(vminu_vv, umin) | ||
226 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a) | ||
227 | |||
228 | GEN_OPIVV_TRANS(vmerge_vvm, opivv_vadc_check) | ||
229 | GEN_OPIVX_TRANS(vmerge_vxm, opivx_vadc_check) | ||
230 | -GEN_OPIVI_TRANS(vmerge_vim, 0, vmerge_vxm, opivx_vadc_check) | ||
231 | +GEN_OPIVI_TRANS(vmerge_vim, IMM_SX, vmerge_vxm, opivx_vadc_check) | ||
232 | |||
233 | /* | ||
234 | *** Vector Fixed-Point Arithmetic Instructions | ||
235 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vsaddu_vx, opivx_check) | ||
236 | GEN_OPIVX_TRANS(vsadd_vx, opivx_check) | ||
237 | GEN_OPIVX_TRANS(vssubu_vx, opivx_check) | ||
238 | GEN_OPIVX_TRANS(vssub_vx, opivx_check) | ||
239 | -GEN_OPIVI_TRANS(vsaddu_vi, 1, vsaddu_vx, opivx_check) | ||
240 | -GEN_OPIVI_TRANS(vsadd_vi, 0, vsadd_vx, opivx_check) | ||
241 | +GEN_OPIVI_TRANS(vsaddu_vi, IMM_ZX, vsaddu_vx, opivx_check) | ||
242 | +GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check) | ||
243 | |||
244 | /* Vector Single-Width Averaging Add and Subtract */ | ||
245 | GEN_OPIVV_TRANS(vaadd_vv, opivv_check) | ||
246 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vssrl_vv, opivv_check) | ||
247 | GEN_OPIVV_TRANS(vssra_vv, opivv_check) | ||
248 | GEN_OPIVX_TRANS(vssrl_vx, opivx_check) | ||
249 | GEN_OPIVX_TRANS(vssra_vx, opivx_check) | ||
250 | -GEN_OPIVI_TRANS(vssrl_vi, 1, vssrl_vx, opivx_check) | ||
251 | -GEN_OPIVI_TRANS(vssra_vi, 0, vssra_vx, opivx_check) | ||
252 | +GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check) | ||
253 | +GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check) | ||
254 | |||
255 | /* Vector Narrowing Fixed-Point Clip Instructions */ | ||
256 | GEN_OPIVV_NARROW_TRANS(vnclipu_vv) | ||
257 | GEN_OPIVV_NARROW_TRANS(vnclip_vv) | ||
258 | GEN_OPIVX_NARROW_TRANS(vnclipu_vx) | ||
259 | GEN_OPIVX_NARROW_TRANS(vnclip_vx) | ||
260 | -GEN_OPIVI_NARROW_TRANS(vnclipu_vi, 1, vnclipu_vx) | ||
261 | -GEN_OPIVI_NARROW_TRANS(vnclip_vi, 1, vnclip_vx) | ||
262 | +GEN_OPIVI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx) | ||
263 | +GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) | ||
264 | |||
265 | /* | ||
266 | *** Vector Float Point Arithmetic Instructions | ||
267 | @@ -XXX,XX +XXX,XX @@ static bool slideup_check(DisasContext *s, arg_rmrr *a) | ||
268 | |||
269 | GEN_OPIVX_TRANS(vslideup_vx, slideup_check) | ||
270 | GEN_OPIVX_TRANS(vslide1up_vx, slideup_check) | ||
271 | -GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check) | ||
272 | +GEN_OPIVI_TRANS(vslideup_vi, IMM_ZX, vslideup_vx, slideup_check) | ||
273 | |||
274 | static bool slidedown_check(DisasContext *s, arg_rmrr *a) | ||
275 | { | ||
276 | @@ -XXX,XX +XXX,XX @@ static bool slidedown_check(DisasContext *s, arg_rmrr *a) | ||
277 | |||
278 | GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check) | ||
279 | GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check) | ||
280 | -GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, slidedown_check) | ||
281 | +GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check) | ||
282 | |||
283 | /* Vector Register Gather Instruction */ | ||
284 | static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a) | ||
285 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) | ||
286 | gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h, | ||
287 | gen_helper_vrgather_vx_w, gen_helper_vrgather_vx_d | ||
288 | }; | ||
289 | - return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, 1); | ||
290 | + return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], | ||
291 | + s, IMM_ZX); | ||
292 | } | ||
293 | return true; | ||
294 | } | ||
295 | -- | ||
296 | 2.31.1 | ||
297 | |||
298 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Add fp16 nan-box check generator function, if a 16-bit input is not | ||
4 | properly nanboxed, then the input is replaced with the default qnan. | ||
5 | * Add do_nanbox() helper function to utilize gen_check_nanbox_X() to | ||
6 | generate the NaN-boxed floating-point values based on SEW setting. | ||
7 | * Apply nanbox helper in opfvf_trans(). | ||
8 | |||
9 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20211210075704.23951-18-frank.chang@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/insn_trans/trans_rvv.c.inc | 35 ++++++++++++++++++++++++- | ||
16 | 1 file changed, 34 insertions(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
21 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
22 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) | ||
23 | /* | ||
24 | *** Vector Float Point Arithmetic Instructions | ||
25 | */ | ||
26 | + | ||
27 | +/* | ||
28 | + * As RVF-only cpus always have values NaN-boxed to 64-bits, | ||
29 | + * RVF and RVD can be treated equally. | ||
30 | + * We don't have to deal with the cases of: SEW > FLEN. | ||
31 | + * | ||
32 | + * If SEW < FLEN, check whether input fp register is a valid | ||
33 | + * NaN-boxed value, in which case the least-significant SEW bits | ||
34 | + * of the f regsiter are used, else the canonical NaN value is used. | ||
35 | + */ | ||
36 | +static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in) | ||
37 | +{ | ||
38 | + switch (s->sew) { | ||
39 | + case 1: | ||
40 | + gen_check_nanbox_h(out, in); | ||
41 | + break; | ||
42 | + case 2: | ||
43 | + gen_check_nanbox_s(out, in); | ||
44 | + break; | ||
45 | + case 3: | ||
46 | + tcg_gen_mov_i64(out, in); | ||
47 | + break; | ||
48 | + default: | ||
49 | + g_assert_not_reached(); | ||
50 | + } | ||
51 | +} | ||
52 | + | ||
53 | /* Vector Single-Width Floating-Point Add/Subtract Instructions */ | ||
54 | |||
55 | /* | ||
56 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
57 | { | ||
58 | TCGv_ptr dest, src2, mask; | ||
59 | TCGv_i32 desc; | ||
60 | + TCGv_i64 t1; | ||
61 | |||
62 | TCGLabel *over = gen_new_label(); | ||
63 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
64 | @@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
65 | tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2)); | ||
66 | tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); | ||
67 | |||
68 | - fn(dest, mask, cpu_fpr[rs1], src2, cpu_env, desc); | ||
69 | + /* NaN-box f[rs1] */ | ||
70 | + t1 = tcg_temp_new_i64(); | ||
71 | + do_nanbox(s, t1, cpu_fpr[rs1]); | ||
72 | + | ||
73 | + fn(dest, mask, t1, src2, cpu_env, desc); | ||
74 | |||
75 | tcg_temp_free_ptr(dest); | ||
76 | tcg_temp_free_ptr(mask); | ||
77 | tcg_temp_free_ptr(src2); | ||
78 | + tcg_temp_free_i64(t1); | ||
79 | mark_vs_dirty(s); | ||
80 | gen_set_label(over); | ||
81 | return true; | ||
82 | -- | ||
83 | 2.31.1 | ||
84 | |||
85 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Vector AMOs are removed from standard vector extensions. Will be added | ||
4 | later as separate Zvamo extension, but will need a different encoding | ||
5 | from earlier proposal. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-19-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/helper.h | 27 ----- | ||
13 | target/riscv/insn32.decode | 24 ---- | ||
14 | target/riscv/vector_helper.c | 125 --------------------- | ||
15 | target/riscv/insn_trans/trans_rvv.c.inc | 140 ------------------------ | ||
16 | 4 files changed, 316 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/helper.h | ||
21 | +++ b/target/riscv/helper.h | ||
22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32) | ||
23 | DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32) | ||
24 | DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32) | ||
25 | DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32) | ||
26 | -DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
28 | -DEF_HELPER_6(vamoaddw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
29 | -DEF_HELPER_6(vamoaddd_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
30 | -DEF_HELPER_6(vamoxorw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
31 | -DEF_HELPER_6(vamoxord_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
32 | -DEF_HELPER_6(vamoandw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
33 | -DEF_HELPER_6(vamoandd_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
34 | -DEF_HELPER_6(vamoorw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
35 | -DEF_HELPER_6(vamoord_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
36 | -DEF_HELPER_6(vamominw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
37 | -DEF_HELPER_6(vamomind_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
38 | -DEF_HELPER_6(vamomaxw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
39 | -DEF_HELPER_6(vamomaxd_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
40 | -DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
41 | -DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
42 | -DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
43 | -DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
44 | -DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
45 | -DEF_HELPER_6(vamoaddw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
46 | -DEF_HELPER_6(vamoxorw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
47 | -DEF_HELPER_6(vamoandw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
48 | -DEF_HELPER_6(vamoorw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
49 | -DEF_HELPER_6(vamominw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
50 | -DEF_HELPER_6(vamomaxw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
51 | -DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
52 | -DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
53 | |||
54 | DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
55 | DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
56 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/target/riscv/insn32.decode | ||
59 | +++ b/target/riscv/insn32.decode | ||
60 | @@ -XXX,XX +XXX,XX @@ | ||
61 | &atomic aq rl rs2 rs1 rd | ||
62 | &rmrr vm rd rs1 rs2 | ||
63 | &rmr vm rd rs2 | ||
64 | -&rwdvm vm wd rd rs1 rs2 | ||
65 | &r2nfvm vm rd rs1 nf | ||
66 | &rnfvm vm rd rs1 rs2 nf | ||
67 | |||
68 | @@ -XXX,XX +XXX,XX @@ | ||
69 | @r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd | ||
70 | @r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd | ||
71 | @r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd | ||
72 | -@r_wdvm ..... wd:1 vm:1 ..... ..... ... ..... ....... &rwdvm %rs2 %rs1 %rd | ||
73 | @r2_zimm . zimm:11 ..... ... ..... ....... %rs1 %rd | ||
74 | @r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
75 | |||
76 | @@ -XXX,XX +XXX,XX @@ vsxh_v ... -11 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
77 | vsxw_v ... -11 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
78 | vsxe_v ... -11 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
79 | |||
80 | -#*** Vector AMO operations are encoded under the standard AMO major opcode *** | ||
81 | -vamoswapw_v 00001 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
82 | -vamoaddw_v 00000 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
83 | -vamoxorw_v 00100 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
84 | -vamoandw_v 01100 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
85 | -vamoorw_v 01000 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
86 | -vamominw_v 10000 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
87 | -vamomaxw_v 10100 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
88 | -vamominuw_v 11000 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
89 | -vamomaxuw_v 11100 . . ..... ..... 110 ..... 0101111 @r_wdvm | ||
90 | - | ||
91 | # *** new major opcode OP-V *** | ||
92 | vadd_vv 000000 . ..... ..... 000 ..... 1010111 @r_vm | ||
93 | vadd_vx 000000 . ..... ..... 100 ..... 1010111 @r_vm | ||
94 | @@ -XXX,XX +XXX,XX @@ vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r | ||
95 | vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm | ||
96 | vsetvl 1000000 ..... ..... 111 ..... 1010111 @r | ||
97 | |||
98 | -#*** Vector AMO operations (in addition to Zvamo) *** | ||
99 | -vamoswapd_v 00001 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
100 | -vamoaddd_v 00000 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
101 | -vamoxord_v 00100 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
102 | -vamoandd_v 01100 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
103 | -vamoord_v 01000 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
104 | -vamomind_v 10000 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
105 | -vamomaxd_v 10100 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
106 | -vamominud_v 11000 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
107 | -vamomaxud_v 11100 . . ..... ..... 111 ..... 0101111 @r_wdvm | ||
108 | - | ||
109 | # *** RV32 Zba Standard Extension *** | ||
110 | sh1add 0010000 .......... 010 ..... 0110011 @r | ||
111 | sh2add 0010000 .......... 100 ..... 0110011 @r | ||
112 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
113 | index XXXXXXX..XXXXXXX 100644 | ||
114 | --- a/target/riscv/vector_helper.c | ||
115 | +++ b/target/riscv/vector_helper.c | ||
116 | @@ -XXX,XX +XXX,XX @@ static inline int32_t vext_lmul(uint32_t desc) | ||
117 | return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3); | ||
118 | } | ||
119 | |||
120 | -static uint32_t vext_wd(uint32_t desc) | ||
121 | -{ | ||
122 | - return FIELD_EX32(simd_data(desc), VDATA, WD); | ||
123 | -} | ||
124 | - | ||
125 | /* | ||
126 | * Get vector group length in bytes. Its range is [64, 2048]. | ||
127 | * | ||
128 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_LDFF(vlhuff_v_d, uint16_t, uint64_t, ldhu_d) | ||
129 | GEN_VEXT_LDFF(vlwuff_v_w, uint32_t, uint32_t, ldwu_w) | ||
130 | GEN_VEXT_LDFF(vlwuff_v_d, uint32_t, uint64_t, ldwu_d) | ||
131 | |||
132 | -/* | ||
133 | - *** Vector AMO Operations (Zvamo) | ||
134 | - */ | ||
135 | -typedef void vext_amo_noatomic_fn(void *vs3, target_ulong addr, | ||
136 | - uint32_t wd, uint32_t idx, CPURISCVState *env, | ||
137 | - uintptr_t retaddr); | ||
138 | - | ||
139 | -/* no atomic opreation for vector atomic insructions */ | ||
140 | #define DO_SWAP(N, M) (M) | ||
141 | #define DO_AND(N, M) (N & M) | ||
142 | #define DO_XOR(N, M) (N ^ M) | ||
143 | #define DO_OR(N, M) (N | M) | ||
144 | #define DO_ADD(N, M) (N + M) | ||
145 | |||
146 | -#define GEN_VEXT_AMO_NOATOMIC_OP(NAME, ESZ, MSZ, H, DO_OP, SUF) \ | ||
147 | -static void \ | ||
148 | -vext_##NAME##_noatomic_op(void *vs3, target_ulong addr, \ | ||
149 | - uint32_t wd, uint32_t idx, \ | ||
150 | - CPURISCVState *env, uintptr_t retaddr)\ | ||
151 | -{ \ | ||
152 | - typedef int##ESZ##_t ETYPE; \ | ||
153 | - typedef int##MSZ##_t MTYPE; \ | ||
154 | - typedef uint##MSZ##_t UMTYPE __attribute__((unused)); \ | ||
155 | - ETYPE *pe3 = (ETYPE *)vs3 + H(idx); \ | ||
156 | - MTYPE a = cpu_ld##SUF##_data(env, addr), b = *pe3; \ | ||
157 | - \ | ||
158 | - cpu_st##SUF##_data(env, addr, DO_OP(a, b)); \ | ||
159 | - if (wd) { \ | ||
160 | - *pe3 = a; \ | ||
161 | - } \ | ||
162 | -} | ||
163 | - | ||
164 | /* Signed min/max */ | ||
165 | #define DO_MAX(N, M) ((N) >= (M) ? (N) : (M)) | ||
166 | #define DO_MIN(N, M) ((N) >= (M) ? (M) : (N)) | ||
167 | @@ -XXX,XX +XXX,XX @@ vext_##NAME##_noatomic_op(void *vs3, target_ulong addr, \ | ||
168 | #define DO_MAXU(N, M) DO_MAX((UMTYPE)N, (UMTYPE)M) | ||
169 | #define DO_MINU(N, M) DO_MIN((UMTYPE)N, (UMTYPE)M) | ||
170 | |||
171 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoswapw_v_w, 32, 32, H4, DO_SWAP, l) | ||
172 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoaddw_v_w, 32, 32, H4, DO_ADD, l) | ||
173 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoxorw_v_w, 32, 32, H4, DO_XOR, l) | ||
174 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoandw_v_w, 32, 32, H4, DO_AND, l) | ||
175 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoorw_v_w, 32, 32, H4, DO_OR, l) | ||
176 | -GEN_VEXT_AMO_NOATOMIC_OP(vamominw_v_w, 32, 32, H4, DO_MIN, l) | ||
177 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxw_v_w, 32, 32, H4, DO_MAX, l) | ||
178 | -GEN_VEXT_AMO_NOATOMIC_OP(vamominuw_v_w, 32, 32, H4, DO_MINU, l) | ||
179 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxuw_v_w, 32, 32, H4, DO_MAXU, l) | ||
180 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoswapw_v_d, 64, 32, H8, DO_SWAP, l) | ||
181 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoswapd_v_d, 64, 64, H8, DO_SWAP, q) | ||
182 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoaddw_v_d, 64, 32, H8, DO_ADD, l) | ||
183 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoaddd_v_d, 64, 64, H8, DO_ADD, q) | ||
184 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoxorw_v_d, 64, 32, H8, DO_XOR, l) | ||
185 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoxord_v_d, 64, 64, H8, DO_XOR, q) | ||
186 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoandw_v_d, 64, 32, H8, DO_AND, l) | ||
187 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoandd_v_d, 64, 64, H8, DO_AND, q) | ||
188 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoorw_v_d, 64, 32, H8, DO_OR, l) | ||
189 | -GEN_VEXT_AMO_NOATOMIC_OP(vamoord_v_d, 64, 64, H8, DO_OR, q) | ||
190 | -GEN_VEXT_AMO_NOATOMIC_OP(vamominw_v_d, 64, 32, H8, DO_MIN, l) | ||
191 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomind_v_d, 64, 64, H8, DO_MIN, q) | ||
192 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxw_v_d, 64, 32, H8, DO_MAX, l) | ||
193 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxd_v_d, 64, 64, H8, DO_MAX, q) | ||
194 | -GEN_VEXT_AMO_NOATOMIC_OP(vamominuw_v_d, 64, 32, H8, DO_MINU, l) | ||
195 | -GEN_VEXT_AMO_NOATOMIC_OP(vamominud_v_d, 64, 64, H8, DO_MINU, q) | ||
196 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxuw_v_d, 64, 32, H8, DO_MAXU, l) | ||
197 | -GEN_VEXT_AMO_NOATOMIC_OP(vamomaxud_v_d, 64, 64, H8, DO_MAXU, q) | ||
198 | - | ||
199 | -static inline void | ||
200 | -vext_amo_noatomic(void *vs3, void *v0, target_ulong base, | ||
201 | - void *vs2, CPURISCVState *env, uint32_t desc, | ||
202 | - vext_get_index_addr get_index_addr, | ||
203 | - vext_amo_noatomic_fn *noatomic_op, | ||
204 | - uint32_t esz, uint32_t msz, uintptr_t ra) | ||
205 | -{ | ||
206 | - uint32_t i; | ||
207 | - target_long addr; | ||
208 | - uint32_t wd = vext_wd(desc); | ||
209 | - uint32_t vm = vext_vm(desc); | ||
210 | - | ||
211 | - for (i = 0; i < env->vl; i++) { | ||
212 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
213 | - continue; | ||
214 | - } | ||
215 | - probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_LOAD); | ||
216 | - probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_STORE); | ||
217 | - } | ||
218 | - for (i = 0; i < env->vl; i++) { | ||
219 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
220 | - continue; | ||
221 | - } | ||
222 | - addr = get_index_addr(base, i, vs2); | ||
223 | - noatomic_op(vs3, addr, wd, i, env, ra); | ||
224 | - } | ||
225 | -} | ||
226 | - | ||
227 | -#define GEN_VEXT_AMO(NAME, MTYPE, ETYPE, INDEX_FN) \ | ||
228 | -void HELPER(NAME)(void *vs3, void *v0, target_ulong base, \ | ||
229 | - void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
230 | -{ \ | ||
231 | - vext_amo_noatomic(vs3, v0, base, vs2, env, desc, \ | ||
232 | - INDEX_FN, vext_##NAME##_noatomic_op, \ | ||
233 | - sizeof(ETYPE), sizeof(MTYPE), \ | ||
234 | - GETPC()); \ | ||
235 | -} | ||
236 | - | ||
237 | -GEN_VEXT_AMO(vamoswapw_v_d, int32_t, int64_t, idx_d) | ||
238 | -GEN_VEXT_AMO(vamoswapd_v_d, int64_t, int64_t, idx_d) | ||
239 | -GEN_VEXT_AMO(vamoaddw_v_d, int32_t, int64_t, idx_d) | ||
240 | -GEN_VEXT_AMO(vamoaddd_v_d, int64_t, int64_t, idx_d) | ||
241 | -GEN_VEXT_AMO(vamoxorw_v_d, int32_t, int64_t, idx_d) | ||
242 | -GEN_VEXT_AMO(vamoxord_v_d, int64_t, int64_t, idx_d) | ||
243 | -GEN_VEXT_AMO(vamoandw_v_d, int32_t, int64_t, idx_d) | ||
244 | -GEN_VEXT_AMO(vamoandd_v_d, int64_t, int64_t, idx_d) | ||
245 | -GEN_VEXT_AMO(vamoorw_v_d, int32_t, int64_t, idx_d) | ||
246 | -GEN_VEXT_AMO(vamoord_v_d, int64_t, int64_t, idx_d) | ||
247 | -GEN_VEXT_AMO(vamominw_v_d, int32_t, int64_t, idx_d) | ||
248 | -GEN_VEXT_AMO(vamomind_v_d, int64_t, int64_t, idx_d) | ||
249 | -GEN_VEXT_AMO(vamomaxw_v_d, int32_t, int64_t, idx_d) | ||
250 | -GEN_VEXT_AMO(vamomaxd_v_d, int64_t, int64_t, idx_d) | ||
251 | -GEN_VEXT_AMO(vamominuw_v_d, uint32_t, uint64_t, idx_d) | ||
252 | -GEN_VEXT_AMO(vamominud_v_d, uint64_t, uint64_t, idx_d) | ||
253 | -GEN_VEXT_AMO(vamomaxuw_v_d, uint32_t, uint64_t, idx_d) | ||
254 | -GEN_VEXT_AMO(vamomaxud_v_d, uint64_t, uint64_t, idx_d) | ||
255 | -GEN_VEXT_AMO(vamoswapw_v_w, int32_t, int32_t, idx_w) | ||
256 | -GEN_VEXT_AMO(vamoaddw_v_w, int32_t, int32_t, idx_w) | ||
257 | -GEN_VEXT_AMO(vamoxorw_v_w, int32_t, int32_t, idx_w) | ||
258 | -GEN_VEXT_AMO(vamoandw_v_w, int32_t, int32_t, idx_w) | ||
259 | -GEN_VEXT_AMO(vamoorw_v_w, int32_t, int32_t, idx_w) | ||
260 | -GEN_VEXT_AMO(vamominw_v_w, int32_t, int32_t, idx_w) | ||
261 | -GEN_VEXT_AMO(vamomaxw_v_w, int32_t, int32_t, idx_w) | ||
262 | -GEN_VEXT_AMO(vamominuw_v_w, uint32_t, uint32_t, idx_w) | ||
263 | -GEN_VEXT_AMO(vamomaxuw_v_w, uint32_t, uint32_t, idx_w) | ||
264 | - | ||
265 | /* | ||
266 | *** Vector Integer Arithmetic Instructions | ||
267 | */ | ||
268 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
269 | index XXXXXXX..XXXXXXX 100644 | ||
270 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
271 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
272 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_TRANS(vlbuff_v, 4, r2nfvm, ldff_op, ld_us_check) | ||
273 | GEN_VEXT_TRANS(vlhuff_v, 5, r2nfvm, ldff_op, ld_us_check) | ||
274 | GEN_VEXT_TRANS(vlwuff_v, 6, r2nfvm, ldff_op, ld_us_check) | ||
275 | |||
276 | -/* | ||
277 | - *** vector atomic operation | ||
278 | - */ | ||
279 | -typedef void gen_helper_amo(TCGv_ptr, TCGv_ptr, TCGv, TCGv_ptr, | ||
280 | - TCGv_env, TCGv_i32); | ||
281 | - | ||
282 | -static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
283 | - uint32_t data, gen_helper_amo *fn, DisasContext *s) | ||
284 | -{ | ||
285 | - TCGv_ptr dest, mask, index; | ||
286 | - TCGv base; | ||
287 | - TCGv_i32 desc; | ||
288 | - | ||
289 | - TCGLabel *over = gen_new_label(); | ||
290 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
291 | - | ||
292 | - dest = tcg_temp_new_ptr(); | ||
293 | - mask = tcg_temp_new_ptr(); | ||
294 | - index = tcg_temp_new_ptr(); | ||
295 | - base = get_gpr(s, rs1, EXT_NONE); | ||
296 | - desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
297 | - | ||
298 | - tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd)); | ||
299 | - tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2)); | ||
300 | - tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); | ||
301 | - | ||
302 | - fn(dest, mask, base, index, cpu_env, desc); | ||
303 | - | ||
304 | - tcg_temp_free_ptr(dest); | ||
305 | - tcg_temp_free_ptr(mask); | ||
306 | - tcg_temp_free_ptr(index); | ||
307 | - mark_vs_dirty(s); | ||
308 | - gen_set_label(over); | ||
309 | - return true; | ||
310 | -} | ||
311 | - | ||
312 | -static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq) | ||
313 | -{ | ||
314 | - uint32_t data = 0; | ||
315 | - gen_helper_amo *fn; | ||
316 | - static gen_helper_amo *const fnsw[9] = { | ||
317 | - /* no atomic operation */ | ||
318 | - gen_helper_vamoswapw_v_w, | ||
319 | - gen_helper_vamoaddw_v_w, | ||
320 | - gen_helper_vamoxorw_v_w, | ||
321 | - gen_helper_vamoandw_v_w, | ||
322 | - gen_helper_vamoorw_v_w, | ||
323 | - gen_helper_vamominw_v_w, | ||
324 | - gen_helper_vamomaxw_v_w, | ||
325 | - gen_helper_vamominuw_v_w, | ||
326 | - gen_helper_vamomaxuw_v_w | ||
327 | - }; | ||
328 | - static gen_helper_amo *const fnsd[18] = { | ||
329 | - gen_helper_vamoswapw_v_d, | ||
330 | - gen_helper_vamoaddw_v_d, | ||
331 | - gen_helper_vamoxorw_v_d, | ||
332 | - gen_helper_vamoandw_v_d, | ||
333 | - gen_helper_vamoorw_v_d, | ||
334 | - gen_helper_vamominw_v_d, | ||
335 | - gen_helper_vamomaxw_v_d, | ||
336 | - gen_helper_vamominuw_v_d, | ||
337 | - gen_helper_vamomaxuw_v_d, | ||
338 | - gen_helper_vamoswapd_v_d, | ||
339 | - gen_helper_vamoaddd_v_d, | ||
340 | - gen_helper_vamoxord_v_d, | ||
341 | - gen_helper_vamoandd_v_d, | ||
342 | - gen_helper_vamoord_v_d, | ||
343 | - gen_helper_vamomind_v_d, | ||
344 | - gen_helper_vamomaxd_v_d, | ||
345 | - gen_helper_vamominud_v_d, | ||
346 | - gen_helper_vamomaxud_v_d | ||
347 | - }; | ||
348 | - | ||
349 | - if (tb_cflags(s->base.tb) & CF_PARALLEL) { | ||
350 | - gen_helper_exit_atomic(cpu_env); | ||
351 | - s->base.is_jmp = DISAS_NORETURN; | ||
352 | - return true; | ||
353 | - } | ||
354 | - | ||
355 | - switch (s->sew) { | ||
356 | - case 0 ... 2: | ||
357 | - assert(seq < ARRAY_SIZE(fnsw)); | ||
358 | - fn = fnsw[seq]; | ||
359 | - break; | ||
360 | - case 3: | ||
361 | - /* XLEN check done in amo_check(). */ | ||
362 | - assert(seq < ARRAY_SIZE(fnsd)); | ||
363 | - fn = fnsd[seq]; | ||
364 | - break; | ||
365 | - default: | ||
366 | - g_assert_not_reached(); | ||
367 | - } | ||
368 | - | ||
369 | - data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
370 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
371 | - data = FIELD_DP32(data, VDATA, WD, a->wd); | ||
372 | - return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s); | ||
373 | -} | ||
374 | -/* | ||
375 | - * There are two rules check here. | ||
376 | - * | ||
377 | - * 1. SEW must be at least as wide as the AMO memory element size. | ||
378 | - * | ||
379 | - * 2. If SEW is greater than XLEN, an illegal instruction exception is raised. | ||
380 | - */ | ||
381 | -static bool amo_check(DisasContext *s, arg_rwdvm* a) | ||
382 | -{ | ||
383 | - return (!s->vill && has_ext(s, RVA) && | ||
384 | - (!a->wd || vext_check_overlap_mask(s, a->rd, a->vm, false)) && | ||
385 | - vext_check_reg(s, a->rd, false) && | ||
386 | - vext_check_reg(s, a->rs2, false) && | ||
387 | - ((1 << s->sew) <= sizeof(target_ulong)) && | ||
388 | - ((1 << s->sew) >= 4)); | ||
389 | -} | ||
390 | - | ||
391 | -static bool amo_check64(DisasContext *s, arg_rwdvm* a) | ||
392 | -{ | ||
393 | - REQUIRE_64BIT(s); | ||
394 | - return amo_check(s, a); | ||
395 | -} | ||
396 | - | ||
397 | -GEN_VEXT_TRANS(vamoswapw_v, 0, rwdvm, amo_op, amo_check) | ||
398 | -GEN_VEXT_TRANS(vamoaddw_v, 1, rwdvm, amo_op, amo_check) | ||
399 | -GEN_VEXT_TRANS(vamoxorw_v, 2, rwdvm, amo_op, amo_check) | ||
400 | -GEN_VEXT_TRANS(vamoandw_v, 3, rwdvm, amo_op, amo_check) | ||
401 | -GEN_VEXT_TRANS(vamoorw_v, 4, rwdvm, amo_op, amo_check) | ||
402 | -GEN_VEXT_TRANS(vamominw_v, 5, rwdvm, amo_op, amo_check) | ||
403 | -GEN_VEXT_TRANS(vamomaxw_v, 6, rwdvm, amo_op, amo_check) | ||
404 | -GEN_VEXT_TRANS(vamominuw_v, 7, rwdvm, amo_op, amo_check) | ||
405 | -GEN_VEXT_TRANS(vamomaxuw_v, 8, rwdvm, amo_op, amo_check) | ||
406 | -GEN_VEXT_TRANS(vamoswapd_v, 9, rwdvm, amo_op, amo_check64) | ||
407 | -GEN_VEXT_TRANS(vamoaddd_v, 10, rwdvm, amo_op, amo_check64) | ||
408 | -GEN_VEXT_TRANS(vamoxord_v, 11, rwdvm, amo_op, amo_check64) | ||
409 | -GEN_VEXT_TRANS(vamoandd_v, 12, rwdvm, amo_op, amo_check64) | ||
410 | -GEN_VEXT_TRANS(vamoord_v, 13, rwdvm, amo_op, amo_check64) | ||
411 | -GEN_VEXT_TRANS(vamomind_v, 14, rwdvm, amo_op, amo_check64) | ||
412 | -GEN_VEXT_TRANS(vamomaxd_v, 15, rwdvm, amo_op, amo_check64) | ||
413 | -GEN_VEXT_TRANS(vamominud_v, 16, rwdvm, amo_op, amo_check64) | ||
414 | -GEN_VEXT_TRANS(vamomaxud_v, 17, rwdvm, amo_op, amo_check64) | ||
415 | - | ||
416 | /* | ||
417 | *** Vector Integer Arithmetic Instructions | ||
418 | */ | ||
419 | -- | ||
420 | 2.31.1 | ||
421 | |||
422 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-20-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/vector_helper.c | 14 +++++- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++-------------- | ||
11 | 2 files changed, 40 insertions(+), 36 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/vector_helper.c | ||
16 | +++ b/target/riscv/vector_helper.c | ||
17 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1, | ||
18 | { | ||
19 | int vlmax, vl; | ||
20 | RISCVCPU *cpu = env_archcpu(env); | ||
21 | + uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL); | ||
22 | uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW); | ||
23 | uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV); | ||
24 | bool vill = FIELD_EX64(s2, VTYPE, VILL); | ||
25 | target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED); | ||
26 | |||
27 | - if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) { | ||
28 | + if (lmul & 4) { | ||
29 | + /* Fractional LMUL. */ | ||
30 | + if (lmul == 4 || | ||
31 | + cpu->cfg.elen >> (8 - lmul) < sew) { | ||
32 | + vill = true; | ||
33 | + } | ||
34 | + } | ||
35 | + | ||
36 | + if ((sew > cpu->cfg.elen) | ||
37 | + || vill | ||
38 | + || (ediv != 0) | ||
39 | + || (reserved != 0)) { | ||
40 | /* only set vill bit. */ | ||
41 | env->vtype = FIELD_DP64(0, VTYPE, VILL, 1); | ||
42 | env->vl = 0; | ||
43 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
46 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
47 | @@ -XXX,XX +XXX,XX @@ static bool require_noover(const int8_t dst, const int8_t dst_lmul, | ||
48 | return !is_overlapped(dst, dst_size, src, src_size); | ||
49 | } | ||
50 | |||
51 | -static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a) | ||
52 | +static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2) | ||
53 | { | ||
54 | - TCGv s1, s2, dst; | ||
55 | + TCGv s1, dst; | ||
56 | |||
57 | - if (!require_rvv(ctx) || !has_ext(ctx, RVV)) { | ||
58 | + if (!require_rvv(s) || !has_ext(s, RVV)) { | ||
59 | return false; | ||
60 | } | ||
61 | |||
62 | - s2 = get_gpr(ctx, a->rs2, EXT_ZERO); | ||
63 | - dst = dest_gpr(ctx, a->rd); | ||
64 | + dst = dest_gpr(s, rd); | ||
65 | |||
66 | - /* Using x0 as the rs1 register specifier, encodes an infinite AVL */ | ||
67 | - if (a->rs1 == 0) { | ||
68 | + if (rd == 0 && rs1 == 0) { | ||
69 | + s1 = tcg_temp_new(); | ||
70 | + tcg_gen_mov_tl(s1, cpu_vl); | ||
71 | + } else if (rs1 == 0) { | ||
72 | /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */ | ||
73 | s1 = tcg_constant_tl(RV_VLEN_MAX); | ||
74 | } else { | ||
75 | - s1 = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
76 | + s1 = get_gpr(s, rs1, EXT_ZERO); | ||
77 | } | ||
78 | + | ||
79 | gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
80 | - gen_set_gpr(ctx, a->rd, dst); | ||
81 | - mark_vs_dirty(ctx); | ||
82 | + gen_set_gpr(s, rd, dst); | ||
83 | + mark_vs_dirty(s); | ||
84 | |||
85 | - tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); | ||
86 | + tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn); | ||
87 | tcg_gen_lookup_and_goto_ptr(); | ||
88 | - ctx->base.is_jmp = DISAS_NORETURN; | ||
89 | - return true; | ||
90 | -} | ||
91 | + s->base.is_jmp = DISAS_NORETURN; | ||
92 | |||
93 | -static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a) | ||
94 | -{ | ||
95 | - TCGv s1, s2, dst; | ||
96 | - | ||
97 | - if (!require_rvv(ctx) || !has_ext(ctx, RVV)) { | ||
98 | - return false; | ||
99 | + if (rd == 0 && rs1 == 0) { | ||
100 | + tcg_temp_free(s1); | ||
101 | } | ||
102 | |||
103 | - s2 = tcg_constant_tl(a->zimm); | ||
104 | - dst = dest_gpr(ctx, a->rd); | ||
105 | + return true; | ||
106 | +} | ||
107 | |||
108 | - /* Using x0 as the rs1 register specifier, encodes an infinite AVL */ | ||
109 | - if (a->rs1 == 0) { | ||
110 | - /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */ | ||
111 | - s1 = tcg_constant_tl(RV_VLEN_MAX); | ||
112 | - } else { | ||
113 | - s1 = get_gpr(ctx, a->rs1, EXT_ZERO); | ||
114 | - } | ||
115 | - gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
116 | - gen_set_gpr(ctx, a->rd, dst); | ||
117 | - mark_vs_dirty(ctx); | ||
118 | +static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a) | ||
119 | +{ | ||
120 | + TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO); | ||
121 | + return do_vsetvl(s, a->rd, a->rs1, s2); | ||
122 | +} | ||
123 | |||
124 | - gen_goto_tb(ctx, 0, ctx->pc_succ_insn); | ||
125 | - ctx->base.is_jmp = DISAS_NORETURN; | ||
126 | - return true; | ||
127 | +static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a) | ||
128 | +{ | ||
129 | + TCGv s2 = tcg_constant_tl(a->zimm); | ||
130 | + return do_vsetvl(s, a->rd, a->rs1, s2); | ||
131 | } | ||
132 | |||
133 | /* vector register offset from env */ | ||
134 | -- | ||
135 | 2.31.1 | ||
136 | |||
137 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-21-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 129 ++------ | ||
9 | target/riscv/insn32.decode | 43 ++- | ||
10 | target/riscv/vector_helper.c | 199 +++++-------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 376 ++++++++++++------------ | ||
12 | 4 files changed, 300 insertions(+), 447 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl) | ||
19 | |||
20 | /* Vector functions */ | ||
21 | DEF_HELPER_3(vsetvl, tl, env, tl, tl) | ||
22 | -DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32) | ||
23 | -DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32) | ||
24 | -DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32) | ||
25 | -DEF_HELPER_5(vlb_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
26 | -DEF_HELPER_5(vlb_v_w, void, ptr, ptr, tl, env, i32) | ||
27 | -DEF_HELPER_5(vlb_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
28 | -DEF_HELPER_5(vlb_v_d, void, ptr, ptr, tl, env, i32) | ||
29 | -DEF_HELPER_5(vlb_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
30 | -DEF_HELPER_5(vlh_v_h, void, ptr, ptr, tl, env, i32) | ||
31 | -DEF_HELPER_5(vlh_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
32 | -DEF_HELPER_5(vlh_v_w, void, ptr, ptr, tl, env, i32) | ||
33 | -DEF_HELPER_5(vlh_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
34 | -DEF_HELPER_5(vlh_v_d, void, ptr, ptr, tl, env, i32) | ||
35 | -DEF_HELPER_5(vlh_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
36 | -DEF_HELPER_5(vlw_v_w, void, ptr, ptr, tl, env, i32) | ||
37 | -DEF_HELPER_5(vlw_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
38 | -DEF_HELPER_5(vlw_v_d, void, ptr, ptr, tl, env, i32) | ||
39 | -DEF_HELPER_5(vlw_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
40 | -DEF_HELPER_5(vle_v_b, void, ptr, ptr, tl, env, i32) | ||
41 | -DEF_HELPER_5(vle_v_b_mask, void, ptr, ptr, tl, env, i32) | ||
42 | -DEF_HELPER_5(vle_v_h, void, ptr, ptr, tl, env, i32) | ||
43 | -DEF_HELPER_5(vle_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
44 | -DEF_HELPER_5(vle_v_w, void, ptr, ptr, tl, env, i32) | ||
45 | -DEF_HELPER_5(vle_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
46 | -DEF_HELPER_5(vle_v_d, void, ptr, ptr, tl, env, i32) | ||
47 | -DEF_HELPER_5(vle_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
48 | -DEF_HELPER_5(vlbu_v_b, void, ptr, ptr, tl, env, i32) | ||
49 | -DEF_HELPER_5(vlbu_v_b_mask, void, ptr, ptr, tl, env, i32) | ||
50 | -DEF_HELPER_5(vlbu_v_h, void, ptr, ptr, tl, env, i32) | ||
51 | -DEF_HELPER_5(vlbu_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
52 | -DEF_HELPER_5(vlbu_v_w, void, ptr, ptr, tl, env, i32) | ||
53 | -DEF_HELPER_5(vlbu_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
54 | -DEF_HELPER_5(vlbu_v_d, void, ptr, ptr, tl, env, i32) | ||
55 | -DEF_HELPER_5(vlbu_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
56 | -DEF_HELPER_5(vlhu_v_h, void, ptr, ptr, tl, env, i32) | ||
57 | -DEF_HELPER_5(vlhu_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
58 | -DEF_HELPER_5(vlhu_v_w, void, ptr, ptr, tl, env, i32) | ||
59 | -DEF_HELPER_5(vlhu_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
60 | -DEF_HELPER_5(vlhu_v_d, void, ptr, ptr, tl, env, i32) | ||
61 | -DEF_HELPER_5(vlhu_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
62 | -DEF_HELPER_5(vlwu_v_w, void, ptr, ptr, tl, env, i32) | ||
63 | -DEF_HELPER_5(vlwu_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
64 | -DEF_HELPER_5(vlwu_v_d, void, ptr, ptr, tl, env, i32) | ||
65 | -DEF_HELPER_5(vlwu_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
66 | -DEF_HELPER_5(vsb_v_b, void, ptr, ptr, tl, env, i32) | ||
67 | -DEF_HELPER_5(vsb_v_b_mask, void, ptr, ptr, tl, env, i32) | ||
68 | -DEF_HELPER_5(vsb_v_h, void, ptr, ptr, tl, env, i32) | ||
69 | -DEF_HELPER_5(vsb_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
70 | -DEF_HELPER_5(vsb_v_w, void, ptr, ptr, tl, env, i32) | ||
71 | -DEF_HELPER_5(vsb_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
72 | -DEF_HELPER_5(vsb_v_d, void, ptr, ptr, tl, env, i32) | ||
73 | -DEF_HELPER_5(vsb_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
74 | -DEF_HELPER_5(vsh_v_h, void, ptr, ptr, tl, env, i32) | ||
75 | -DEF_HELPER_5(vsh_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
76 | -DEF_HELPER_5(vsh_v_w, void, ptr, ptr, tl, env, i32) | ||
77 | -DEF_HELPER_5(vsh_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
78 | -DEF_HELPER_5(vsh_v_d, void, ptr, ptr, tl, env, i32) | ||
79 | -DEF_HELPER_5(vsh_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
80 | -DEF_HELPER_5(vsw_v_w, void, ptr, ptr, tl, env, i32) | ||
81 | -DEF_HELPER_5(vsw_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
82 | -DEF_HELPER_5(vsw_v_d, void, ptr, ptr, tl, env, i32) | ||
83 | -DEF_HELPER_5(vsw_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
84 | -DEF_HELPER_5(vse_v_b, void, ptr, ptr, tl, env, i32) | ||
85 | -DEF_HELPER_5(vse_v_b_mask, void, ptr, ptr, tl, env, i32) | ||
86 | -DEF_HELPER_5(vse_v_h, void, ptr, ptr, tl, env, i32) | ||
87 | -DEF_HELPER_5(vse_v_h_mask, void, ptr, ptr, tl, env, i32) | ||
88 | -DEF_HELPER_5(vse_v_w, void, ptr, ptr, tl, env, i32) | ||
89 | -DEF_HELPER_5(vse_v_w_mask, void, ptr, ptr, tl, env, i32) | ||
90 | -DEF_HELPER_5(vse_v_d, void, ptr, ptr, tl, env, i32) | ||
91 | -DEF_HELPER_5(vse_v_d_mask, void, ptr, ptr, tl, env, i32) | ||
92 | -DEF_HELPER_6(vlsb_v_b, void, ptr, ptr, tl, tl, env, i32) | ||
93 | -DEF_HELPER_6(vlsb_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
94 | -DEF_HELPER_6(vlsb_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
95 | -DEF_HELPER_6(vlsb_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
96 | -DEF_HELPER_6(vlsh_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
97 | -DEF_HELPER_6(vlsh_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
98 | -DEF_HELPER_6(vlsh_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
99 | -DEF_HELPER_6(vlsw_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
100 | -DEF_HELPER_6(vlsw_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
101 | -DEF_HELPER_6(vlse_v_b, void, ptr, ptr, tl, tl, env, i32) | ||
102 | -DEF_HELPER_6(vlse_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
103 | -DEF_HELPER_6(vlse_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
104 | -DEF_HELPER_6(vlse_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
105 | -DEF_HELPER_6(vlsbu_v_b, void, ptr, ptr, tl, tl, env, i32) | ||
106 | -DEF_HELPER_6(vlsbu_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
107 | -DEF_HELPER_6(vlsbu_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
108 | -DEF_HELPER_6(vlsbu_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
109 | -DEF_HELPER_6(vlshu_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
110 | -DEF_HELPER_6(vlshu_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
111 | -DEF_HELPER_6(vlshu_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
112 | -DEF_HELPER_6(vlswu_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
113 | -DEF_HELPER_6(vlswu_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
114 | -DEF_HELPER_6(vssb_v_b, void, ptr, ptr, tl, tl, env, i32) | ||
115 | -DEF_HELPER_6(vssb_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
116 | -DEF_HELPER_6(vssb_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
117 | -DEF_HELPER_6(vssb_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
118 | -DEF_HELPER_6(vssh_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
119 | -DEF_HELPER_6(vssh_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
120 | -DEF_HELPER_6(vssh_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
121 | -DEF_HELPER_6(vssw_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
122 | -DEF_HELPER_6(vssw_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
123 | -DEF_HELPER_6(vsse_v_b, void, ptr, ptr, tl, tl, env, i32) | ||
124 | -DEF_HELPER_6(vsse_v_h, void, ptr, ptr, tl, tl, env, i32) | ||
125 | -DEF_HELPER_6(vsse_v_w, void, ptr, ptr, tl, tl, env, i32) | ||
126 | -DEF_HELPER_6(vsse_v_d, void, ptr, ptr, tl, tl, env, i32) | ||
127 | +DEF_HELPER_5(vle8_v, void, ptr, ptr, tl, env, i32) | ||
128 | +DEF_HELPER_5(vle16_v, void, ptr, ptr, tl, env, i32) | ||
129 | +DEF_HELPER_5(vle32_v, void, ptr, ptr, tl, env, i32) | ||
130 | +DEF_HELPER_5(vle64_v, void, ptr, ptr, tl, env, i32) | ||
131 | +DEF_HELPER_5(vle8_v_mask, void, ptr, ptr, tl, env, i32) | ||
132 | +DEF_HELPER_5(vle16_v_mask, void, ptr, ptr, tl, env, i32) | ||
133 | +DEF_HELPER_5(vle32_v_mask, void, ptr, ptr, tl, env, i32) | ||
134 | +DEF_HELPER_5(vle64_v_mask, void, ptr, ptr, tl, env, i32) | ||
135 | +DEF_HELPER_5(vse8_v, void, ptr, ptr, tl, env, i32) | ||
136 | +DEF_HELPER_5(vse16_v, void, ptr, ptr, tl, env, i32) | ||
137 | +DEF_HELPER_5(vse32_v, void, ptr, ptr, tl, env, i32) | ||
138 | +DEF_HELPER_5(vse64_v, void, ptr, ptr, tl, env, i32) | ||
139 | +DEF_HELPER_5(vse8_v_mask, void, ptr, ptr, tl, env, i32) | ||
140 | +DEF_HELPER_5(vse16_v_mask, void, ptr, ptr, tl, env, i32) | ||
141 | +DEF_HELPER_5(vse32_v_mask, void, ptr, ptr, tl, env, i32) | ||
142 | +DEF_HELPER_5(vse64_v_mask, void, ptr, ptr, tl, env, i32) | ||
143 | +DEF_HELPER_6(vlse8_v, void, ptr, ptr, tl, tl, env, i32) | ||
144 | +DEF_HELPER_6(vlse16_v, void, ptr, ptr, tl, tl, env, i32) | ||
145 | +DEF_HELPER_6(vlse32_v, void, ptr, ptr, tl, tl, env, i32) | ||
146 | +DEF_HELPER_6(vlse64_v, void, ptr, ptr, tl, tl, env, i32) | ||
147 | +DEF_HELPER_6(vsse8_v, void, ptr, ptr, tl, tl, env, i32) | ||
148 | +DEF_HELPER_6(vsse16_v, void, ptr, ptr, tl, tl, env, i32) | ||
149 | +DEF_HELPER_6(vsse32_v, void, ptr, ptr, tl, tl, env, i32) | ||
150 | +DEF_HELPER_6(vsse64_v, void, ptr, ptr, tl, tl, env, i32) | ||
151 | DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
152 | DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
153 | DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
154 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
155 | index XXXXXXX..XXXXXXX 100644 | ||
156 | --- a/target/riscv/insn32.decode | ||
157 | +++ b/target/riscv/insn32.decode | ||
158 | @@ -XXX,XX +XXX,XX @@ hlv_d 0110110 00000 ..... 100 ..... 1110011 @r2 | ||
159 | hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s | ||
160 | |||
161 | # *** Vector loads and stores are encoded within LOADFP/STORE-FP *** | ||
162 | -vlb_v ... 100 . 00000 ..... 000 ..... 0000111 @r2_nfvm | ||
163 | -vlh_v ... 100 . 00000 ..... 101 ..... 0000111 @r2_nfvm | ||
164 | -vlw_v ... 100 . 00000 ..... 110 ..... 0000111 @r2_nfvm | ||
165 | -vle_v ... 000 . 00000 ..... 111 ..... 0000111 @r2_nfvm | ||
166 | -vlbu_v ... 000 . 00000 ..... 000 ..... 0000111 @r2_nfvm | ||
167 | -vlhu_v ... 000 . 00000 ..... 101 ..... 0000111 @r2_nfvm | ||
168 | -vlwu_v ... 000 . 00000 ..... 110 ..... 0000111 @r2_nfvm | ||
169 | +# Vector unit-stride load/store insns. | ||
170 | +vle8_v ... 000 . 00000 ..... 000 ..... 0000111 @r2_nfvm | ||
171 | +vle16_v ... 000 . 00000 ..... 101 ..... 0000111 @r2_nfvm | ||
172 | +vle32_v ... 000 . 00000 ..... 110 ..... 0000111 @r2_nfvm | ||
173 | +vle64_v ... 000 . 00000 ..... 111 ..... 0000111 @r2_nfvm | ||
174 | +vse8_v ... 000 . 00000 ..... 000 ..... 0100111 @r2_nfvm | ||
175 | +vse16_v ... 000 . 00000 ..... 101 ..... 0100111 @r2_nfvm | ||
176 | +vse32_v ... 000 . 00000 ..... 110 ..... 0100111 @r2_nfvm | ||
177 | +vse64_v ... 000 . 00000 ..... 111 ..... 0100111 @r2_nfvm | ||
178 | + | ||
179 | +# Vector strided insns. | ||
180 | +vlse8_v ... 010 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
181 | +vlse16_v ... 010 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
182 | +vlse32_v ... 010 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
183 | +vlse64_v ... 010 . ..... ..... 111 ..... 0000111 @r_nfvm | ||
184 | +vsse8_v ... 010 . ..... ..... 000 ..... 0100111 @r_nfvm | ||
185 | +vsse16_v ... 010 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
186 | +vsse32_v ... 010 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
187 | +vsse64_v ... 010 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
188 | + | ||
189 | vlbff_v ... 100 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
190 | vlhff_v ... 100 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
191 | vlwff_v ... 100 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
192 | @@ -XXX,XX +XXX,XX @@ vleff_v ... 000 . 10000 ..... 111 ..... 0000111 @r2_nfvm | ||
193 | vlbuff_v ... 000 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
194 | vlhuff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
195 | vlwuff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
196 | -vsb_v ... 000 . 00000 ..... 000 ..... 0100111 @r2_nfvm | ||
197 | -vsh_v ... 000 . 00000 ..... 101 ..... 0100111 @r2_nfvm | ||
198 | -vsw_v ... 000 . 00000 ..... 110 ..... 0100111 @r2_nfvm | ||
199 | -vse_v ... 000 . 00000 ..... 111 ..... 0100111 @r2_nfvm | ||
200 | - | ||
201 | -vlsb_v ... 110 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
202 | -vlsh_v ... 110 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
203 | -vlsw_v ... 110 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
204 | -vlse_v ... 010 . ..... ..... 111 ..... 0000111 @r_nfvm | ||
205 | -vlsbu_v ... 010 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
206 | -vlshu_v ... 010 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
207 | -vlswu_v ... 010 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
208 | -vssb_v ... 010 . ..... ..... 000 ..... 0100111 @r_nfvm | ||
209 | -vssh_v ... 010 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
210 | -vssw_v ... 010 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
211 | -vsse_v ... 010 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
212 | |||
213 | vlxb_v ... 111 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
214 | vlxh_v ... 111 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
215 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
216 | index XXXXXXX..XXXXXXX 100644 | ||
217 | --- a/target/riscv/vector_helper.c | ||
218 | +++ b/target/riscv/vector_helper.c | ||
219 | @@ -XXX,XX +XXX,XX @@ static inline int vext_elem_mask(void *v0, int index) | ||
220 | typedef void vext_ldst_elem_fn(CPURISCVState *env, target_ulong addr, | ||
221 | uint32_t idx, void *vd, uintptr_t retaddr); | ||
222 | |||
223 | -#define GEN_VEXT_LD_ELEM(NAME, MTYPE, ETYPE, H, LDSUF) \ | ||
224 | +#define GEN_VEXT_LD_ELEM(NAME, ETYPE, H, LDSUF) \ | ||
225 | static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
226 | uint32_t idx, void *vd, uintptr_t retaddr)\ | ||
227 | { \ | ||
228 | - MTYPE data; \ | ||
229 | ETYPE *cur = ((ETYPE *)vd + H(idx)); \ | ||
230 | - data = cpu_##LDSUF##_data_ra(env, addr, retaddr); \ | ||
231 | - *cur = data; \ | ||
232 | + *cur = cpu_##LDSUF##_data_ra(env, addr, retaddr); \ | ||
233 | } \ | ||
234 | |||
235 | -GEN_VEXT_LD_ELEM(ldb_b, int8_t, int8_t, H1, ldsb) | ||
236 | -GEN_VEXT_LD_ELEM(ldb_h, int8_t, int16_t, H2, ldsb) | ||
237 | -GEN_VEXT_LD_ELEM(ldb_w, int8_t, int32_t, H4, ldsb) | ||
238 | -GEN_VEXT_LD_ELEM(ldb_d, int8_t, int64_t, H8, ldsb) | ||
239 | -GEN_VEXT_LD_ELEM(ldh_h, int16_t, int16_t, H2, ldsw) | ||
240 | -GEN_VEXT_LD_ELEM(ldh_w, int16_t, int32_t, H4, ldsw) | ||
241 | -GEN_VEXT_LD_ELEM(ldh_d, int16_t, int64_t, H8, ldsw) | ||
242 | -GEN_VEXT_LD_ELEM(ldw_w, int32_t, int32_t, H4, ldl) | ||
243 | -GEN_VEXT_LD_ELEM(ldw_d, int32_t, int64_t, H8, ldl) | ||
244 | -GEN_VEXT_LD_ELEM(lde_b, int8_t, int8_t, H1, ldsb) | ||
245 | -GEN_VEXT_LD_ELEM(lde_h, int16_t, int16_t, H2, ldsw) | ||
246 | -GEN_VEXT_LD_ELEM(lde_w, int32_t, int32_t, H4, ldl) | ||
247 | -GEN_VEXT_LD_ELEM(lde_d, int64_t, int64_t, H8, ldq) | ||
248 | -GEN_VEXT_LD_ELEM(ldbu_b, uint8_t, uint8_t, H1, ldub) | ||
249 | -GEN_VEXT_LD_ELEM(ldbu_h, uint8_t, uint16_t, H2, ldub) | ||
250 | -GEN_VEXT_LD_ELEM(ldbu_w, uint8_t, uint32_t, H4, ldub) | ||
251 | -GEN_VEXT_LD_ELEM(ldbu_d, uint8_t, uint64_t, H8, ldub) | ||
252 | -GEN_VEXT_LD_ELEM(ldhu_h, uint16_t, uint16_t, H2, lduw) | ||
253 | -GEN_VEXT_LD_ELEM(ldhu_w, uint16_t, uint32_t, H4, lduw) | ||
254 | -GEN_VEXT_LD_ELEM(ldhu_d, uint16_t, uint64_t, H8, lduw) | ||
255 | -GEN_VEXT_LD_ELEM(ldwu_w, uint32_t, uint32_t, H4, ldl) | ||
256 | -GEN_VEXT_LD_ELEM(ldwu_d, uint32_t, uint64_t, H8, ldl) | ||
257 | +GEN_VEXT_LD_ELEM(ldb_b, int8_t, H1, ldsb) | ||
258 | +GEN_VEXT_LD_ELEM(ldb_h, int16_t, H2, ldsb) | ||
259 | +GEN_VEXT_LD_ELEM(ldb_w, int32_t, H4, ldsb) | ||
260 | +GEN_VEXT_LD_ELEM(ldb_d, int64_t, H8, ldsb) | ||
261 | +GEN_VEXT_LD_ELEM(ldh_h, int16_t, H2, ldsw) | ||
262 | +GEN_VEXT_LD_ELEM(ldh_w, int32_t, H4, ldsw) | ||
263 | +GEN_VEXT_LD_ELEM(ldh_d, int64_t, H8, ldsw) | ||
264 | +GEN_VEXT_LD_ELEM(ldw_w, int32_t, H4, ldl) | ||
265 | +GEN_VEXT_LD_ELEM(ldw_d, int64_t, H8, ldl) | ||
266 | +GEN_VEXT_LD_ELEM(lde_b, int8_t, H1, ldsb) | ||
267 | +GEN_VEXT_LD_ELEM(lde_h, int16_t, H2, ldsw) | ||
268 | +GEN_VEXT_LD_ELEM(lde_w, int32_t, H4, ldl) | ||
269 | +GEN_VEXT_LD_ELEM(lde_d, int64_t, H8, ldq) | ||
270 | +GEN_VEXT_LD_ELEM(ldbu_b, uint8_t, H1, ldub) | ||
271 | +GEN_VEXT_LD_ELEM(ldbu_h, uint16_t, H2, ldub) | ||
272 | +GEN_VEXT_LD_ELEM(ldbu_w, uint32_t, H4, ldub) | ||
273 | +GEN_VEXT_LD_ELEM(ldbu_d, uint64_t, H8, ldub) | ||
274 | +GEN_VEXT_LD_ELEM(ldhu_h, uint16_t, H2, lduw) | ||
275 | +GEN_VEXT_LD_ELEM(ldhu_w, uint32_t, H4, lduw) | ||
276 | +GEN_VEXT_LD_ELEM(ldhu_d, uint64_t, H8, lduw) | ||
277 | +GEN_VEXT_LD_ELEM(ldwu_w, uint32_t, H4, ldl) | ||
278 | +GEN_VEXT_LD_ELEM(ldwu_d, uint64_t, H8, ldl) | ||
279 | |||
280 | #define GEN_VEXT_ST_ELEM(NAME, ETYPE, H, STSUF) \ | ||
281 | static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
282 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
283 | target_ulong stride, CPURISCVState *env, | ||
284 | uint32_t desc, uint32_t vm, | ||
285 | vext_ldst_elem_fn *ldst_elem, | ||
286 | - uint32_t esz, uint32_t msz, uintptr_t ra, | ||
287 | - MMUAccessType access_type) | ||
288 | + uint32_t esz, uintptr_t ra, MMUAccessType access_type) | ||
289 | { | ||
290 | uint32_t i, k; | ||
291 | uint32_t nf = vext_nf(desc); | ||
292 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
293 | if (!vm && !vext_elem_mask(v0, i)) { | ||
294 | continue; | ||
295 | } | ||
296 | - probe_pages(env, base + stride * i, nf * msz, ra, access_type); | ||
297 | + probe_pages(env, base + stride * i, nf * esz, ra, access_type); | ||
298 | } | ||
299 | /* do real access */ | ||
300 | for (i = 0; i < env->vl; i++) { | ||
301 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
302 | continue; | ||
303 | } | ||
304 | while (k < nf) { | ||
305 | - target_ulong addr = base + stride * i + k * msz; | ||
306 | + target_ulong addr = base + stride * i + k * esz; | ||
307 | ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
308 | k++; | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | -#define GEN_VEXT_LD_STRIDE(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
314 | +#define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN) \ | ||
315 | void HELPER(NAME)(void *vd, void * v0, target_ulong base, \ | ||
316 | target_ulong stride, CPURISCVState *env, \ | ||
317 | uint32_t desc) \ | ||
318 | { \ | ||
319 | uint32_t vm = vext_vm(desc); \ | ||
320 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \ | ||
321 | - sizeof(ETYPE), sizeof(MTYPE), \ | ||
322 | - GETPC(), MMU_DATA_LOAD); \ | ||
323 | -} | ||
324 | - | ||
325 | -GEN_VEXT_LD_STRIDE(vlsb_v_b, int8_t, int8_t, ldb_b) | ||
326 | -GEN_VEXT_LD_STRIDE(vlsb_v_h, int8_t, int16_t, ldb_h) | ||
327 | -GEN_VEXT_LD_STRIDE(vlsb_v_w, int8_t, int32_t, ldb_w) | ||
328 | -GEN_VEXT_LD_STRIDE(vlsb_v_d, int8_t, int64_t, ldb_d) | ||
329 | -GEN_VEXT_LD_STRIDE(vlsh_v_h, int16_t, int16_t, ldh_h) | ||
330 | -GEN_VEXT_LD_STRIDE(vlsh_v_w, int16_t, int32_t, ldh_w) | ||
331 | -GEN_VEXT_LD_STRIDE(vlsh_v_d, int16_t, int64_t, ldh_d) | ||
332 | -GEN_VEXT_LD_STRIDE(vlsw_v_w, int32_t, int32_t, ldw_w) | ||
333 | -GEN_VEXT_LD_STRIDE(vlsw_v_d, int32_t, int64_t, ldw_d) | ||
334 | -GEN_VEXT_LD_STRIDE(vlse_v_b, int8_t, int8_t, lde_b) | ||
335 | -GEN_VEXT_LD_STRIDE(vlse_v_h, int16_t, int16_t, lde_h) | ||
336 | -GEN_VEXT_LD_STRIDE(vlse_v_w, int32_t, int32_t, lde_w) | ||
337 | -GEN_VEXT_LD_STRIDE(vlse_v_d, int64_t, int64_t, lde_d) | ||
338 | -GEN_VEXT_LD_STRIDE(vlsbu_v_b, uint8_t, uint8_t, ldbu_b) | ||
339 | -GEN_VEXT_LD_STRIDE(vlsbu_v_h, uint8_t, uint16_t, ldbu_h) | ||
340 | -GEN_VEXT_LD_STRIDE(vlsbu_v_w, uint8_t, uint32_t, ldbu_w) | ||
341 | -GEN_VEXT_LD_STRIDE(vlsbu_v_d, uint8_t, uint64_t, ldbu_d) | ||
342 | -GEN_VEXT_LD_STRIDE(vlshu_v_h, uint16_t, uint16_t, ldhu_h) | ||
343 | -GEN_VEXT_LD_STRIDE(vlshu_v_w, uint16_t, uint32_t, ldhu_w) | ||
344 | -GEN_VEXT_LD_STRIDE(vlshu_v_d, uint16_t, uint64_t, ldhu_d) | ||
345 | -GEN_VEXT_LD_STRIDE(vlswu_v_w, uint32_t, uint32_t, ldwu_w) | ||
346 | -GEN_VEXT_LD_STRIDE(vlswu_v_d, uint32_t, uint64_t, ldwu_d) | ||
347 | - | ||
348 | -#define GEN_VEXT_ST_STRIDE(NAME, MTYPE, ETYPE, STORE_FN) \ | ||
349 | + sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
350 | +} | ||
351 | + | ||
352 | +GEN_VEXT_LD_STRIDE(vlse8_v, int8_t, lde_b) | ||
353 | +GEN_VEXT_LD_STRIDE(vlse16_v, int16_t, lde_h) | ||
354 | +GEN_VEXT_LD_STRIDE(vlse32_v, int32_t, lde_w) | ||
355 | +GEN_VEXT_LD_STRIDE(vlse64_v, int64_t, lde_d) | ||
356 | + | ||
357 | +#define GEN_VEXT_ST_STRIDE(NAME, ETYPE, STORE_FN) \ | ||
358 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
359 | target_ulong stride, CPURISCVState *env, \ | ||
360 | uint32_t desc) \ | ||
361 | { \ | ||
362 | uint32_t vm = vext_vm(desc); \ | ||
363 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN, \ | ||
364 | - sizeof(ETYPE), sizeof(MTYPE), \ | ||
365 | - GETPC(), MMU_DATA_STORE); \ | ||
366 | -} | ||
367 | - | ||
368 | -GEN_VEXT_ST_STRIDE(vssb_v_b, int8_t, int8_t, stb_b) | ||
369 | -GEN_VEXT_ST_STRIDE(vssb_v_h, int8_t, int16_t, stb_h) | ||
370 | -GEN_VEXT_ST_STRIDE(vssb_v_w, int8_t, int32_t, stb_w) | ||
371 | -GEN_VEXT_ST_STRIDE(vssb_v_d, int8_t, int64_t, stb_d) | ||
372 | -GEN_VEXT_ST_STRIDE(vssh_v_h, int16_t, int16_t, sth_h) | ||
373 | -GEN_VEXT_ST_STRIDE(vssh_v_w, int16_t, int32_t, sth_w) | ||
374 | -GEN_VEXT_ST_STRIDE(vssh_v_d, int16_t, int64_t, sth_d) | ||
375 | -GEN_VEXT_ST_STRIDE(vssw_v_w, int32_t, int32_t, stw_w) | ||
376 | -GEN_VEXT_ST_STRIDE(vssw_v_d, int32_t, int64_t, stw_d) | ||
377 | -GEN_VEXT_ST_STRIDE(vsse_v_b, int8_t, int8_t, ste_b) | ||
378 | -GEN_VEXT_ST_STRIDE(vsse_v_h, int16_t, int16_t, ste_h) | ||
379 | -GEN_VEXT_ST_STRIDE(vsse_v_w, int32_t, int32_t, ste_w) | ||
380 | -GEN_VEXT_ST_STRIDE(vsse_v_d, int64_t, int64_t, ste_d) | ||
381 | + sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
382 | +} | ||
383 | + | ||
384 | +GEN_VEXT_ST_STRIDE(vsse8_v, int8_t, ste_b) | ||
385 | +GEN_VEXT_ST_STRIDE(vsse16_v, int16_t, ste_h) | ||
386 | +GEN_VEXT_ST_STRIDE(vsse32_v, int32_t, ste_w) | ||
387 | +GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d) | ||
388 | |||
389 | /* | ||
390 | *** unit-stride: access elements stored contiguously in memory | ||
391 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_STRIDE(vsse_v_d, int64_t, int64_t, ste_d) | ||
392 | /* unmasked unit-stride load and store operation*/ | ||
393 | static void | ||
394 | vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
395 | - vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t msz, | ||
396 | - uintptr_t ra, MMUAccessType access_type) | ||
397 | + vext_ldst_elem_fn *ldst_elem, | ||
398 | + uint32_t esz, uintptr_t ra, MMUAccessType access_type) | ||
399 | { | ||
400 | uint32_t i, k; | ||
401 | uint32_t nf = vext_nf(desc); | ||
402 | uint32_t vlmax = vext_maxsz(desc) / esz; | ||
403 | |||
404 | /* probe every access */ | ||
405 | - probe_pages(env, base, env->vl * nf * msz, ra, access_type); | ||
406 | + probe_pages(env, base, env->vl * nf * esz, ra, access_type); | ||
407 | /* load bytes from guest memory */ | ||
408 | for (i = 0; i < env->vl; i++) { | ||
409 | k = 0; | ||
410 | while (k < nf) { | ||
411 | - target_ulong addr = base + (i * nf + k) * msz; | ||
412 | + target_ulong addr = base + (i * nf + k) * esz; | ||
413 | ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
414 | k++; | ||
415 | } | ||
416 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
417 | * stride = NF * sizeof (MTYPE) | ||
418 | */ | ||
419 | |||
420 | -#define GEN_VEXT_LD_US(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
421 | +#define GEN_VEXT_LD_US(NAME, ETYPE, LOAD_FN) \ | ||
422 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
423 | CPURISCVState *env, uint32_t desc) \ | ||
424 | { \ | ||
425 | - uint32_t stride = vext_nf(desc) * sizeof(MTYPE); \ | ||
426 | + uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \ | ||
427 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN, \ | ||
428 | - sizeof(ETYPE), sizeof(MTYPE), \ | ||
429 | - GETPC(), MMU_DATA_LOAD); \ | ||
430 | + sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
431 | } \ | ||
432 | \ | ||
433 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
434 | CPURISCVState *env, uint32_t desc) \ | ||
435 | { \ | ||
436 | vext_ldst_us(vd, base, env, desc, LOAD_FN, \ | ||
437 | - sizeof(ETYPE), sizeof(MTYPE), GETPC(), MMU_DATA_LOAD); \ | ||
438 | -} | ||
439 | - | ||
440 | -GEN_VEXT_LD_US(vlb_v_b, int8_t, int8_t, ldb_b) | ||
441 | -GEN_VEXT_LD_US(vlb_v_h, int8_t, int16_t, ldb_h) | ||
442 | -GEN_VEXT_LD_US(vlb_v_w, int8_t, int32_t, ldb_w) | ||
443 | -GEN_VEXT_LD_US(vlb_v_d, int8_t, int64_t, ldb_d) | ||
444 | -GEN_VEXT_LD_US(vlh_v_h, int16_t, int16_t, ldh_h) | ||
445 | -GEN_VEXT_LD_US(vlh_v_w, int16_t, int32_t, ldh_w) | ||
446 | -GEN_VEXT_LD_US(vlh_v_d, int16_t, int64_t, ldh_d) | ||
447 | -GEN_VEXT_LD_US(vlw_v_w, int32_t, int32_t, ldw_w) | ||
448 | -GEN_VEXT_LD_US(vlw_v_d, int32_t, int64_t, ldw_d) | ||
449 | -GEN_VEXT_LD_US(vle_v_b, int8_t, int8_t, lde_b) | ||
450 | -GEN_VEXT_LD_US(vle_v_h, int16_t, int16_t, lde_h) | ||
451 | -GEN_VEXT_LD_US(vle_v_w, int32_t, int32_t, lde_w) | ||
452 | -GEN_VEXT_LD_US(vle_v_d, int64_t, int64_t, lde_d) | ||
453 | -GEN_VEXT_LD_US(vlbu_v_b, uint8_t, uint8_t, ldbu_b) | ||
454 | -GEN_VEXT_LD_US(vlbu_v_h, uint8_t, uint16_t, ldbu_h) | ||
455 | -GEN_VEXT_LD_US(vlbu_v_w, uint8_t, uint32_t, ldbu_w) | ||
456 | -GEN_VEXT_LD_US(vlbu_v_d, uint8_t, uint64_t, ldbu_d) | ||
457 | -GEN_VEXT_LD_US(vlhu_v_h, uint16_t, uint16_t, ldhu_h) | ||
458 | -GEN_VEXT_LD_US(vlhu_v_w, uint16_t, uint32_t, ldhu_w) | ||
459 | -GEN_VEXT_LD_US(vlhu_v_d, uint16_t, uint64_t, ldhu_d) | ||
460 | -GEN_VEXT_LD_US(vlwu_v_w, uint32_t, uint32_t, ldwu_w) | ||
461 | -GEN_VEXT_LD_US(vlwu_v_d, uint32_t, uint64_t, ldwu_d) | ||
462 | - | ||
463 | -#define GEN_VEXT_ST_US(NAME, MTYPE, ETYPE, STORE_FN) \ | ||
464 | + sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
465 | +} | ||
466 | + | ||
467 | +GEN_VEXT_LD_US(vle8_v, int8_t, lde_b) | ||
468 | +GEN_VEXT_LD_US(vle16_v, int16_t, lde_h) | ||
469 | +GEN_VEXT_LD_US(vle32_v, int32_t, lde_w) | ||
470 | +GEN_VEXT_LD_US(vle64_v, int64_t, lde_d) | ||
471 | + | ||
472 | +#define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN) \ | ||
473 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
474 | CPURISCVState *env, uint32_t desc) \ | ||
475 | { \ | ||
476 | - uint32_t stride = vext_nf(desc) * sizeof(MTYPE); \ | ||
477 | + uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \ | ||
478 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \ | ||
479 | - sizeof(ETYPE), sizeof(MTYPE), \ | ||
480 | - GETPC(), MMU_DATA_STORE); \ | ||
481 | + sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
482 | } \ | ||
483 | \ | ||
484 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
485 | CPURISCVState *env, uint32_t desc) \ | ||
486 | { \ | ||
487 | vext_ldst_us(vd, base, env, desc, STORE_FN, \ | ||
488 | - sizeof(ETYPE), sizeof(MTYPE), GETPC(), MMU_DATA_STORE);\ | ||
489 | -} | ||
490 | - | ||
491 | -GEN_VEXT_ST_US(vsb_v_b, int8_t, int8_t , stb_b) | ||
492 | -GEN_VEXT_ST_US(vsb_v_h, int8_t, int16_t, stb_h) | ||
493 | -GEN_VEXT_ST_US(vsb_v_w, int8_t, int32_t, stb_w) | ||
494 | -GEN_VEXT_ST_US(vsb_v_d, int8_t, int64_t, stb_d) | ||
495 | -GEN_VEXT_ST_US(vsh_v_h, int16_t, int16_t, sth_h) | ||
496 | -GEN_VEXT_ST_US(vsh_v_w, int16_t, int32_t, sth_w) | ||
497 | -GEN_VEXT_ST_US(vsh_v_d, int16_t, int64_t, sth_d) | ||
498 | -GEN_VEXT_ST_US(vsw_v_w, int32_t, int32_t, stw_w) | ||
499 | -GEN_VEXT_ST_US(vsw_v_d, int32_t, int64_t, stw_d) | ||
500 | -GEN_VEXT_ST_US(vse_v_b, int8_t, int8_t , ste_b) | ||
501 | -GEN_VEXT_ST_US(vse_v_h, int16_t, int16_t, ste_h) | ||
502 | -GEN_VEXT_ST_US(vse_v_w, int32_t, int32_t, ste_w) | ||
503 | -GEN_VEXT_ST_US(vse_v_d, int64_t, int64_t, ste_d) | ||
504 | + sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
505 | +} | ||
506 | + | ||
507 | +GEN_VEXT_ST_US(vse8_v, int8_t, ste_b) | ||
508 | +GEN_VEXT_ST_US(vse16_v, int16_t, ste_h) | ||
509 | +GEN_VEXT_ST_US(vse32_v, int32_t, ste_w) | ||
510 | +GEN_VEXT_ST_US(vse64_v, int64_t, ste_d) | ||
511 | |||
512 | /* | ||
513 | *** index: access vector element from indexed memory | ||
514 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
515 | index XXXXXXX..XXXXXXX 100644 | ||
516 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
517 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
518 | @@ -XXX,XX +XXX,XX @@ static bool require_vm(int vm, int vd) | ||
519 | return (vm != 0 || vd != 0); | ||
520 | } | ||
521 | |||
522 | +static bool require_nf(int vd, int nf, int lmul) | ||
523 | +{ | ||
524 | + int size = nf << MAX(lmul, 0); | ||
525 | + return size <= 8 && vd + size <= 32; | ||
526 | +} | ||
527 | + | ||
528 | /* | ||
529 | * Vector register should aligned with the passed-in LMUL (EMUL). | ||
530 | * If LMUL < 0, i.e. fractional LMUL, any vector register is allowed. | ||
531 | @@ -XXX,XX +XXX,XX @@ static uint32_t vreg_ofs(DisasContext *s, int reg) | ||
532 | |||
533 | /* check functions */ | ||
534 | |||
535 | +/* | ||
536 | + * Vector unit-stride, strided, unit-stride segment, strided segment | ||
537 | + * store check function. | ||
538 | + * | ||
539 | + * Rules to be checked here: | ||
540 | + * 1. EMUL must within the range: 1/8 <= EMUL <= 8. (Section 7.3) | ||
541 | + * 2. Destination vector register number is multiples of EMUL. | ||
542 | + * (Section 3.4.2, 7.3) | ||
543 | + * 3. The EMUL setting must be such that EMUL * NFIELDS ≤ 8. (Section 7.8) | ||
544 | + * 4. Vector register numbers accessed by the segment load or store | ||
545 | + * cannot increment past 31. (Section 7.8) | ||
546 | + */ | ||
547 | +static bool vext_check_store(DisasContext *s, int vd, int nf, uint8_t eew) | ||
548 | +{ | ||
549 | + int8_t emul = eew - s->sew + s->lmul; | ||
550 | + return (emul >= -3 && emul <= 3) && | ||
551 | + require_align(vd, emul) && | ||
552 | + require_nf(vd, nf, emul); | ||
553 | +} | ||
554 | + | ||
555 | +/* | ||
556 | + * Vector unit-stride, strided, unit-stride segment, strided segment | ||
557 | + * load check function. | ||
558 | + * | ||
559 | + * Rules to be checked here: | ||
560 | + * 1. All rules applies to store instructions are applies | ||
561 | + * to load instructions. | ||
562 | + * 2. Destination vector register group for a masked vector | ||
563 | + * instruction cannot overlap the source mask register (v0). | ||
564 | + * (Section 5.3) | ||
565 | + */ | ||
566 | +static bool vext_check_load(DisasContext *s, int vd, int nf, int vm, | ||
567 | + uint8_t eew) | ||
568 | +{ | ||
569 | + return vext_check_store(s, vd, nf, eew) && require_vm(vm, vd); | ||
570 | +} | ||
571 | + | ||
572 | +/* | ||
573 | + * Vector indexed, indexed segment store check function. | ||
574 | + * | ||
575 | + * Rules to be checked here: | ||
576 | + * 1. EMUL must within the range: 1/8 <= EMUL <= 8. (Section 7.3) | ||
577 | + * 2. Index vector register number is multiples of EMUL. | ||
578 | + * (Section 3.4.2, 7.3) | ||
579 | + * 3. Destination vector register number is multiples of LMUL. | ||
580 | + * (Section 3.4.2, 7.3) | ||
581 | + * 4. The EMUL setting must be such that EMUL * NFIELDS ≤ 8. (Section 7.8) | ||
582 | + * 5. Vector register numbers accessed by the segment load or store | ||
583 | + * cannot increment past 31. (Section 7.8) | ||
584 | + */ | ||
585 | +static bool vext_check_st_index(DisasContext *s, int vd, int vs2, int nf, | ||
586 | + uint8_t eew) | ||
587 | +{ | ||
588 | + int8_t emul = eew - s->sew + s->lmul; | ||
589 | + return (emul >= -3 && emul <= 3) && | ||
590 | + require_align(vs2, emul) && | ||
591 | + require_align(vd, s->lmul) && | ||
592 | + require_nf(vd, nf, s->lmul); | ||
593 | +} | ||
594 | + | ||
595 | +/* | ||
596 | + * Vector indexed, indexed segment load check function. | ||
597 | + * | ||
598 | + * Rules to be checked here: | ||
599 | + * 1. All rules applies to store instructions are applies | ||
600 | + * to load instructions. | ||
601 | + * 2. Destination vector register group for a masked vector | ||
602 | + * instruction cannot overlap the source mask register (v0). | ||
603 | + * (Section 5.3) | ||
604 | + * 3. Destination vector register cannot overlap a source vector | ||
605 | + * register (vs2) group. | ||
606 | + * (Section 5.2) | ||
607 | + * 4. Destination vector register groups cannot overlap | ||
608 | + * the source vector register (vs2) group for | ||
609 | + * indexed segment load instructions. (Section 7.8.3) | ||
610 | + */ | ||
611 | +static bool vext_check_ld_index(DisasContext *s, int vd, int vs2, | ||
612 | + int nf, int vm, uint8_t eew) | ||
613 | +{ | ||
614 | + int8_t seg_vd; | ||
615 | + int8_t emul = eew - s->sew + s->lmul; | ||
616 | + bool ret = vext_check_st_index(s, vd, vs2, nf, eew) && | ||
617 | + require_vm(vm, vd); | ||
618 | + | ||
619 | + /* Each segment register group has to follow overlap rules. */ | ||
620 | + for (int i = 0; i < nf; ++i) { | ||
621 | + seg_vd = vd + (1 << MAX(s->lmul, 0)) * i; | ||
622 | + | ||
623 | + if (eew > s->sew) { | ||
624 | + if (seg_vd != vs2) { | ||
625 | + ret &= require_noover(seg_vd, s->lmul, vs2, emul); | ||
626 | + } | ||
627 | + } else if (eew < s->sew) { | ||
628 | + ret &= require_noover(seg_vd, s->lmul, vs2, emul); | ||
629 | + } | ||
630 | + | ||
631 | + /* | ||
632 | + * Destination vector register groups cannot overlap | ||
633 | + * the source vector register (vs2) group for | ||
634 | + * indexed segment load instructions. | ||
635 | + */ | ||
636 | + if (nf > 1) { | ||
637 | + ret &= !is_overlapped(seg_vd, 1 << MAX(s->lmul, 0), | ||
638 | + vs2, 1 << MAX(emul, 0)); | ||
639 | + } | ||
640 | + } | ||
641 | + return ret; | ||
642 | +} | ||
643 | + | ||
644 | static bool vext_check_ss(DisasContext *s, int vd, int vs, int vm) | ||
645 | { | ||
646 | return require_vm(vm, vd) && | ||
647 | @@ -XXX,XX +XXX,XX @@ static bool vext_check_isa_ill(DisasContext *s) | ||
648 | return !s->vill; | ||
649 | } | ||
650 | |||
651 | -/* | ||
652 | - * There are two rules check here. | ||
653 | - * | ||
654 | - * 1. Vector register numbers are multiples of LMUL. (Section 3.2) | ||
655 | - * | ||
656 | - * 2. For all widening instructions, the destination LMUL value must also be | ||
657 | - * a supported LMUL value. (Section 11.2) | ||
658 | - */ | ||
659 | -static bool vext_check_reg(DisasContext *s, uint32_t reg, bool widen) | ||
660 | -{ | ||
661 | - /* | ||
662 | - * The destination vector register group results are arranged as if both | ||
663 | - * SEW and LMUL were at twice their current settings. (Section 11.2). | ||
664 | - */ | ||
665 | - int legal = widen ? 2 << s->lmul : 1 << s->lmul; | ||
666 | - | ||
667 | - return !((s->lmul == 0x3 && widen) || (reg % legal)); | ||
668 | -} | ||
669 | - | ||
670 | -/* | ||
671 | - * There are two rules check here. | ||
672 | - * | ||
673 | - * 1. The destination vector register group for a masked vector instruction can | ||
674 | - * only overlap the source mask register (v0) when LMUL=1. (Section 5.3) | ||
675 | - * | ||
676 | - * 2. In widen instructions and some other insturctions, like vslideup.vx, | ||
677 | - * there is no need to check whether LMUL=1. | ||
678 | - */ | ||
679 | -static bool vext_check_overlap_mask(DisasContext *s, uint32_t vd, bool vm, | ||
680 | - bool force) | ||
681 | -{ | ||
682 | - return (vm != 0 || vd != 0) || (!force && (s->lmul == 0)); | ||
683 | -} | ||
684 | - | ||
685 | -/* The LMUL setting must be such that LMUL * NFIELDS <= 8. (Section 7.8) */ | ||
686 | -static bool vext_check_nf(DisasContext *s, uint32_t nf) | ||
687 | -{ | ||
688 | - return (1 << s->lmul) * nf <= 8; | ||
689 | -} | ||
690 | - | ||
691 | -/* | ||
692 | - * The destination vector register group cannot overlap a source vector register | ||
693 | - * group of a different element width. (Section 11.2) | ||
694 | - */ | ||
695 | -static inline bool vext_check_overlap_group(int rd, int dlen, int rs, int slen) | ||
696 | -{ | ||
697 | - return ((rd >= rs + slen) || (rs >= rd + dlen)); | ||
698 | -} | ||
699 | - | ||
700 | /* common translation macro */ | ||
701 | -#define GEN_VEXT_TRANS(NAME, SEQ, ARGTYPE, OP, CHECK) \ | ||
702 | -static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE *a)\ | ||
703 | -{ \ | ||
704 | - if (CHECK(s, a)) { \ | ||
705 | - return OP(s, a, SEQ); \ | ||
706 | - } \ | ||
707 | - return false; \ | ||
708 | +#define GEN_VEXT_TRANS(NAME, EEW, ARGTYPE, OP, CHECK) \ | ||
709 | +static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE * a) \ | ||
710 | +{ \ | ||
711 | + if (CHECK(s, a, EEW)) { \ | ||
712 | + return OP(s, a, EEW); \ | ||
713 | + } \ | ||
714 | + return false; \ | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | @@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
719 | return true; | ||
720 | } | ||
721 | |||
722 | -static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
723 | +static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
724 | { | ||
725 | uint32_t data = 0; | ||
726 | gen_helper_ldst_us *fn; | ||
727 | - static gen_helper_ldst_us * const fns[2][7][4] = { | ||
728 | + static gen_helper_ldst_us * const fns[2][4] = { | ||
729 | /* masked unit stride load */ | ||
730 | - { { gen_helper_vlb_v_b_mask, gen_helper_vlb_v_h_mask, | ||
731 | - gen_helper_vlb_v_w_mask, gen_helper_vlb_v_d_mask }, | ||
732 | - { NULL, gen_helper_vlh_v_h_mask, | ||
733 | - gen_helper_vlh_v_w_mask, gen_helper_vlh_v_d_mask }, | ||
734 | - { NULL, NULL, | ||
735 | - gen_helper_vlw_v_w_mask, gen_helper_vlw_v_d_mask }, | ||
736 | - { gen_helper_vle_v_b_mask, gen_helper_vle_v_h_mask, | ||
737 | - gen_helper_vle_v_w_mask, gen_helper_vle_v_d_mask }, | ||
738 | - { gen_helper_vlbu_v_b_mask, gen_helper_vlbu_v_h_mask, | ||
739 | - gen_helper_vlbu_v_w_mask, gen_helper_vlbu_v_d_mask }, | ||
740 | - { NULL, gen_helper_vlhu_v_h_mask, | ||
741 | - gen_helper_vlhu_v_w_mask, gen_helper_vlhu_v_d_mask }, | ||
742 | - { NULL, NULL, | ||
743 | - gen_helper_vlwu_v_w_mask, gen_helper_vlwu_v_d_mask } }, | ||
744 | + { gen_helper_vle8_v_mask, gen_helper_vle16_v_mask, | ||
745 | + gen_helper_vle32_v_mask, gen_helper_vle64_v_mask }, | ||
746 | /* unmasked unit stride load */ | ||
747 | - { { gen_helper_vlb_v_b, gen_helper_vlb_v_h, | ||
748 | - gen_helper_vlb_v_w, gen_helper_vlb_v_d }, | ||
749 | - { NULL, gen_helper_vlh_v_h, | ||
750 | - gen_helper_vlh_v_w, gen_helper_vlh_v_d }, | ||
751 | - { NULL, NULL, | ||
752 | - gen_helper_vlw_v_w, gen_helper_vlw_v_d }, | ||
753 | - { gen_helper_vle_v_b, gen_helper_vle_v_h, | ||
754 | - gen_helper_vle_v_w, gen_helper_vle_v_d }, | ||
755 | - { gen_helper_vlbu_v_b, gen_helper_vlbu_v_h, | ||
756 | - gen_helper_vlbu_v_w, gen_helper_vlbu_v_d }, | ||
757 | - { NULL, gen_helper_vlhu_v_h, | ||
758 | - gen_helper_vlhu_v_w, gen_helper_vlhu_v_d }, | ||
759 | - { NULL, NULL, | ||
760 | - gen_helper_vlwu_v_w, gen_helper_vlwu_v_d } } | ||
761 | + { gen_helper_vle8_v, gen_helper_vle16_v, | ||
762 | + gen_helper_vle32_v, gen_helper_vle64_v } | ||
763 | }; | ||
764 | |||
765 | - fn = fns[a->vm][seq][s->sew]; | ||
766 | + fn = fns[a->vm][eew]; | ||
767 | if (fn == NULL) { | ||
768 | return false; | ||
769 | } | ||
770 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
771 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
772 | } | ||
773 | |||
774 | -static bool ld_us_check(DisasContext *s, arg_r2nfvm* a) | ||
775 | +static bool ld_us_check(DisasContext *s, arg_r2nfvm* a, uint8_t eew) | ||
776 | { | ||
777 | - return (vext_check_isa_ill(s) && | ||
778 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
779 | - vext_check_reg(s, a->rd, false) && | ||
780 | - vext_check_nf(s, a->nf)); | ||
781 | + return require_rvv(s) && | ||
782 | + vext_check_isa_ill(s) && | ||
783 | + vext_check_load(s, a->rd, a->nf, a->vm, eew); | ||
784 | } | ||
785 | |||
786 | -GEN_VEXT_TRANS(vlb_v, 0, r2nfvm, ld_us_op, ld_us_check) | ||
787 | -GEN_VEXT_TRANS(vlh_v, 1, r2nfvm, ld_us_op, ld_us_check) | ||
788 | -GEN_VEXT_TRANS(vlw_v, 2, r2nfvm, ld_us_op, ld_us_check) | ||
789 | -GEN_VEXT_TRANS(vle_v, 3, r2nfvm, ld_us_op, ld_us_check) | ||
790 | -GEN_VEXT_TRANS(vlbu_v, 4, r2nfvm, ld_us_op, ld_us_check) | ||
791 | -GEN_VEXT_TRANS(vlhu_v, 5, r2nfvm, ld_us_op, ld_us_check) | ||
792 | -GEN_VEXT_TRANS(vlwu_v, 6, r2nfvm, ld_us_op, ld_us_check) | ||
793 | +GEN_VEXT_TRANS(vle8_v, MO_8, r2nfvm, ld_us_op, ld_us_check) | ||
794 | +GEN_VEXT_TRANS(vle16_v, MO_16, r2nfvm, ld_us_op, ld_us_check) | ||
795 | +GEN_VEXT_TRANS(vle32_v, MO_32, r2nfvm, ld_us_op, ld_us_check) | ||
796 | +GEN_VEXT_TRANS(vle64_v, MO_64, r2nfvm, ld_us_op, ld_us_check) | ||
797 | |||
798 | -static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
799 | +static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
800 | { | ||
801 | uint32_t data = 0; | ||
802 | gen_helper_ldst_us *fn; | ||
803 | - static gen_helper_ldst_us * const fns[2][4][4] = { | ||
804 | - /* masked unit stride load and store */ | ||
805 | - { { gen_helper_vsb_v_b_mask, gen_helper_vsb_v_h_mask, | ||
806 | - gen_helper_vsb_v_w_mask, gen_helper_vsb_v_d_mask }, | ||
807 | - { NULL, gen_helper_vsh_v_h_mask, | ||
808 | - gen_helper_vsh_v_w_mask, gen_helper_vsh_v_d_mask }, | ||
809 | - { NULL, NULL, | ||
810 | - gen_helper_vsw_v_w_mask, gen_helper_vsw_v_d_mask }, | ||
811 | - { gen_helper_vse_v_b_mask, gen_helper_vse_v_h_mask, | ||
812 | - gen_helper_vse_v_w_mask, gen_helper_vse_v_d_mask } }, | ||
813 | + static gen_helper_ldst_us * const fns[2][4] = { | ||
814 | + /* masked unit stride store */ | ||
815 | + { gen_helper_vse8_v_mask, gen_helper_vse16_v_mask, | ||
816 | + gen_helper_vse32_v_mask, gen_helper_vse64_v_mask }, | ||
817 | /* unmasked unit stride store */ | ||
818 | - { { gen_helper_vsb_v_b, gen_helper_vsb_v_h, | ||
819 | - gen_helper_vsb_v_w, gen_helper_vsb_v_d }, | ||
820 | - { NULL, gen_helper_vsh_v_h, | ||
821 | - gen_helper_vsh_v_w, gen_helper_vsh_v_d }, | ||
822 | - { NULL, NULL, | ||
823 | - gen_helper_vsw_v_w, gen_helper_vsw_v_d }, | ||
824 | - { gen_helper_vse_v_b, gen_helper_vse_v_h, | ||
825 | - gen_helper_vse_v_w, gen_helper_vse_v_d } } | ||
826 | + { gen_helper_vse8_v, gen_helper_vse16_v, | ||
827 | + gen_helper_vse32_v, gen_helper_vse64_v } | ||
828 | }; | ||
829 | |||
830 | - fn = fns[a->vm][seq][s->sew]; | ||
831 | + fn = fns[a->vm][eew]; | ||
832 | if (fn == NULL) { | ||
833 | return false; | ||
834 | } | ||
835 | @@ -XXX,XX +XXX,XX @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
836 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, true); | ||
837 | } | ||
838 | |||
839 | -static bool st_us_check(DisasContext *s, arg_r2nfvm* a) | ||
840 | +static bool st_us_check(DisasContext *s, arg_r2nfvm* a, uint8_t eew) | ||
841 | { | ||
842 | - return (vext_check_isa_ill(s) && | ||
843 | - vext_check_reg(s, a->rd, false) && | ||
844 | - vext_check_nf(s, a->nf)); | ||
845 | + return require_rvv(s) && | ||
846 | + vext_check_isa_ill(s) && | ||
847 | + vext_check_store(s, a->rd, a->nf, eew); | ||
848 | } | ||
849 | |||
850 | -GEN_VEXT_TRANS(vsb_v, 0, r2nfvm, st_us_op, st_us_check) | ||
851 | -GEN_VEXT_TRANS(vsh_v, 1, r2nfvm, st_us_op, st_us_check) | ||
852 | -GEN_VEXT_TRANS(vsw_v, 2, r2nfvm, st_us_op, st_us_check) | ||
853 | -GEN_VEXT_TRANS(vse_v, 3, r2nfvm, st_us_op, st_us_check) | ||
854 | +GEN_VEXT_TRANS(vse8_v, MO_8, r2nfvm, st_us_op, st_us_check) | ||
855 | +GEN_VEXT_TRANS(vse16_v, MO_16, r2nfvm, st_us_op, st_us_check) | ||
856 | +GEN_VEXT_TRANS(vse32_v, MO_32, r2nfvm, st_us_op, st_us_check) | ||
857 | +GEN_VEXT_TRANS(vse64_v, MO_64, r2nfvm, st_us_op, st_us_check) | ||
858 | |||
859 | /* | ||
860 | *** stride load and store | ||
861 | @@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2, | ||
862 | return true; | ||
863 | } | ||
864 | |||
865 | -static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
866 | +static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
867 | { | ||
868 | uint32_t data = 0; | ||
869 | gen_helper_ldst_stride *fn; | ||
870 | - static gen_helper_ldst_stride * const fns[7][4] = { | ||
871 | - { gen_helper_vlsb_v_b, gen_helper_vlsb_v_h, | ||
872 | - gen_helper_vlsb_v_w, gen_helper_vlsb_v_d }, | ||
873 | - { NULL, gen_helper_vlsh_v_h, | ||
874 | - gen_helper_vlsh_v_w, gen_helper_vlsh_v_d }, | ||
875 | - { NULL, NULL, | ||
876 | - gen_helper_vlsw_v_w, gen_helper_vlsw_v_d }, | ||
877 | - { gen_helper_vlse_v_b, gen_helper_vlse_v_h, | ||
878 | - gen_helper_vlse_v_w, gen_helper_vlse_v_d }, | ||
879 | - { gen_helper_vlsbu_v_b, gen_helper_vlsbu_v_h, | ||
880 | - gen_helper_vlsbu_v_w, gen_helper_vlsbu_v_d }, | ||
881 | - { NULL, gen_helper_vlshu_v_h, | ||
882 | - gen_helper_vlshu_v_w, gen_helper_vlshu_v_d }, | ||
883 | - { NULL, NULL, | ||
884 | - gen_helper_vlswu_v_w, gen_helper_vlswu_v_d }, | ||
885 | + static gen_helper_ldst_stride * const fns[4] = { | ||
886 | + gen_helper_vlse8_v, gen_helper_vlse16_v, | ||
887 | + gen_helper_vlse32_v, gen_helper_vlse64_v | ||
888 | }; | ||
889 | |||
890 | - fn = fns[seq][s->sew]; | ||
891 | + fn = fns[eew]; | ||
892 | if (fn == NULL) { | ||
893 | return false; | ||
894 | } | ||
895 | @@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
896 | return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
897 | } | ||
898 | |||
899 | -static bool ld_stride_check(DisasContext *s, arg_rnfvm* a) | ||
900 | +static bool ld_stride_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
901 | { | ||
902 | - return (vext_check_isa_ill(s) && | ||
903 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
904 | - vext_check_reg(s, a->rd, false) && | ||
905 | - vext_check_nf(s, a->nf)); | ||
906 | + return require_rvv(s) && | ||
907 | + vext_check_isa_ill(s) && | ||
908 | + vext_check_load(s, a->rd, a->nf, a->vm, eew); | ||
909 | } | ||
910 | |||
911 | -GEN_VEXT_TRANS(vlsb_v, 0, rnfvm, ld_stride_op, ld_stride_check) | ||
912 | -GEN_VEXT_TRANS(vlsh_v, 1, rnfvm, ld_stride_op, ld_stride_check) | ||
913 | -GEN_VEXT_TRANS(vlsw_v, 2, rnfvm, ld_stride_op, ld_stride_check) | ||
914 | -GEN_VEXT_TRANS(vlse_v, 3, rnfvm, ld_stride_op, ld_stride_check) | ||
915 | -GEN_VEXT_TRANS(vlsbu_v, 4, rnfvm, ld_stride_op, ld_stride_check) | ||
916 | -GEN_VEXT_TRANS(vlshu_v, 5, rnfvm, ld_stride_op, ld_stride_check) | ||
917 | -GEN_VEXT_TRANS(vlswu_v, 6, rnfvm, ld_stride_op, ld_stride_check) | ||
918 | +GEN_VEXT_TRANS(vlse8_v, MO_8, rnfvm, ld_stride_op, ld_stride_check) | ||
919 | +GEN_VEXT_TRANS(vlse16_v, MO_16, rnfvm, ld_stride_op, ld_stride_check) | ||
920 | +GEN_VEXT_TRANS(vlse32_v, MO_32, rnfvm, ld_stride_op, ld_stride_check) | ||
921 | +GEN_VEXT_TRANS(vlse64_v, MO_64, rnfvm, ld_stride_op, ld_stride_check) | ||
922 | |||
923 | -static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
924 | +static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
925 | { | ||
926 | uint32_t data = 0; | ||
927 | gen_helper_ldst_stride *fn; | ||
928 | - static gen_helper_ldst_stride * const fns[4][4] = { | ||
929 | + static gen_helper_ldst_stride * const fns[4] = { | ||
930 | /* masked stride store */ | ||
931 | - { gen_helper_vssb_v_b, gen_helper_vssb_v_h, | ||
932 | - gen_helper_vssb_v_w, gen_helper_vssb_v_d }, | ||
933 | - { NULL, gen_helper_vssh_v_h, | ||
934 | - gen_helper_vssh_v_w, gen_helper_vssh_v_d }, | ||
935 | - { NULL, NULL, | ||
936 | - gen_helper_vssw_v_w, gen_helper_vssw_v_d }, | ||
937 | - { gen_helper_vsse_v_b, gen_helper_vsse_v_h, | ||
938 | - gen_helper_vsse_v_w, gen_helper_vsse_v_d } | ||
939 | + gen_helper_vsse8_v, gen_helper_vsse16_v, | ||
940 | + gen_helper_vsse32_v, gen_helper_vsse64_v | ||
941 | }; | ||
942 | |||
943 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
944 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
945 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
946 | - fn = fns[seq][s->sew]; | ||
947 | + fn = fns[eew]; | ||
948 | if (fn == NULL) { | ||
949 | return false; | ||
950 | } | ||
951 | @@ -XXX,XX +XXX,XX @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
952 | return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, true); | ||
953 | } | ||
954 | |||
955 | -static bool st_stride_check(DisasContext *s, arg_rnfvm* a) | ||
956 | +static bool st_stride_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
957 | { | ||
958 | - return (vext_check_isa_ill(s) && | ||
959 | - vext_check_reg(s, a->rd, false) && | ||
960 | - vext_check_nf(s, a->nf)); | ||
961 | + return require_rvv(s) && | ||
962 | + vext_check_isa_ill(s) && | ||
963 | + vext_check_store(s, a->rd, a->nf, eew); | ||
964 | } | ||
965 | |||
966 | -GEN_VEXT_TRANS(vssb_v, 0, rnfvm, st_stride_op, st_stride_check) | ||
967 | -GEN_VEXT_TRANS(vssh_v, 1, rnfvm, st_stride_op, st_stride_check) | ||
968 | -GEN_VEXT_TRANS(vssw_v, 2, rnfvm, st_stride_op, st_stride_check) | ||
969 | -GEN_VEXT_TRANS(vsse_v, 3, rnfvm, st_stride_op, st_stride_check) | ||
970 | +GEN_VEXT_TRANS(vsse8_v, MO_8, rnfvm, st_stride_op, st_stride_check) | ||
971 | +GEN_VEXT_TRANS(vsse16_v, MO_16, rnfvm, st_stride_op, st_stride_check) | ||
972 | +GEN_VEXT_TRANS(vsse32_v, MO_32, rnfvm, st_stride_op, st_stride_check) | ||
973 | +GEN_VEXT_TRANS(vsse64_v, MO_64, rnfvm, st_stride_op, st_stride_check) | ||
974 | |||
975 | /* | ||
976 | *** index load and store | ||
977 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
978 | * groups cannot overlap the source vector register group (specified by | ||
979 | * `vs2`), else an illegal instruction exception is raised. | ||
980 | */ | ||
981 | -static bool ld_index_check(DisasContext *s, arg_rnfvm* a) | ||
982 | +static bool ld_index_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
983 | { | ||
984 | - return (vext_check_isa_ill(s) && | ||
985 | - vext_check_overlap_mask(s, a->rd, a->vm, false) && | ||
986 | - vext_check_reg(s, a->rd, false) && | ||
987 | - vext_check_reg(s, a->rs2, false) && | ||
988 | - vext_check_nf(s, a->nf) && | ||
989 | - ((a->nf == 1) || | ||
990 | - vext_check_overlap_group(a->rd, a->nf << s->lmul, | ||
991 | - a->rs2, 1 << s->lmul))); | ||
992 | + return require_rvv(s) && | ||
993 | + vext_check_isa_ill(s) && | ||
994 | + vext_check_ld_index(s, a->rd, a->rs2, a->nf, a->vm, eew); | ||
995 | } | ||
996 | |||
997 | GEN_VEXT_TRANS(vlxb_v, 0, rnfvm, ld_index_op, ld_index_check) | ||
998 | @@ -XXX,XX +XXX,XX @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
999 | return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true); | ||
1000 | } | ||
1001 | |||
1002 | -static bool st_index_check(DisasContext *s, arg_rnfvm* a) | ||
1003 | +static bool st_index_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
1004 | { | ||
1005 | - return (vext_check_isa_ill(s) && | ||
1006 | - vext_check_reg(s, a->rd, false) && | ||
1007 | - vext_check_reg(s, a->rs2, false) && | ||
1008 | - vext_check_nf(s, a->nf)); | ||
1009 | + return require_rvv(s) && | ||
1010 | + vext_check_isa_ill(s) && | ||
1011 | + vext_check_st_index(s, a->rd, a->rs2, a->nf, eew); | ||
1012 | } | ||
1013 | |||
1014 | GEN_VEXT_TRANS(vsxb_v, 0, rnfvm, st_index_op, st_index_check) | ||
1015 | -- | ||
1016 | 2.31.1 | ||
1017 | |||
1018 | |||
1019 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-22-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 67 +++++++-------- | ||
9 | target/riscv/insn32.decode | 21 +++-- | ||
10 | target/riscv/vector_helper.c | 98 +++++++++------------ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 110 +++++++++++++----------- | ||
12 | 4 files changed, 145 insertions(+), 151 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vsse8_v, void, ptr, ptr, tl, tl, env, i32) | ||
19 | DEF_HELPER_6(vsse16_v, void, ptr, ptr, tl, tl, env, i32) | ||
20 | DEF_HELPER_6(vsse32_v, void, ptr, ptr, tl, tl, env, i32) | ||
21 | DEF_HELPER_6(vsse64_v, void, ptr, ptr, tl, tl, env, i32) | ||
22 | -DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
23 | -DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
24 | -DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
25 | -DEF_HELPER_6(vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
26 | -DEF_HELPER_6(vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
28 | -DEF_HELPER_6(vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
29 | -DEF_HELPER_6(vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
30 | -DEF_HELPER_6(vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
31 | -DEF_HELPER_6(vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
32 | -DEF_HELPER_6(vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
33 | -DEF_HELPER_6(vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
34 | -DEF_HELPER_6(vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
35 | -DEF_HELPER_6(vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
36 | -DEF_HELPER_6(vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
37 | -DEF_HELPER_6(vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
38 | -DEF_HELPER_6(vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
39 | -DEF_HELPER_6(vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
40 | -DEF_HELPER_6(vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
41 | -DEF_HELPER_6(vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
42 | -DEF_HELPER_6(vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
43 | -DEF_HELPER_6(vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
44 | -DEF_HELPER_6(vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
45 | -DEF_HELPER_6(vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
46 | -DEF_HELPER_6(vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
47 | -DEF_HELPER_6(vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
48 | -DEF_HELPER_6(vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
49 | -DEF_HELPER_6(vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
50 | -DEF_HELPER_6(vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
51 | -DEF_HELPER_6(vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
52 | -DEF_HELPER_6(vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
53 | -DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32) | ||
54 | -DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32) | ||
55 | -DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32) | ||
56 | -DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32) | ||
57 | +DEF_HELPER_6(vlxei8_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
58 | +DEF_HELPER_6(vlxei8_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
59 | +DEF_HELPER_6(vlxei8_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
60 | +DEF_HELPER_6(vlxei8_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
61 | +DEF_HELPER_6(vlxei16_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
62 | +DEF_HELPER_6(vlxei16_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
63 | +DEF_HELPER_6(vlxei16_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
64 | +DEF_HELPER_6(vlxei16_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
65 | +DEF_HELPER_6(vlxei32_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
66 | +DEF_HELPER_6(vlxei32_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
67 | +DEF_HELPER_6(vlxei32_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
68 | +DEF_HELPER_6(vlxei32_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
69 | +DEF_HELPER_6(vlxei64_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
70 | +DEF_HELPER_6(vlxei64_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
71 | +DEF_HELPER_6(vlxei64_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
72 | +DEF_HELPER_6(vlxei64_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
73 | +DEF_HELPER_6(vsxei8_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
74 | +DEF_HELPER_6(vsxei8_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
75 | +DEF_HELPER_6(vsxei8_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
76 | +DEF_HELPER_6(vsxei8_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
77 | +DEF_HELPER_6(vsxei16_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
78 | +DEF_HELPER_6(vsxei16_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
79 | +DEF_HELPER_6(vsxei16_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
80 | +DEF_HELPER_6(vsxei16_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
81 | +DEF_HELPER_6(vsxei32_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
82 | +DEF_HELPER_6(vsxei32_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
83 | +DEF_HELPER_6(vsxei32_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
84 | +DEF_HELPER_6(vsxei32_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
85 | +DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
86 | +DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
87 | +DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
88 | +DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
89 | DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32) | ||
90 | DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32) | ||
91 | DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32) | ||
92 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
93 | index XXXXXXX..XXXXXXX 100644 | ||
94 | --- a/target/riscv/insn32.decode | ||
95 | +++ b/target/riscv/insn32.decode | ||
96 | @@ -XXX,XX +XXX,XX @@ vlbuff_v ... 000 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
97 | vlhuff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
98 | vlwuff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
99 | |||
100 | -vlxb_v ... 111 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
101 | -vlxh_v ... 111 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
102 | -vlxw_v ... 111 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
103 | -vlxe_v ... 011 . ..... ..... 111 ..... 0000111 @r_nfvm | ||
104 | -vlxbu_v ... 011 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
105 | -vlxhu_v ... 011 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
106 | -vlxwu_v ... 011 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
107 | +# Vector ordered-indexed and unordered-indexed load insns. | ||
108 | +vlxei8_v ... 0-1 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
109 | +vlxei16_v ... 0-1 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
110 | +vlxei32_v ... 0-1 . ..... ..... 110 ..... 0000111 @r_nfvm | ||
111 | +vlxei64_v ... 0-1 . ..... ..... 111 ..... 0000111 @r_nfvm | ||
112 | + | ||
113 | # Vector ordered-indexed and unordered-indexed store insns. | ||
114 | -vsxb_v ... -11 . ..... ..... 000 ..... 0100111 @r_nfvm | ||
115 | -vsxh_v ... -11 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
116 | -vsxw_v ... -11 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
117 | -vsxe_v ... -11 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
118 | +vsxei8_v ... 0-1 . ..... ..... 000 ..... 0100111 @r_nfvm | ||
119 | +vsxei16_v ... 0-1 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
120 | +vsxei32_v ... 0-1 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
121 | +vsxei64_v ... 0-1 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
122 | |||
123 | # *** new major opcode OP-V *** | ||
124 | vadd_vv 000000 . ..... ..... 000 ..... 1010111 @r_vm | ||
125 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/target/riscv/vector_helper.c | ||
128 | +++ b/target/riscv/vector_helper.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
130 | cpu_##STSUF##_data_ra(env, addr, data, retaddr); \ | ||
131 | } | ||
132 | |||
133 | -GEN_VEXT_ST_ELEM(stb_b, int8_t, H1, stb) | ||
134 | -GEN_VEXT_ST_ELEM(stb_h, int16_t, H2, stb) | ||
135 | -GEN_VEXT_ST_ELEM(stb_w, int32_t, H4, stb) | ||
136 | -GEN_VEXT_ST_ELEM(stb_d, int64_t, H8, stb) | ||
137 | -GEN_VEXT_ST_ELEM(sth_h, int16_t, H2, stw) | ||
138 | -GEN_VEXT_ST_ELEM(sth_w, int32_t, H4, stw) | ||
139 | -GEN_VEXT_ST_ELEM(sth_d, int64_t, H8, stw) | ||
140 | -GEN_VEXT_ST_ELEM(stw_w, int32_t, H4, stl) | ||
141 | -GEN_VEXT_ST_ELEM(stw_d, int64_t, H8, stl) | ||
142 | GEN_VEXT_ST_ELEM(ste_b, int8_t, H1, stb) | ||
143 | GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw) | ||
144 | GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl) | ||
145 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
146 | void *vs2, CPURISCVState *env, uint32_t desc, | ||
147 | vext_get_index_addr get_index_addr, | ||
148 | vext_ldst_elem_fn *ldst_elem, | ||
149 | - uint32_t esz, uint32_t msz, uintptr_t ra, | ||
150 | - MMUAccessType access_type) | ||
151 | + uint32_t esz, uintptr_t ra, MMUAccessType access_type) | ||
152 | { | ||
153 | uint32_t i, k; | ||
154 | uint32_t nf = vext_nf(desc); | ||
155 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
156 | if (!vm && !vext_elem_mask(v0, i)) { | ||
157 | continue; | ||
158 | } | ||
159 | - probe_pages(env, get_index_addr(base, i, vs2), nf * msz, ra, | ||
160 | + probe_pages(env, get_index_addr(base, i, vs2), nf * esz, ra, | ||
161 | access_type); | ||
162 | } | ||
163 | /* load bytes from guest memory */ | ||
164 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
165 | continue; | ||
166 | } | ||
167 | while (k < nf) { | ||
168 | - abi_ptr addr = get_index_addr(base, i, vs2) + k * msz; | ||
169 | + abi_ptr addr = get_index_addr(base, i, vs2) + k * esz; | ||
170 | ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
171 | k++; | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | |||
176 | -#define GEN_VEXT_LD_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, LOAD_FN) \ | ||
177 | +#define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN) \ | ||
178 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
179 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
180 | { \ | ||
181 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
182 | - LOAD_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
183 | - GETPC(), MMU_DATA_LOAD); \ | ||
184 | -} | ||
185 | - | ||
186 | -GEN_VEXT_LD_INDEX(vlxb_v_b, int8_t, int8_t, idx_b, ldb_b) | ||
187 | -GEN_VEXT_LD_INDEX(vlxb_v_h, int8_t, int16_t, idx_h, ldb_h) | ||
188 | -GEN_VEXT_LD_INDEX(vlxb_v_w, int8_t, int32_t, idx_w, ldb_w) | ||
189 | -GEN_VEXT_LD_INDEX(vlxb_v_d, int8_t, int64_t, idx_d, ldb_d) | ||
190 | -GEN_VEXT_LD_INDEX(vlxh_v_h, int16_t, int16_t, idx_h, ldh_h) | ||
191 | -GEN_VEXT_LD_INDEX(vlxh_v_w, int16_t, int32_t, idx_w, ldh_w) | ||
192 | -GEN_VEXT_LD_INDEX(vlxh_v_d, int16_t, int64_t, idx_d, ldh_d) | ||
193 | -GEN_VEXT_LD_INDEX(vlxw_v_w, int32_t, int32_t, idx_w, ldw_w) | ||
194 | -GEN_VEXT_LD_INDEX(vlxw_v_d, int32_t, int64_t, idx_d, ldw_d) | ||
195 | -GEN_VEXT_LD_INDEX(vlxe_v_b, int8_t, int8_t, idx_b, lde_b) | ||
196 | -GEN_VEXT_LD_INDEX(vlxe_v_h, int16_t, int16_t, idx_h, lde_h) | ||
197 | -GEN_VEXT_LD_INDEX(vlxe_v_w, int32_t, int32_t, idx_w, lde_w) | ||
198 | -GEN_VEXT_LD_INDEX(vlxe_v_d, int64_t, int64_t, idx_d, lde_d) | ||
199 | -GEN_VEXT_LD_INDEX(vlxbu_v_b, uint8_t, uint8_t, idx_b, ldbu_b) | ||
200 | -GEN_VEXT_LD_INDEX(vlxbu_v_h, uint8_t, uint16_t, idx_h, ldbu_h) | ||
201 | -GEN_VEXT_LD_INDEX(vlxbu_v_w, uint8_t, uint32_t, idx_w, ldbu_w) | ||
202 | -GEN_VEXT_LD_INDEX(vlxbu_v_d, uint8_t, uint64_t, idx_d, ldbu_d) | ||
203 | -GEN_VEXT_LD_INDEX(vlxhu_v_h, uint16_t, uint16_t, idx_h, ldhu_h) | ||
204 | -GEN_VEXT_LD_INDEX(vlxhu_v_w, uint16_t, uint32_t, idx_w, ldhu_w) | ||
205 | -GEN_VEXT_LD_INDEX(vlxhu_v_d, uint16_t, uint64_t, idx_d, ldhu_d) | ||
206 | -GEN_VEXT_LD_INDEX(vlxwu_v_w, uint32_t, uint32_t, idx_w, ldwu_w) | ||
207 | -GEN_VEXT_LD_INDEX(vlxwu_v_d, uint32_t, uint64_t, idx_d, ldwu_d) | ||
208 | - | ||
209 | -#define GEN_VEXT_ST_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, STORE_FN)\ | ||
210 | + LOAD_FN, sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
211 | +} | ||
212 | + | ||
213 | +GEN_VEXT_LD_INDEX(vlxei8_8_v, int8_t, idx_b, lde_b) | ||
214 | +GEN_VEXT_LD_INDEX(vlxei8_16_v, int16_t, idx_b, lde_h) | ||
215 | +GEN_VEXT_LD_INDEX(vlxei8_32_v, int32_t, idx_b, lde_w) | ||
216 | +GEN_VEXT_LD_INDEX(vlxei8_64_v, int64_t, idx_b, lde_d) | ||
217 | +GEN_VEXT_LD_INDEX(vlxei16_8_v, int8_t, idx_h, lde_b) | ||
218 | +GEN_VEXT_LD_INDEX(vlxei16_16_v, int16_t, idx_h, lde_h) | ||
219 | +GEN_VEXT_LD_INDEX(vlxei16_32_v, int32_t, idx_h, lde_w) | ||
220 | +GEN_VEXT_LD_INDEX(vlxei16_64_v, int64_t, idx_h, lde_d) | ||
221 | +GEN_VEXT_LD_INDEX(vlxei32_8_v, int8_t, idx_w, lde_b) | ||
222 | +GEN_VEXT_LD_INDEX(vlxei32_16_v, int16_t, idx_w, lde_h) | ||
223 | +GEN_VEXT_LD_INDEX(vlxei32_32_v, int32_t, idx_w, lde_w) | ||
224 | +GEN_VEXT_LD_INDEX(vlxei32_64_v, int64_t, idx_w, lde_d) | ||
225 | +GEN_VEXT_LD_INDEX(vlxei64_8_v, int8_t, idx_d, lde_b) | ||
226 | +GEN_VEXT_LD_INDEX(vlxei64_16_v, int16_t, idx_d, lde_h) | ||
227 | +GEN_VEXT_LD_INDEX(vlxei64_32_v, int32_t, idx_d, lde_w) | ||
228 | +GEN_VEXT_LD_INDEX(vlxei64_64_v, int64_t, idx_d, lde_d) | ||
229 | + | ||
230 | +#define GEN_VEXT_ST_INDEX(NAME, ETYPE, INDEX_FN, STORE_FN) \ | ||
231 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
232 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
233 | { \ | ||
234 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
235 | - STORE_FN, sizeof(ETYPE), sizeof(MTYPE), \ | ||
236 | + STORE_FN, sizeof(ETYPE), \ | ||
237 | GETPC(), MMU_DATA_STORE); \ | ||
238 | } | ||
239 | |||
240 | -GEN_VEXT_ST_INDEX(vsxb_v_b, int8_t, int8_t, idx_b, stb_b) | ||
241 | -GEN_VEXT_ST_INDEX(vsxb_v_h, int8_t, int16_t, idx_h, stb_h) | ||
242 | -GEN_VEXT_ST_INDEX(vsxb_v_w, int8_t, int32_t, idx_w, stb_w) | ||
243 | -GEN_VEXT_ST_INDEX(vsxb_v_d, int8_t, int64_t, idx_d, stb_d) | ||
244 | -GEN_VEXT_ST_INDEX(vsxh_v_h, int16_t, int16_t, idx_h, sth_h) | ||
245 | -GEN_VEXT_ST_INDEX(vsxh_v_w, int16_t, int32_t, idx_w, sth_w) | ||
246 | -GEN_VEXT_ST_INDEX(vsxh_v_d, int16_t, int64_t, idx_d, sth_d) | ||
247 | -GEN_VEXT_ST_INDEX(vsxw_v_w, int32_t, int32_t, idx_w, stw_w) | ||
248 | -GEN_VEXT_ST_INDEX(vsxw_v_d, int32_t, int64_t, idx_d, stw_d) | ||
249 | -GEN_VEXT_ST_INDEX(vsxe_v_b, int8_t, int8_t, idx_b, ste_b) | ||
250 | -GEN_VEXT_ST_INDEX(vsxe_v_h, int16_t, int16_t, idx_h, ste_h) | ||
251 | -GEN_VEXT_ST_INDEX(vsxe_v_w, int32_t, int32_t, idx_w, ste_w) | ||
252 | -GEN_VEXT_ST_INDEX(vsxe_v_d, int64_t, int64_t, idx_d, ste_d) | ||
253 | +GEN_VEXT_ST_INDEX(vsxei8_8_v, int8_t, idx_b, ste_b) | ||
254 | +GEN_VEXT_ST_INDEX(vsxei8_16_v, int16_t, idx_b, ste_h) | ||
255 | +GEN_VEXT_ST_INDEX(vsxei8_32_v, int32_t, idx_b, ste_w) | ||
256 | +GEN_VEXT_ST_INDEX(vsxei8_64_v, int64_t, idx_b, ste_d) | ||
257 | +GEN_VEXT_ST_INDEX(vsxei16_8_v, int8_t, idx_h, ste_b) | ||
258 | +GEN_VEXT_ST_INDEX(vsxei16_16_v, int16_t, idx_h, ste_h) | ||
259 | +GEN_VEXT_ST_INDEX(vsxei16_32_v, int32_t, idx_h, ste_w) | ||
260 | +GEN_VEXT_ST_INDEX(vsxei16_64_v, int64_t, idx_h, ste_d) | ||
261 | +GEN_VEXT_ST_INDEX(vsxei32_8_v, int8_t, idx_w, ste_b) | ||
262 | +GEN_VEXT_ST_INDEX(vsxei32_16_v, int16_t, idx_w, ste_h) | ||
263 | +GEN_VEXT_ST_INDEX(vsxei32_32_v, int32_t, idx_w, ste_w) | ||
264 | +GEN_VEXT_ST_INDEX(vsxei32_64_v, int64_t, idx_w, ste_d) | ||
265 | +GEN_VEXT_ST_INDEX(vsxei64_8_v, int8_t, idx_d, ste_b) | ||
266 | +GEN_VEXT_ST_INDEX(vsxei64_16_v, int16_t, idx_d, ste_h) | ||
267 | +GEN_VEXT_ST_INDEX(vsxei64_32_v, int32_t, idx_d, ste_w) | ||
268 | +GEN_VEXT_ST_INDEX(vsxei64_64_v, int64_t, idx_d, ste_d) | ||
269 | |||
270 | /* | ||
271 | *** unit-stride fault-only-fisrt load instructions | ||
272 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
273 | index XXXXXXX..XXXXXXX 100644 | ||
274 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
275 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
276 | @@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, | ||
277 | return true; | ||
278 | } | ||
279 | |||
280 | -static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
281 | +static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
282 | { | ||
283 | uint32_t data = 0; | ||
284 | gen_helper_ldst_index *fn; | ||
285 | - static gen_helper_ldst_index * const fns[7][4] = { | ||
286 | - { gen_helper_vlxb_v_b, gen_helper_vlxb_v_h, | ||
287 | - gen_helper_vlxb_v_w, gen_helper_vlxb_v_d }, | ||
288 | - { NULL, gen_helper_vlxh_v_h, | ||
289 | - gen_helper_vlxh_v_w, gen_helper_vlxh_v_d }, | ||
290 | - { NULL, NULL, | ||
291 | - gen_helper_vlxw_v_w, gen_helper_vlxw_v_d }, | ||
292 | - { gen_helper_vlxe_v_b, gen_helper_vlxe_v_h, | ||
293 | - gen_helper_vlxe_v_w, gen_helper_vlxe_v_d }, | ||
294 | - { gen_helper_vlxbu_v_b, gen_helper_vlxbu_v_h, | ||
295 | - gen_helper_vlxbu_v_w, gen_helper_vlxbu_v_d }, | ||
296 | - { NULL, gen_helper_vlxhu_v_h, | ||
297 | - gen_helper_vlxhu_v_w, gen_helper_vlxhu_v_d }, | ||
298 | - { NULL, NULL, | ||
299 | - gen_helper_vlxwu_v_w, gen_helper_vlxwu_v_d }, | ||
300 | + static gen_helper_ldst_index * const fns[4][4] = { | ||
301 | + /* | ||
302 | + * offset vector register group EEW = 8, | ||
303 | + * data vector register group EEW = SEW | ||
304 | + */ | ||
305 | + { gen_helper_vlxei8_8_v, gen_helper_vlxei8_16_v, | ||
306 | + gen_helper_vlxei8_32_v, gen_helper_vlxei8_64_v }, | ||
307 | + /* | ||
308 | + * offset vector register group EEW = 16, | ||
309 | + * data vector register group EEW = SEW | ||
310 | + */ | ||
311 | + { gen_helper_vlxei16_8_v, gen_helper_vlxei16_16_v, | ||
312 | + gen_helper_vlxei16_32_v, gen_helper_vlxei16_64_v }, | ||
313 | + /* | ||
314 | + * offset vector register group EEW = 32, | ||
315 | + * data vector register group EEW = SEW | ||
316 | + */ | ||
317 | + { gen_helper_vlxei32_8_v, gen_helper_vlxei32_16_v, | ||
318 | + gen_helper_vlxei32_32_v, gen_helper_vlxei32_64_v }, | ||
319 | + /* | ||
320 | + * offset vector register group EEW = 64, | ||
321 | + * data vector register group EEW = SEW | ||
322 | + */ | ||
323 | + { gen_helper_vlxei64_8_v, gen_helper_vlxei64_16_v, | ||
324 | + gen_helper_vlxei64_32_v, gen_helper_vlxei64_64_v } | ||
325 | }; | ||
326 | |||
327 | - fn = fns[seq][s->sew]; | ||
328 | - if (fn == NULL) { | ||
329 | - return false; | ||
330 | - } | ||
331 | + fn = fns[eew][s->sew]; | ||
332 | |||
333 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
334 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
335 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
336 | return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
337 | } | ||
338 | |||
339 | -/* | ||
340 | - * For vector indexed segment loads, the destination vector register | ||
341 | - * groups cannot overlap the source vector register group (specified by | ||
342 | - * `vs2`), else an illegal instruction exception is raised. | ||
343 | - */ | ||
344 | static bool ld_index_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
345 | { | ||
346 | return require_rvv(s) && | ||
347 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
348 | vext_check_ld_index(s, a->rd, a->rs2, a->nf, a->vm, eew); | ||
349 | } | ||
350 | |||
351 | -GEN_VEXT_TRANS(vlxb_v, 0, rnfvm, ld_index_op, ld_index_check) | ||
352 | -GEN_VEXT_TRANS(vlxh_v, 1, rnfvm, ld_index_op, ld_index_check) | ||
353 | -GEN_VEXT_TRANS(vlxw_v, 2, rnfvm, ld_index_op, ld_index_check) | ||
354 | -GEN_VEXT_TRANS(vlxe_v, 3, rnfvm, ld_index_op, ld_index_check) | ||
355 | -GEN_VEXT_TRANS(vlxbu_v, 4, rnfvm, ld_index_op, ld_index_check) | ||
356 | -GEN_VEXT_TRANS(vlxhu_v, 5, rnfvm, ld_index_op, ld_index_check) | ||
357 | -GEN_VEXT_TRANS(vlxwu_v, 6, rnfvm, ld_index_op, ld_index_check) | ||
358 | +GEN_VEXT_TRANS(vlxei8_v, MO_8, rnfvm, ld_index_op, ld_index_check) | ||
359 | +GEN_VEXT_TRANS(vlxei16_v, MO_16, rnfvm, ld_index_op, ld_index_check) | ||
360 | +GEN_VEXT_TRANS(vlxei32_v, MO_32, rnfvm, ld_index_op, ld_index_check) | ||
361 | +GEN_VEXT_TRANS(vlxei64_v, MO_64, rnfvm, ld_index_op, ld_index_check) | ||
362 | |||
363 | -static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq) | ||
364 | +static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
365 | { | ||
366 | uint32_t data = 0; | ||
367 | gen_helper_ldst_index *fn; | ||
368 | static gen_helper_ldst_index * const fns[4][4] = { | ||
369 | - { gen_helper_vsxb_v_b, gen_helper_vsxb_v_h, | ||
370 | - gen_helper_vsxb_v_w, gen_helper_vsxb_v_d }, | ||
371 | - { NULL, gen_helper_vsxh_v_h, | ||
372 | - gen_helper_vsxh_v_w, gen_helper_vsxh_v_d }, | ||
373 | - { NULL, NULL, | ||
374 | - gen_helper_vsxw_v_w, gen_helper_vsxw_v_d }, | ||
375 | - { gen_helper_vsxe_v_b, gen_helper_vsxe_v_h, | ||
376 | - gen_helper_vsxe_v_w, gen_helper_vsxe_v_d } | ||
377 | + /* | ||
378 | + * offset vector register group EEW = 8, | ||
379 | + * data vector register group EEW = SEW | ||
380 | + */ | ||
381 | + { gen_helper_vsxei8_8_v, gen_helper_vsxei8_16_v, | ||
382 | + gen_helper_vsxei8_32_v, gen_helper_vsxei8_64_v }, | ||
383 | + /* | ||
384 | + * offset vector register group EEW = 16, | ||
385 | + * data vector register group EEW = SEW | ||
386 | + */ | ||
387 | + { gen_helper_vsxei16_8_v, gen_helper_vsxei16_16_v, | ||
388 | + gen_helper_vsxei16_32_v, gen_helper_vsxei16_64_v }, | ||
389 | + /* | ||
390 | + * offset vector register group EEW = 32, | ||
391 | + * data vector register group EEW = SEW | ||
392 | + */ | ||
393 | + { gen_helper_vsxei32_8_v, gen_helper_vsxei32_16_v, | ||
394 | + gen_helper_vsxei32_32_v, gen_helper_vsxei32_64_v }, | ||
395 | + /* | ||
396 | + * offset vector register group EEW = 64, | ||
397 | + * data vector register group EEW = SEW | ||
398 | + */ | ||
399 | + { gen_helper_vsxei64_8_v, gen_helper_vsxei64_16_v, | ||
400 | + gen_helper_vsxei64_32_v, gen_helper_vsxei64_64_v } | ||
401 | }; | ||
402 | |||
403 | - fn = fns[seq][s->sew]; | ||
404 | - if (fn == NULL) { | ||
405 | - return false; | ||
406 | - } | ||
407 | + fn = fns[eew][s->sew]; | ||
408 | |||
409 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
410 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
411 | @@ -XXX,XX +XXX,XX @@ static bool st_index_check(DisasContext *s, arg_rnfvm* a, uint8_t eew) | ||
412 | vext_check_st_index(s, a->rd, a->rs2, a->nf, eew); | ||
413 | } | ||
414 | |||
415 | -GEN_VEXT_TRANS(vsxb_v, 0, rnfvm, st_index_op, st_index_check) | ||
416 | -GEN_VEXT_TRANS(vsxh_v, 1, rnfvm, st_index_op, st_index_check) | ||
417 | -GEN_VEXT_TRANS(vsxw_v, 2, rnfvm, st_index_op, st_index_check) | ||
418 | -GEN_VEXT_TRANS(vsxe_v, 3, rnfvm, st_index_op, st_index_check) | ||
419 | +GEN_VEXT_TRANS(vsxei8_v, MO_8, rnfvm, st_index_op, st_index_check) | ||
420 | +GEN_VEXT_TRANS(vsxei16_v, MO_16, rnfvm, st_index_op, st_index_check) | ||
421 | +GEN_VEXT_TRANS(vsxei32_v, MO_32, rnfvm, st_index_op, st_index_check) | ||
422 | +GEN_VEXT_TRANS(vsxei64_v, MO_64, rnfvm, st_index_op, st_index_check) | ||
423 | |||
424 | /* | ||
425 | *** unit stride fault-only-first load | ||
426 | -- | ||
427 | 2.31.1 | ||
428 | |||
429 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Replace ETYPE from signed int to unsigned int to prevent index overflow | ||
4 | issue, which would lead to wrong index address. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-23-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/vector_helper.c | 8 ++++---- | ||
13 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/vector_helper.c | ||
18 | +++ b/target/riscv/vector_helper.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static target_ulong NAME(target_ulong base, \ | ||
20 | return (base + *((ETYPE *)vs2 + H(idx))); \ | ||
21 | } | ||
22 | |||
23 | -GEN_VEXT_GET_INDEX_ADDR(idx_b, int8_t, H1) | ||
24 | -GEN_VEXT_GET_INDEX_ADDR(idx_h, int16_t, H2) | ||
25 | -GEN_VEXT_GET_INDEX_ADDR(idx_w, int32_t, H4) | ||
26 | -GEN_VEXT_GET_INDEX_ADDR(idx_d, int64_t, H8) | ||
27 | +GEN_VEXT_GET_INDEX_ADDR(idx_b, uint8_t, H1) | ||
28 | +GEN_VEXT_GET_INDEX_ADDR(idx_h, uint16_t, H2) | ||
29 | +GEN_VEXT_GET_INDEX_ADDR(idx_w, uint32_t, H4) | ||
30 | +GEN_VEXT_GET_INDEX_ADDR(idx_d, uint64_t, H8) | ||
31 | |||
32 | static inline void | ||
33 | vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
34 | -- | ||
35 | 2.31.1 | ||
36 | |||
37 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-24-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/helper.h | 26 ++------- | ||
10 | target/riscv/insn32.decode | 14 ++--- | ||
11 | target/riscv/vector_helper.c | 74 +++++++------------------ | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 33 +++-------- | ||
13 | 4 files changed, 38 insertions(+), 109 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/helper.h | ||
18 | +++ b/target/riscv/helper.h | ||
19 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, i32) | ||
20 | DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32) | ||
21 | DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32) | ||
22 | DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32) | ||
23 | -DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32) | ||
24 | -DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32) | ||
25 | -DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32) | ||
26 | -DEF_HELPER_5(vlbff_v_d, void, ptr, ptr, tl, env, i32) | ||
27 | -DEF_HELPER_5(vlhff_v_h, void, ptr, ptr, tl, env, i32) | ||
28 | -DEF_HELPER_5(vlhff_v_w, void, ptr, ptr, tl, env, i32) | ||
29 | -DEF_HELPER_5(vlhff_v_d, void, ptr, ptr, tl, env, i32) | ||
30 | -DEF_HELPER_5(vlwff_v_w, void, ptr, ptr, tl, env, i32) | ||
31 | -DEF_HELPER_5(vlwff_v_d, void, ptr, ptr, tl, env, i32) | ||
32 | -DEF_HELPER_5(vleff_v_b, void, ptr, ptr, tl, env, i32) | ||
33 | -DEF_HELPER_5(vleff_v_h, void, ptr, ptr, tl, env, i32) | ||
34 | -DEF_HELPER_5(vleff_v_w, void, ptr, ptr, tl, env, i32) | ||
35 | -DEF_HELPER_5(vleff_v_d, void, ptr, ptr, tl, env, i32) | ||
36 | -DEF_HELPER_5(vlbuff_v_b, void, ptr, ptr, tl, env, i32) | ||
37 | -DEF_HELPER_5(vlbuff_v_h, void, ptr, ptr, tl, env, i32) | ||
38 | -DEF_HELPER_5(vlbuff_v_w, void, ptr, ptr, tl, env, i32) | ||
39 | -DEF_HELPER_5(vlbuff_v_d, void, ptr, ptr, tl, env, i32) | ||
40 | -DEF_HELPER_5(vlhuff_v_h, void, ptr, ptr, tl, env, i32) | ||
41 | -DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32) | ||
42 | -DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32) | ||
43 | -DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32) | ||
44 | -DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32) | ||
45 | +DEF_HELPER_5(vle8ff_v, void, ptr, ptr, tl, env, i32) | ||
46 | +DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32) | ||
47 | +DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32) | ||
48 | +DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32) | ||
49 | |||
50 | DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
51 | DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
52 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/insn32.decode | ||
55 | +++ b/target/riscv/insn32.decode | ||
56 | @@ -XXX,XX +XXX,XX @@ vsse16_v ... 010 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
57 | vsse32_v ... 010 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
58 | vsse64_v ... 010 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
59 | |||
60 | -vlbff_v ... 100 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
61 | -vlhff_v ... 100 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
62 | -vlwff_v ... 100 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
63 | -vleff_v ... 000 . 10000 ..... 111 ..... 0000111 @r2_nfvm | ||
64 | -vlbuff_v ... 000 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
65 | -vlhuff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
66 | -vlwuff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
67 | - | ||
68 | # Vector ordered-indexed and unordered-indexed load insns. | ||
69 | vlxei8_v ... 0-1 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
70 | vlxei16_v ... 0-1 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
71 | @@ -XXX,XX +XXX,XX @@ vsxei16_v ... 0-1 . ..... ..... 101 ..... 0100111 @r_nfvm | ||
72 | vsxei32_v ... 0-1 . ..... ..... 110 ..... 0100111 @r_nfvm | ||
73 | vsxei64_v ... 0-1 . ..... ..... 111 ..... 0100111 @r_nfvm | ||
74 | |||
75 | +# Vector unit-stride fault-only-first load insns. | ||
76 | +vle8ff_v ... 000 . 10000 ..... 000 ..... 0000111 @r2_nfvm | ||
77 | +vle16ff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
78 | +vle32ff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
79 | +vle64ff_v ... 000 . 10000 ..... 111 ..... 0000111 @r2_nfvm | ||
80 | + | ||
81 | # *** new major opcode OP-V *** | ||
82 | vadd_vv 000000 . ..... ..... 000 ..... 1010111 @r_vm | ||
83 | vadd_vx 000000 . ..... ..... 100 ..... 1010111 @r_vm | ||
84 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
85 | index XXXXXXX..XXXXXXX 100644 | ||
86 | --- a/target/riscv/vector_helper.c | ||
87 | +++ b/target/riscv/vector_helper.c | ||
88 | @@ -XXX,XX +XXX,XX @@ static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
89 | *cur = cpu_##LDSUF##_data_ra(env, addr, retaddr); \ | ||
90 | } \ | ||
91 | |||
92 | -GEN_VEXT_LD_ELEM(ldb_b, int8_t, H1, ldsb) | ||
93 | -GEN_VEXT_LD_ELEM(ldb_h, int16_t, H2, ldsb) | ||
94 | -GEN_VEXT_LD_ELEM(ldb_w, int32_t, H4, ldsb) | ||
95 | -GEN_VEXT_LD_ELEM(ldb_d, int64_t, H8, ldsb) | ||
96 | -GEN_VEXT_LD_ELEM(ldh_h, int16_t, H2, ldsw) | ||
97 | -GEN_VEXT_LD_ELEM(ldh_w, int32_t, H4, ldsw) | ||
98 | -GEN_VEXT_LD_ELEM(ldh_d, int64_t, H8, ldsw) | ||
99 | -GEN_VEXT_LD_ELEM(ldw_w, int32_t, H4, ldl) | ||
100 | -GEN_VEXT_LD_ELEM(ldw_d, int64_t, H8, ldl) | ||
101 | GEN_VEXT_LD_ELEM(lde_b, int8_t, H1, ldsb) | ||
102 | GEN_VEXT_LD_ELEM(lde_h, int16_t, H2, ldsw) | ||
103 | GEN_VEXT_LD_ELEM(lde_w, int32_t, H4, ldl) | ||
104 | GEN_VEXT_LD_ELEM(lde_d, int64_t, H8, ldq) | ||
105 | -GEN_VEXT_LD_ELEM(ldbu_b, uint8_t, H1, ldub) | ||
106 | -GEN_VEXT_LD_ELEM(ldbu_h, uint16_t, H2, ldub) | ||
107 | -GEN_VEXT_LD_ELEM(ldbu_w, uint32_t, H4, ldub) | ||
108 | -GEN_VEXT_LD_ELEM(ldbu_d, uint64_t, H8, ldub) | ||
109 | -GEN_VEXT_LD_ELEM(ldhu_h, uint16_t, H2, lduw) | ||
110 | -GEN_VEXT_LD_ELEM(ldhu_w, uint32_t, H4, lduw) | ||
111 | -GEN_VEXT_LD_ELEM(ldhu_d, uint64_t, H8, lduw) | ||
112 | -GEN_VEXT_LD_ELEM(ldwu_w, uint32_t, H4, ldl) | ||
113 | -GEN_VEXT_LD_ELEM(ldwu_d, uint64_t, H8, ldl) | ||
114 | |||
115 | #define GEN_VEXT_ST_ELEM(NAME, ETYPE, H, STSUF) \ | ||
116 | static void NAME(CPURISCVState *env, abi_ptr addr, \ | ||
117 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
118 | vext_ldff(void *vd, void *v0, target_ulong base, | ||
119 | CPURISCVState *env, uint32_t desc, | ||
120 | vext_ldst_elem_fn *ldst_elem, | ||
121 | - uint32_t esz, uint32_t msz, uintptr_t ra) | ||
122 | + uint32_t esz, uintptr_t ra) | ||
123 | { | ||
124 | void *host; | ||
125 | uint32_t i, k, vl = 0; | ||
126 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
127 | if (!vm && !vext_elem_mask(v0, i)) { | ||
128 | continue; | ||
129 | } | ||
130 | - addr = base + nf * i * msz; | ||
131 | + addr = base + nf * i * esz; | ||
132 | if (i == 0) { | ||
133 | - probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD); | ||
134 | + probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD); | ||
135 | } else { | ||
136 | /* if it triggers an exception, no need to check watchpoint */ | ||
137 | - remain = nf * msz; | ||
138 | + remain = nf * esz; | ||
139 | while (remain > 0) { | ||
140 | offset = -(addr | TARGET_PAGE_MASK); | ||
141 | host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, | ||
142 | cpu_mmu_index(env, false)); | ||
143 | if (host) { | ||
144 | #ifdef CONFIG_USER_ONLY | ||
145 | - if (page_check_range(addr, nf * msz, PAGE_READ) < 0) { | ||
146 | + if (page_check_range(addr, nf * esz, PAGE_READ) < 0) { | ||
147 | vl = i; | ||
148 | goto ProbeSuccess; | ||
149 | } | ||
150 | #else | ||
151 | - probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD); | ||
152 | + probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD); | ||
153 | #endif | ||
154 | } else { | ||
155 | vl = i; | ||
156 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
157 | continue; | ||
158 | } | ||
159 | while (k < nf) { | ||
160 | - target_ulong addr = base + (i * nf + k) * msz; | ||
161 | + target_ulong addr = base + (i * nf + k) * esz; | ||
162 | ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
163 | k++; | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | |||
168 | -#define GEN_VEXT_LDFF(NAME, MTYPE, ETYPE, LOAD_FN) \ | ||
169 | -void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
170 | - CPURISCVState *env, uint32_t desc) \ | ||
171 | -{ \ | ||
172 | - vext_ldff(vd, v0, base, env, desc, LOAD_FN, \ | ||
173 | - sizeof(ETYPE), sizeof(MTYPE), GETPC()); \ | ||
174 | -} | ||
175 | - | ||
176 | -GEN_VEXT_LDFF(vlbff_v_b, int8_t, int8_t, ldb_b) | ||
177 | -GEN_VEXT_LDFF(vlbff_v_h, int8_t, int16_t, ldb_h) | ||
178 | -GEN_VEXT_LDFF(vlbff_v_w, int8_t, int32_t, ldb_w) | ||
179 | -GEN_VEXT_LDFF(vlbff_v_d, int8_t, int64_t, ldb_d) | ||
180 | -GEN_VEXT_LDFF(vlhff_v_h, int16_t, int16_t, ldh_h) | ||
181 | -GEN_VEXT_LDFF(vlhff_v_w, int16_t, int32_t, ldh_w) | ||
182 | -GEN_VEXT_LDFF(vlhff_v_d, int16_t, int64_t, ldh_d) | ||
183 | -GEN_VEXT_LDFF(vlwff_v_w, int32_t, int32_t, ldw_w) | ||
184 | -GEN_VEXT_LDFF(vlwff_v_d, int32_t, int64_t, ldw_d) | ||
185 | -GEN_VEXT_LDFF(vleff_v_b, int8_t, int8_t, lde_b) | ||
186 | -GEN_VEXT_LDFF(vleff_v_h, int16_t, int16_t, lde_h) | ||
187 | -GEN_VEXT_LDFF(vleff_v_w, int32_t, int32_t, lde_w) | ||
188 | -GEN_VEXT_LDFF(vleff_v_d, int64_t, int64_t, lde_d) | ||
189 | -GEN_VEXT_LDFF(vlbuff_v_b, uint8_t, uint8_t, ldbu_b) | ||
190 | -GEN_VEXT_LDFF(vlbuff_v_h, uint8_t, uint16_t, ldbu_h) | ||
191 | -GEN_VEXT_LDFF(vlbuff_v_w, uint8_t, uint32_t, ldbu_w) | ||
192 | -GEN_VEXT_LDFF(vlbuff_v_d, uint8_t, uint64_t, ldbu_d) | ||
193 | -GEN_VEXT_LDFF(vlhuff_v_h, uint16_t, uint16_t, ldhu_h) | ||
194 | -GEN_VEXT_LDFF(vlhuff_v_w, uint16_t, uint32_t, ldhu_w) | ||
195 | -GEN_VEXT_LDFF(vlhuff_v_d, uint16_t, uint64_t, ldhu_d) | ||
196 | -GEN_VEXT_LDFF(vlwuff_v_w, uint32_t, uint32_t, ldwu_w) | ||
197 | -GEN_VEXT_LDFF(vlwuff_v_d, uint32_t, uint64_t, ldwu_d) | ||
198 | +#define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN) \ | ||
199 | +void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
200 | + CPURISCVState *env, uint32_t desc) \ | ||
201 | +{ \ | ||
202 | + vext_ldff(vd, v0, base, env, desc, LOAD_FN, \ | ||
203 | + sizeof(ETYPE), GETPC()); \ | ||
204 | +} | ||
205 | + | ||
206 | +GEN_VEXT_LDFF(vle8ff_v, int8_t, lde_b) | ||
207 | +GEN_VEXT_LDFF(vle16ff_v, int16_t, lde_h) | ||
208 | +GEN_VEXT_LDFF(vle32ff_v, int32_t, lde_w) | ||
209 | +GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d) | ||
210 | |||
211 | #define DO_SWAP(N, M) (M) | ||
212 | #define DO_AND(N, M) (N & M) | ||
213 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
214 | index XXXXXXX..XXXXXXX 100644 | ||
215 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
216 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
217 | @@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
218 | return true; | ||
219 | } | ||
220 | |||
221 | -static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
222 | +static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
223 | { | ||
224 | uint32_t data = 0; | ||
225 | gen_helper_ldst_us *fn; | ||
226 | - static gen_helper_ldst_us * const fns[7][4] = { | ||
227 | - { gen_helper_vlbff_v_b, gen_helper_vlbff_v_h, | ||
228 | - gen_helper_vlbff_v_w, gen_helper_vlbff_v_d }, | ||
229 | - { NULL, gen_helper_vlhff_v_h, | ||
230 | - gen_helper_vlhff_v_w, gen_helper_vlhff_v_d }, | ||
231 | - { NULL, NULL, | ||
232 | - gen_helper_vlwff_v_w, gen_helper_vlwff_v_d }, | ||
233 | - { gen_helper_vleff_v_b, gen_helper_vleff_v_h, | ||
234 | - gen_helper_vleff_v_w, gen_helper_vleff_v_d }, | ||
235 | - { gen_helper_vlbuff_v_b, gen_helper_vlbuff_v_h, | ||
236 | - gen_helper_vlbuff_v_w, gen_helper_vlbuff_v_d }, | ||
237 | - { NULL, gen_helper_vlhuff_v_h, | ||
238 | - gen_helper_vlhuff_v_w, gen_helper_vlhuff_v_d }, | ||
239 | - { NULL, NULL, | ||
240 | - gen_helper_vlwuff_v_w, gen_helper_vlwuff_v_d } | ||
241 | + static gen_helper_ldst_us * const fns[4] = { | ||
242 | + gen_helper_vle8ff_v, gen_helper_vle16ff_v, | ||
243 | + gen_helper_vle32ff_v, gen_helper_vle64ff_v | ||
244 | }; | ||
245 | |||
246 | - fn = fns[seq][s->sew]; | ||
247 | + fn = fns[eew]; | ||
248 | if (fn == NULL) { | ||
249 | return false; | ||
250 | } | ||
251 | @@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq) | ||
252 | return ldff_trans(a->rd, a->rs1, data, fn, s); | ||
253 | } | ||
254 | |||
255 | -GEN_VEXT_TRANS(vlbff_v, 0, r2nfvm, ldff_op, ld_us_check) | ||
256 | -GEN_VEXT_TRANS(vlhff_v, 1, r2nfvm, ldff_op, ld_us_check) | ||
257 | -GEN_VEXT_TRANS(vlwff_v, 2, r2nfvm, ldff_op, ld_us_check) | ||
258 | -GEN_VEXT_TRANS(vleff_v, 3, r2nfvm, ldff_op, ld_us_check) | ||
259 | -GEN_VEXT_TRANS(vlbuff_v, 4, r2nfvm, ldff_op, ld_us_check) | ||
260 | -GEN_VEXT_TRANS(vlhuff_v, 5, r2nfvm, ldff_op, ld_us_check) | ||
261 | -GEN_VEXT_TRANS(vlwuff_v, 6, r2nfvm, ldff_op, ld_us_check) | ||
262 | +GEN_VEXT_TRANS(vle8ff_v, MO_8, r2nfvm, ldff_op, ld_us_check) | ||
263 | +GEN_VEXT_TRANS(vle16ff_v, MO_16, r2nfvm, ldff_op, ld_us_check) | ||
264 | +GEN_VEXT_TRANS(vle32ff_v, MO_32, r2nfvm, ldff_op, ld_us_check) | ||
265 | +GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check) | ||
266 | |||
267 | /* | ||
268 | *** Vector Integer Arithmetic Instructions | ||
269 | -- | ||
270 | 2.31.1 | ||
271 | |||
272 | diff view generated by jsdifflib |
1 | From: Thomas Huth <thuth@redhat.com> | 1 | From: Frank Chang <frank.chang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Configuring a drive with "if=none" is meant for creation of a backend | 3 | Add the following instructions: |
4 | only, it should not get automatically assigned to a device frontend. | 4 | |
5 | Use "if=pflash" for the One-Time-Programmable device instead (like | 5 | * vl<nf>re<eew>.v |
6 | it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c). | 6 | * vs<nf>r.v |
7 | 7 | ||
8 | Since the old way of configuring the device has already been published | 8 | Signed-off-by: Frank Chang <frank.chang@sifive.com> |
9 | with the previous QEMU versions, we cannot remove this immediately, but | ||
10 | have to deprecate it and support it for at least two more releases. | ||
11 | |||
12 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
13 | Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
14 | Reviewed-by: Markus Armbruster <armbru@redhat.com> | ||
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
16 | Message-id: 20211119102549.217755-1-thuth@redhat.com | 10 | Message-Id: <20211210075704.23951-25-frank.chang@sifive.com> |
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
18 | --- | 12 | --- |
19 | docs/about/deprecated.rst | 6 ++++++ | 13 | target/riscv/helper.h | 21 ++++++++ |
20 | hw/misc/sifive_u_otp.c | 9 ++++++++- | 14 | target/riscv/insn32.decode | 22 ++++++++ |
21 | 2 files changed, 14 insertions(+), 1 deletion(-) | 15 | target/riscv/vector_helper.c | 65 +++++++++++++++++++++++ |
22 | 16 | target/riscv/insn_trans/trans_rvv.c.inc | 68 +++++++++++++++++++++++++ | |
23 | diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst | 17 | 4 files changed, 176 insertions(+) |
24 | index XXXXXXX..XXXXXXX 100644 | 18 | |
25 | --- a/docs/about/deprecated.rst | 19 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h |
26 | +++ b/docs/about/deprecated.rst | 20 | index XXXXXXX..XXXXXXX 100644 |
27 | @@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``. | 21 | --- a/target/riscv/helper.h |
28 | However, short-form booleans are deprecated and full explicit ``arg_name=on`` | 22 | +++ b/target/riscv/helper.h |
29 | form is preferred. | 23 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32) |
30 | 24 | DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32) | |
31 | +``-drive if=none`` for the sifive_u OTP device (since 6.2) | 25 | DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32) |
32 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | 26 | |
33 | + | 27 | +DEF_HELPER_4(vl1re8_v, void, ptr, tl, env, i32) |
34 | +Using ``-drive if=none`` to configure the OTP device of the sifive_u | 28 | +DEF_HELPER_4(vl1re16_v, void, ptr, tl, env, i32) |
35 | +RISC-V machine is deprecated. Use ``-drive if=pflash`` instead. | 29 | +DEF_HELPER_4(vl1re32_v, void, ptr, tl, env, i32) |
36 | + | 30 | +DEF_HELPER_4(vl1re64_v, void, ptr, tl, env, i32) |
37 | 31 | +DEF_HELPER_4(vl2re8_v, void, ptr, tl, env, i32) | |
38 | QEMU Machine Protocol (QMP) commands | 32 | +DEF_HELPER_4(vl2re16_v, void, ptr, tl, env, i32) |
39 | ------------------------------------ | 33 | +DEF_HELPER_4(vl2re32_v, void, ptr, tl, env, i32) |
40 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | 34 | +DEF_HELPER_4(vl2re64_v, void, ptr, tl, env, i32) |
41 | index XXXXXXX..XXXXXXX 100644 | 35 | +DEF_HELPER_4(vl4re8_v, void, ptr, tl, env, i32) |
42 | --- a/hw/misc/sifive_u_otp.c | 36 | +DEF_HELPER_4(vl4re16_v, void, ptr, tl, env, i32) |
43 | +++ b/hw/misc/sifive_u_otp.c | 37 | +DEF_HELPER_4(vl4re32_v, void, ptr, tl, env, i32) |
44 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 38 | +DEF_HELPER_4(vl4re64_v, void, ptr, tl, env, i32) |
45 | TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); | 39 | +DEF_HELPER_4(vl8re8_v, void, ptr, tl, env, i32) |
46 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); | 40 | +DEF_HELPER_4(vl8re16_v, void, ptr, tl, env, i32) |
47 | 41 | +DEF_HELPER_4(vl8re32_v, void, ptr, tl, env, i32) | |
48 | - dinfo = drive_get_next(IF_NONE); | 42 | +DEF_HELPER_4(vl8re64_v, void, ptr, tl, env, i32) |
49 | + dinfo = drive_get_next(IF_PFLASH); | 43 | +DEF_HELPER_4(vs1r_v, void, ptr, tl, env, i32) |
50 | + if (!dinfo) { | 44 | +DEF_HELPER_4(vs2r_v, void, ptr, tl, env, i32) |
51 | + dinfo = drive_get_next(IF_NONE); | 45 | +DEF_HELPER_4(vs4r_v, void, ptr, tl, env, i32) |
52 | + if (dinfo) { | 46 | +DEF_HELPER_4(vs8r_v, void, ptr, tl, env, i32) |
53 | + warn_report("using \"-drive if=none\" for the OTP is deprecated, " | 47 | + |
54 | + "use \"-drive if=pflash\" instead."); | 48 | DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) |
49 | DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
50 | DEF_HELPER_6(vadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
51 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/target/riscv/insn32.decode | ||
54 | +++ b/target/riscv/insn32.decode | ||
55 | @@ -XXX,XX +XXX,XX @@ vle16ff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm | ||
56 | vle32ff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm | ||
57 | vle64ff_v ... 000 . 10000 ..... 111 ..... 0000111 @r2_nfvm | ||
58 | |||
59 | +# Vector whole register insns | ||
60 | +vl1re8_v 000 000 1 01000 ..... 000 ..... 0000111 @r2 | ||
61 | +vl1re16_v 000 000 1 01000 ..... 101 ..... 0000111 @r2 | ||
62 | +vl1re32_v 000 000 1 01000 ..... 110 ..... 0000111 @r2 | ||
63 | +vl1re64_v 000 000 1 01000 ..... 111 ..... 0000111 @r2 | ||
64 | +vl2re8_v 001 000 1 01000 ..... 000 ..... 0000111 @r2 | ||
65 | +vl2re16_v 001 000 1 01000 ..... 101 ..... 0000111 @r2 | ||
66 | +vl2re32_v 001 000 1 01000 ..... 110 ..... 0000111 @r2 | ||
67 | +vl2re64_v 001 000 1 01000 ..... 111 ..... 0000111 @r2 | ||
68 | +vl4re8_v 011 000 1 01000 ..... 000 ..... 0000111 @r2 | ||
69 | +vl4re16_v 011 000 1 01000 ..... 101 ..... 0000111 @r2 | ||
70 | +vl4re32_v 011 000 1 01000 ..... 110 ..... 0000111 @r2 | ||
71 | +vl4re64_v 011 000 1 01000 ..... 111 ..... 0000111 @r2 | ||
72 | +vl8re8_v 111 000 1 01000 ..... 000 ..... 0000111 @r2 | ||
73 | +vl8re16_v 111 000 1 01000 ..... 101 ..... 0000111 @r2 | ||
74 | +vl8re32_v 111 000 1 01000 ..... 110 ..... 0000111 @r2 | ||
75 | +vl8re64_v 111 000 1 01000 ..... 111 ..... 0000111 @r2 | ||
76 | +vs1r_v 000 000 1 01000 ..... 000 ..... 0100111 @r2 | ||
77 | +vs2r_v 001 000 1 01000 ..... 000 ..... 0100111 @r2 | ||
78 | +vs4r_v 011 000 1 01000 ..... 000 ..... 0100111 @r2 | ||
79 | +vs8r_v 111 000 1 01000 ..... 000 ..... 0100111 @r2 | ||
80 | + | ||
81 | # *** new major opcode OP-V *** | ||
82 | vadd_vv 000000 . ..... ..... 000 ..... 1010111 @r_vm | ||
83 | vadd_vx 000000 . ..... ..... 100 ..... 1010111 @r_vm | ||
84 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
85 | index XXXXXXX..XXXXXXX 100644 | ||
86 | --- a/target/riscv/vector_helper.c | ||
87 | +++ b/target/riscv/vector_helper.c | ||
88 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d) | ||
89 | #define DO_MAXU(N, M) DO_MAX((UMTYPE)N, (UMTYPE)M) | ||
90 | #define DO_MINU(N, M) DO_MIN((UMTYPE)N, (UMTYPE)M) | ||
91 | |||
92 | +/* | ||
93 | + *** load and store whole register instructions | ||
94 | + */ | ||
95 | +static void | ||
96 | +vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
97 | + vext_ldst_elem_fn *ldst_elem, uint32_t esz, uintptr_t ra, | ||
98 | + MMUAccessType access_type) | ||
99 | +{ | ||
100 | + uint32_t i, k; | ||
101 | + uint32_t nf = vext_nf(desc); | ||
102 | + uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3; | ||
103 | + uint32_t max_elems = vlenb >> esz; | ||
104 | + | ||
105 | + /* probe every access */ | ||
106 | + probe_pages(env, base, vlenb * nf, ra, access_type); | ||
107 | + | ||
108 | + /* load bytes from guest memory */ | ||
109 | + for (k = 0; k < nf; k++) { | ||
110 | + for (i = 0; i < max_elems; i++) { | ||
111 | + target_ulong addr = base + ((i + k * max_elems) << esz); | ||
112 | + ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
55 | + } | 113 | + } |
56 | + } | 114 | + } |
57 | if (dinfo) { | 115 | +} |
58 | int ret; | 116 | + |
59 | uint64_t perm; | 117 | +#define GEN_VEXT_LD_WHOLE(NAME, ETYPE, LOAD_FN) \ |
118 | +void HELPER(NAME)(void *vd, target_ulong base, \ | ||
119 | + CPURISCVState *env, uint32_t desc) \ | ||
120 | +{ \ | ||
121 | + vext_ldst_whole(vd, base, env, desc, LOAD_FN, \ | ||
122 | + ctzl(sizeof(ETYPE)), GETPC(), \ | ||
123 | + MMU_DATA_LOAD); \ | ||
124 | +} | ||
125 | + | ||
126 | +GEN_VEXT_LD_WHOLE(vl1re8_v, int8_t, lde_b) | ||
127 | +GEN_VEXT_LD_WHOLE(vl1re16_v, int16_t, lde_h) | ||
128 | +GEN_VEXT_LD_WHOLE(vl1re32_v, int32_t, lde_w) | ||
129 | +GEN_VEXT_LD_WHOLE(vl1re64_v, int64_t, lde_d) | ||
130 | +GEN_VEXT_LD_WHOLE(vl2re8_v, int8_t, lde_b) | ||
131 | +GEN_VEXT_LD_WHOLE(vl2re16_v, int16_t, lde_h) | ||
132 | +GEN_VEXT_LD_WHOLE(vl2re32_v, int32_t, lde_w) | ||
133 | +GEN_VEXT_LD_WHOLE(vl2re64_v, int64_t, lde_d) | ||
134 | +GEN_VEXT_LD_WHOLE(vl4re8_v, int8_t, lde_b) | ||
135 | +GEN_VEXT_LD_WHOLE(vl4re16_v, int16_t, lde_h) | ||
136 | +GEN_VEXT_LD_WHOLE(vl4re32_v, int32_t, lde_w) | ||
137 | +GEN_VEXT_LD_WHOLE(vl4re64_v, int64_t, lde_d) | ||
138 | +GEN_VEXT_LD_WHOLE(vl8re8_v, int8_t, lde_b) | ||
139 | +GEN_VEXT_LD_WHOLE(vl8re16_v, int16_t, lde_h) | ||
140 | +GEN_VEXT_LD_WHOLE(vl8re32_v, int32_t, lde_w) | ||
141 | +GEN_VEXT_LD_WHOLE(vl8re64_v, int64_t, lde_d) | ||
142 | + | ||
143 | +#define GEN_VEXT_ST_WHOLE(NAME, ETYPE, STORE_FN) \ | ||
144 | +void HELPER(NAME)(void *vd, target_ulong base, \ | ||
145 | + CPURISCVState *env, uint32_t desc) \ | ||
146 | +{ \ | ||
147 | + vext_ldst_whole(vd, base, env, desc, STORE_FN, \ | ||
148 | + ctzl(sizeof(ETYPE)), GETPC(), \ | ||
149 | + MMU_DATA_STORE); \ | ||
150 | +} | ||
151 | + | ||
152 | +GEN_VEXT_ST_WHOLE(vs1r_v, int8_t, ste_b) | ||
153 | +GEN_VEXT_ST_WHOLE(vs2r_v, int8_t, ste_b) | ||
154 | +GEN_VEXT_ST_WHOLE(vs4r_v, int8_t, ste_b) | ||
155 | +GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b) | ||
156 | + | ||
157 | /* | ||
158 | *** Vector Integer Arithmetic Instructions | ||
159 | */ | ||
160 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
161 | index XXXXXXX..XXXXXXX 100644 | ||
162 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
163 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
164 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_TRANS(vle16ff_v, MO_16, r2nfvm, ldff_op, ld_us_check) | ||
165 | GEN_VEXT_TRANS(vle32ff_v, MO_32, r2nfvm, ldff_op, ld_us_check) | ||
166 | GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check) | ||
167 | |||
168 | +/* | ||
169 | + * load and store whole register instructions | ||
170 | + */ | ||
171 | +typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32); | ||
172 | + | ||
173 | +static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf, | ||
174 | + gen_helper_ldst_whole *fn, DisasContext *s, | ||
175 | + bool is_store) | ||
176 | +{ | ||
177 | + TCGv_ptr dest; | ||
178 | + TCGv base; | ||
179 | + TCGv_i32 desc; | ||
180 | + | ||
181 | + uint32_t data = FIELD_DP32(0, VDATA, NF, nf); | ||
182 | + dest = tcg_temp_new_ptr(); | ||
183 | + desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
184 | + | ||
185 | + base = get_gpr(s, rs1, EXT_NONE); | ||
186 | + tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd)); | ||
187 | + | ||
188 | + fn(dest, base, cpu_env, desc); | ||
189 | + | ||
190 | + tcg_temp_free_ptr(dest); | ||
191 | + | ||
192 | + if (!is_store) { | ||
193 | + mark_vs_dirty(s); | ||
194 | + } | ||
195 | + | ||
196 | + return true; | ||
197 | +} | ||
198 | + | ||
199 | +/* | ||
200 | + * load and store whole register instructions ignore vtype and vl setting. | ||
201 | + * Thus, we don't need to check vill bit. (Section 7.9) | ||
202 | + */ | ||
203 | +#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, IS_STORE) \ | ||
204 | +static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
205 | +{ \ | ||
206 | + if (require_rvv(s) && \ | ||
207 | + QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \ | ||
208 | + return ldst_whole_trans(a->rd, a->rs1, ARG_NF, gen_helper_##NAME, \ | ||
209 | + s, IS_STORE); \ | ||
210 | + } \ | ||
211 | + return false; \ | ||
212 | +} | ||
213 | + | ||
214 | +GEN_LDST_WHOLE_TRANS(vl1re8_v, 1, false) | ||
215 | +GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, false) | ||
216 | +GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, false) | ||
217 | +GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, false) | ||
218 | +GEN_LDST_WHOLE_TRANS(vl2re8_v, 2, false) | ||
219 | +GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, false) | ||
220 | +GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, false) | ||
221 | +GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, false) | ||
222 | +GEN_LDST_WHOLE_TRANS(vl4re8_v, 4, false) | ||
223 | +GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, false) | ||
224 | +GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, false) | ||
225 | +GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, false) | ||
226 | +GEN_LDST_WHOLE_TRANS(vl8re8_v, 8, false) | ||
227 | +GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, false) | ||
228 | +GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, false) | ||
229 | +GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, false) | ||
230 | + | ||
231 | +GEN_LDST_WHOLE_TRANS(vs1r_v, 1, true) | ||
232 | +GEN_LDST_WHOLE_TRANS(vs2r_v, 2, true) | ||
233 | +GEN_LDST_WHOLE_TRANS(vs4r_v, 4, true) | ||
234 | +GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true) | ||
235 | + | ||
236 | /* | ||
237 | *** Vector Integer Arithmetic Instructions | ||
238 | */ | ||
60 | -- | 239 | -- |
61 | 2.31.1 | 240 | 2.31.1 |
62 | 241 | ||
63 | 242 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-26-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/vector_helper.c | 99 ++++++++++++++----------- | ||
9 | target/riscv/insn_trans/trans_rvv.c.inc | 32 ++++++-- | ||
10 | 2 files changed, 80 insertions(+), 51 deletions(-) | ||
11 | |||
12 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/vector_helper.c | ||
15 | +++ b/target/riscv/vector_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ | ||
17 | */ | ||
18 | |||
19 | #include "qemu/osdep.h" | ||
20 | +#include "qemu/host-utils.h" | ||
21 | #include "cpu.h" | ||
22 | #include "exec/memop.h" | ||
23 | #include "exec/exec-all.h" | ||
24 | @@ -XXX,XX +XXX,XX @@ static inline int32_t vext_lmul(uint32_t desc) | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | - * Get vector group length in bytes. Its range is [64, 2048]. | ||
29 | + * Get the maximum number of elements can be operated. | ||
30 | * | ||
31 | - * As simd_desc support at most 256, the max vlen is 512 bits. | ||
32 | - * So vlen in bytes is encoded as maxsz. | ||
33 | + * esz: log2 of element size in bytes. | ||
34 | */ | ||
35 | -static inline uint32_t vext_maxsz(uint32_t desc) | ||
36 | +static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz) | ||
37 | { | ||
38 | - return simd_maxsz(desc) << vext_lmul(desc); | ||
39 | + /* | ||
40 | + * As simd_desc support at most 256 bytes, the max vlen is 256 bits. | ||
41 | + * so vlen in bytes (vlenb) is encoded as maxsz. | ||
42 | + */ | ||
43 | + uint32_t vlenb = simd_maxsz(desc); | ||
44 | + | ||
45 | + /* Return VLMAX */ | ||
46 | + int scale = vext_lmul(desc) - esz; | ||
47 | + return scale < 0 ? vlenb >> -scale : vlenb << scale; | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
52 | { | ||
53 | uint32_t i, k; | ||
54 | uint32_t nf = vext_nf(desc); | ||
55 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
56 | + uint32_t max_elems = vext_max_elems(desc, esz); | ||
57 | |||
58 | /* probe every access*/ | ||
59 | for (i = 0; i < env->vl; i++) { | ||
60 | if (!vm && !vext_elem_mask(v0, i)) { | ||
61 | continue; | ||
62 | } | ||
63 | - probe_pages(env, base + stride * i, nf * esz, ra, access_type); | ||
64 | + probe_pages(env, base + stride * i, nf << esz, ra, access_type); | ||
65 | } | ||
66 | /* do real access */ | ||
67 | for (i = 0; i < env->vl; i++) { | ||
68 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
69 | continue; | ||
70 | } | ||
71 | while (k < nf) { | ||
72 | - target_ulong addr = base + stride * i + k * esz; | ||
73 | - ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
74 | + target_ulong addr = base + stride * i + (k << esz); | ||
75 | + ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
76 | k++; | ||
77 | } | ||
78 | } | ||
79 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void * v0, target_ulong base, \ | ||
80 | { \ | ||
81 | uint32_t vm = vext_vm(desc); \ | ||
82 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \ | ||
83 | - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
84 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \ | ||
85 | } | ||
86 | |||
87 | GEN_VEXT_LD_STRIDE(vlse8_v, int8_t, lde_b) | ||
88 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
89 | { \ | ||
90 | uint32_t vm = vext_vm(desc); \ | ||
91 | vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN, \ | ||
92 | - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
93 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
94 | } | ||
95 | |||
96 | GEN_VEXT_ST_STRIDE(vsse8_v, int8_t, ste_b) | ||
97 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
98 | { | ||
99 | uint32_t i, k; | ||
100 | uint32_t nf = vext_nf(desc); | ||
101 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
102 | + uint32_t max_elems = vext_max_elems(desc, esz); | ||
103 | |||
104 | /* probe every access */ | ||
105 | - probe_pages(env, base, env->vl * nf * esz, ra, access_type); | ||
106 | + probe_pages(env, base, env->vl * (nf << esz), ra, access_type); | ||
107 | /* load bytes from guest memory */ | ||
108 | for (i = 0; i < env->vl; i++) { | ||
109 | k = 0; | ||
110 | while (k < nf) { | ||
111 | - target_ulong addr = base + (i * nf + k) * esz; | ||
112 | - ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
113 | + target_ulong addr = base + ((i * nf + k) << esz); | ||
114 | + ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
115 | k++; | ||
116 | } | ||
117 | } | ||
118 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
119 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
120 | CPURISCVState *env, uint32_t desc) \ | ||
121 | { \ | ||
122 | - uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \ | ||
123 | + uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \ | ||
124 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN, \ | ||
125 | - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
126 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \ | ||
127 | } \ | ||
128 | \ | ||
129 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
130 | CPURISCVState *env, uint32_t desc) \ | ||
131 | { \ | ||
132 | vext_ldst_us(vd, base, env, desc, LOAD_FN, \ | ||
133 | - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
134 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \ | ||
135 | } | ||
136 | |||
137 | GEN_VEXT_LD_US(vle8_v, int8_t, lde_b) | ||
138 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_LD_US(vle64_v, int64_t, lde_d) | ||
139 | void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
140 | CPURISCVState *env, uint32_t desc) \ | ||
141 | { \ | ||
142 | - uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \ | ||
143 | + uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \ | ||
144 | vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \ | ||
145 | - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
146 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
147 | } \ | ||
148 | \ | ||
149 | void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
150 | CPURISCVState *env, uint32_t desc) \ | ||
151 | { \ | ||
152 | vext_ldst_us(vd, base, env, desc, STORE_FN, \ | ||
153 | - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \ | ||
154 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
155 | } | ||
156 | |||
157 | GEN_VEXT_ST_US(vse8_v, int8_t, ste_b) | ||
158 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
159 | uint32_t i, k; | ||
160 | uint32_t nf = vext_nf(desc); | ||
161 | uint32_t vm = vext_vm(desc); | ||
162 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
163 | + uint32_t max_elems = vext_max_elems(desc, esz); | ||
164 | |||
165 | /* probe every access*/ | ||
166 | for (i = 0; i < env->vl; i++) { | ||
167 | if (!vm && !vext_elem_mask(v0, i)) { | ||
168 | continue; | ||
169 | } | ||
170 | - probe_pages(env, get_index_addr(base, i, vs2), nf * esz, ra, | ||
171 | + probe_pages(env, get_index_addr(base, i, vs2), nf << esz, ra, | ||
172 | access_type); | ||
173 | } | ||
174 | /* load bytes from guest memory */ | ||
175 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
176 | continue; | ||
177 | } | ||
178 | while (k < nf) { | ||
179 | - abi_ptr addr = get_index_addr(base, i, vs2) + k * esz; | ||
180 | - ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
181 | + abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz); | ||
182 | + ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
183 | k++; | ||
184 | } | ||
185 | } | ||
186 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
187 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
188 | { \ | ||
189 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
190 | - LOAD_FN, sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \ | ||
191 | + LOAD_FN, ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \ | ||
192 | } | ||
193 | |||
194 | GEN_VEXT_LD_INDEX(vlxei8_8_v, int8_t, idx_b, lde_b) | ||
195 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
196 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
197 | { \ | ||
198 | vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \ | ||
199 | - STORE_FN, sizeof(ETYPE), \ | ||
200 | + STORE_FN, ctzl(sizeof(ETYPE)), \ | ||
201 | GETPC(), MMU_DATA_STORE); \ | ||
202 | } | ||
203 | |||
204 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
205 | uint32_t i, k, vl = 0; | ||
206 | uint32_t nf = vext_nf(desc); | ||
207 | uint32_t vm = vext_vm(desc); | ||
208 | - uint32_t vlmax = vext_maxsz(desc) / esz; | ||
209 | + uint32_t max_elems = vext_max_elems(desc, esz); | ||
210 | target_ulong addr, offset, remain; | ||
211 | |||
212 | /* probe every access*/ | ||
213 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
214 | if (!vm && !vext_elem_mask(v0, i)) { | ||
215 | continue; | ||
216 | } | ||
217 | - addr = base + nf * i * esz; | ||
218 | + addr = base + i * (nf << esz); | ||
219 | if (i == 0) { | ||
220 | - probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD); | ||
221 | + probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD); | ||
222 | } else { | ||
223 | /* if it triggers an exception, no need to check watchpoint */ | ||
224 | - remain = nf * esz; | ||
225 | + remain = nf << esz; | ||
226 | while (remain > 0) { | ||
227 | offset = -(addr | TARGET_PAGE_MASK); | ||
228 | host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, | ||
229 | cpu_mmu_index(env, false)); | ||
230 | if (host) { | ||
231 | #ifdef CONFIG_USER_ONLY | ||
232 | - if (page_check_range(addr, nf * esz, PAGE_READ) < 0) { | ||
233 | + if (page_check_range(addr, nf << esz, PAGE_READ) < 0) { | ||
234 | vl = i; | ||
235 | goto ProbeSuccess; | ||
236 | } | ||
237 | #else | ||
238 | - probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD); | ||
239 | + probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD); | ||
240 | #endif | ||
241 | } else { | ||
242 | vl = i; | ||
243 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
244 | continue; | ||
245 | } | ||
246 | while (k < nf) { | ||
247 | - target_ulong addr = base + (i * nf + k) * esz; | ||
248 | - ldst_elem(env, addr, i + k * vlmax, vd, ra); | ||
249 | + target_ulong addr = base + ((i * nf + k) << esz); | ||
250 | + ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
251 | k++; | ||
252 | } | ||
253 | } | ||
254 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
255 | CPURISCVState *env, uint32_t desc) \ | ||
256 | { \ | ||
257 | vext_ldff(vd, v0, base, env, desc, LOAD_FN, \ | ||
258 | - sizeof(ETYPE), GETPC()); \ | ||
259 | + ctzl(sizeof(ETYPE)), GETPC()); \ | ||
260 | } | ||
261 | |||
262 | GEN_VEXT_LDFF(vle8ff_v, int8_t, lde_b) | ||
263 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
264 | CPURISCVState *env, uint32_t desc) \ | ||
265 | { \ | ||
266 | uint32_t vl = env->vl; \ | ||
267 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
268 | + uint32_t vlmax = vext_max_elems(desc, \ | ||
269 | + ctzl(sizeof(ETYPE))); \ | ||
270 | uint32_t i; \ | ||
271 | \ | ||
272 | for (i = 0; i < vl; i++) { \ | ||
273 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
274 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
275 | { \ | ||
276 | uint32_t vl = env->vl; \ | ||
277 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
278 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
279 | uint32_t i; \ | ||
280 | \ | ||
281 | for (i = 0; i < vl; i++) { \ | ||
282 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
283 | { \ | ||
284 | uint32_t vm = vext_vm(desc); \ | ||
285 | uint32_t vl = env->vl; \ | ||
286 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
287 | + uint32_t vlmax = vext_max_elems(desc, \ | ||
288 | + ctzl(sizeof(ETYPE))); \ | ||
289 | uint32_t i; \ | ||
290 | \ | ||
291 | for (i = 0; i < vl; i++) { \ | ||
292 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
293 | { \ | ||
294 | uint32_t vm = vext_vm(desc); \ | ||
295 | uint32_t vl = env->vl; \ | ||
296 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
297 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
298 | uint32_t i; \ | ||
299 | \ | ||
300 | for (i = 0; i < vl; i++) { \ | ||
301 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
302 | { \ | ||
303 | uint32_t vm = vext_vm(desc); \ | ||
304 | uint32_t vl = env->vl; \ | ||
305 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
306 | + uint32_t vlmax = vext_max_elems(desc, \ | ||
307 | + ctzl(sizeof(ETYPE))); \ | ||
308 | uint32_t i; \ | ||
309 | \ | ||
310 | for (i = 0; i < vl; i++) { \ | ||
311 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
312 | { \ | ||
313 | uint32_t vm = vext_vm(desc); \ | ||
314 | uint32_t vl = env->vl; \ | ||
315 | - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \ | ||
316 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
317 | uint32_t i; \ | ||
318 | \ | ||
319 | for (i = 0; i < vl; i++) { \ | ||
320 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) | ||
321 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
322 | CPURISCVState *env, uint32_t desc) \ | ||
323 | { \ | ||
324 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
325 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
326 | uint32_t vm = vext_vm(desc); \ | ||
327 | uint32_t vl = env->vl; \ | ||
328 | uint64_t index; \ | ||
329 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8) | ||
330 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
331 | CPURISCVState *env, uint32_t desc) \ | ||
332 | { \ | ||
333 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
334 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
335 | uint32_t vm = vext_vm(desc); \ | ||
336 | uint32_t vl = env->vl; \ | ||
337 | uint64_t index = s1; \ | ||
338 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
339 | index XXXXXXX..XXXXXXX 100644 | ||
340 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
341 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
342 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE * a) \ | ||
343 | return false; \ | ||
344 | } | ||
345 | |||
346 | +static uint8_t vext_get_emul(DisasContext *s, uint8_t eew) | ||
347 | +{ | ||
348 | + int8_t emul = eew - s->sew + s->lmul; | ||
349 | + return emul < 0 ? 0 : emul; | ||
350 | +} | ||
351 | + | ||
352 | /* | ||
353 | *** unit stride load and store | ||
354 | */ | ||
355 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
356 | return false; | ||
357 | } | ||
358 | |||
359 | + /* | ||
360 | + * Vector load/store instructions have the EEW encoded | ||
361 | + * directly in the instructions. The maximum vector size is | ||
362 | + * calculated with EMUL rather than LMUL. | ||
363 | + */ | ||
364 | + uint8_t emul = vext_get_emul(s, eew); | ||
365 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
366 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
367 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
368 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
369 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
370 | } | ||
371 | @@ -XXX,XX +XXX,XX @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
372 | return false; | ||
373 | } | ||
374 | |||
375 | + uint8_t emul = vext_get_emul(s, eew); | ||
376 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
377 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
378 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
379 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
380 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, true); | ||
381 | } | ||
382 | @@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
383 | return false; | ||
384 | } | ||
385 | |||
386 | + uint8_t emul = vext_get_emul(s, eew); | ||
387 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
388 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
389 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
390 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
391 | return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
392 | } | ||
393 | @@ -XXX,XX +XXX,XX @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
394 | gen_helper_vsse32_v, gen_helper_vsse64_v | ||
395 | }; | ||
396 | |||
397 | + uint8_t emul = vext_get_emul(s, eew); | ||
398 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
399 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
400 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
401 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
402 | fn = fns[eew]; | ||
403 | if (fn == NULL) { | ||
404 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
405 | |||
406 | fn = fns[eew][s->sew]; | ||
407 | |||
408 | + uint8_t emul = vext_get_emul(s, s->sew); | ||
409 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
410 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
411 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
412 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
413 | return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
414 | } | ||
415 | @@ -XXX,XX +XXX,XX @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
416 | |||
417 | fn = fns[eew][s->sew]; | ||
418 | |||
419 | + uint8_t emul = vext_get_emul(s, s->sew); | ||
420 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
421 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
422 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
423 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
424 | return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true); | ||
425 | } | ||
426 | @@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
427 | return false; | ||
428 | } | ||
429 | |||
430 | + uint8_t emul = vext_get_emul(s, eew); | ||
431 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
432 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
433 | + data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
434 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
435 | return ldff_trans(a->rd, a->rs1, data, fn, s); | ||
436 | } | ||
437 | -- | ||
438 | 2.31.1 | ||
439 | |||
440 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Update vext_get_vlmax() and MAXSZ() to take fractional LMUL into | ||
4 | calculation for RVV 1.0. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-27-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/cpu.h | 27 ++++++++++++++++--------- | ||
13 | target/riscv/cpu_helper.c | 16 ++++++++++++--- | ||
14 | target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++++++- | ||
15 | 3 files changed, 42 insertions(+), 13 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.h | ||
20 | +++ b/target/riscv/cpu.h | ||
21 | @@ -XXX,XX +XXX,XX @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env) | ||
22 | #endif | ||
23 | |||
24 | /* | ||
25 | - * A simplification for VLMAX | ||
26 | - * = (1 << LMUL) * VLEN / (8 * (1 << SEW)) | ||
27 | - * = (VLEN << LMUL) / (8 << SEW) | ||
28 | - * = (VLEN << LMUL) >> (SEW + 3) | ||
29 | - * = VLEN >> (SEW + 3 - LMUL) | ||
30 | + * Encode LMUL to lmul as follows: | ||
31 | + * LMUL vlmul lmul | ||
32 | + * 1 000 0 | ||
33 | + * 2 001 1 | ||
34 | + * 4 010 2 | ||
35 | + * 8 011 3 | ||
36 | + * - 100 - | ||
37 | + * 1/8 101 -3 | ||
38 | + * 1/4 110 -2 | ||
39 | + * 1/2 111 -1 | ||
40 | + * | ||
41 | + * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul) | ||
42 | + * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8 | ||
43 | + * => VLMAX = vlen >> (1 + 3 - (-3)) | ||
44 | + * = 256 >> 7 | ||
45 | + * = 2 | ||
46 | */ | ||
47 | static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) | ||
48 | { | ||
49 | - uint8_t sew, lmul; | ||
50 | - | ||
51 | - sew = FIELD_EX64(vtype, VTYPE, VSEW); | ||
52 | - lmul = FIELD_EX64(vtype, VTYPE, VLMUL); | ||
53 | + uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW); | ||
54 | + int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3); | ||
55 | return cpu->cfg.vlen >> (sew + 3 - lmul); | ||
56 | } | ||
57 | |||
58 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/cpu_helper.c | ||
61 | +++ b/target/riscv/cpu_helper.c | ||
62 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | ||
63 | *cs_base = 0; | ||
64 | |||
65 | if (riscv_has_ext(env, RVV)) { | ||
66 | + /* | ||
67 | + * If env->vl equals to VLMAX, we can use generic vector operation | ||
68 | + * expanders (GVEC) to accerlate the vector operations. | ||
69 | + * However, as LMUL could be a fractional number. The maximum | ||
70 | + * vector size can be operated might be less than 8 bytes, | ||
71 | + * which is not supported by GVEC. So we set vl_eq_vlmax flag to true | ||
72 | + * only when maxsz >= 8 bytes. | ||
73 | + */ | ||
74 | uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype); | ||
75 | - bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl); | ||
76 | + uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW); | ||
77 | + uint32_t maxsz = vlmax << sew; | ||
78 | + bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) && | ||
79 | + (maxsz >= 8); | ||
80 | flags = FIELD_DP32(flags, TB_FLAGS, VILL, | ||
81 | FIELD_EX64(env->vtype, VTYPE, VILL)); | ||
82 | - flags = FIELD_DP32(flags, TB_FLAGS, SEW, | ||
83 | - FIELD_EX64(env->vtype, VTYPE, VSEW)); | ||
84 | + flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew); | ||
85 | flags = FIELD_DP32(flags, TB_FLAGS, LMUL, | ||
86 | FIELD_EX64(env->vtype, VTYPE, VLMUL)); | ||
87 | flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); | ||
88 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
91 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
92 | @@ -XXX,XX +XXX,XX @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true) | ||
93 | /* | ||
94 | *** Vector Integer Arithmetic Instructions | ||
95 | */ | ||
96 | -#define MAXSZ(s) (s->vlen >> (3 - s->lmul)) | ||
97 | + | ||
98 | +/* | ||
99 | + * MAXSZ returns the maximum vector size can be operated in bytes, | ||
100 | + * which is used in GVEC IR when vl_eq_vlmax flag is set to true | ||
101 | + * to accerlate vector operation. | ||
102 | + */ | ||
103 | +static inline uint32_t MAXSZ(DisasContext *s) | ||
104 | +{ | ||
105 | + int scale = s->lmul - 3; | ||
106 | + return scale < 0 ? s->vlen >> -scale : s->vlen << scale; | ||
107 | +} | ||
108 | |||
109 | static bool opivv_check(DisasContext *s, arg_rmrr *a) | ||
110 | { | ||
111 | -- | ||
112 | 2.31.1 | ||
113 | |||
114 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-28-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/insn32.decode | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/insn32.decode | ||
15 | +++ b/target/riscv/insn32.decode | ||
16 | @@ -XXX,XX +XXX,XX @@ vfwmsac_vv 111110 . ..... ..... 001 ..... 1010111 @r_vm | ||
17 | vfwmsac_vf 111110 . ..... ..... 101 ..... 1010111 @r_vm | ||
18 | vfwnmsac_vv 111111 . ..... ..... 001 ..... 1010111 @r_vm | ||
19 | vfwnmsac_vf 111111 . ..... ..... 101 ..... 1010111 @r_vm | ||
20 | -vfsqrt_v 100011 . ..... 00000 001 ..... 1010111 @r2_vm | ||
21 | +vfsqrt_v 010011 . ..... 00000 001 ..... 1010111 @r2_vm | ||
22 | vfmin_vv 000100 . ..... ..... 001 ..... 1010111 @r_vm | ||
23 | vfmin_vf 000100 . ..... ..... 101 ..... 1010111 @r_vm | ||
24 | vfmax_vv 000110 . ..... ..... 001 ..... 1010111 @r_vm | ||
25 | -- | ||
26 | 2.31.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-29-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/insn32.decode | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/insn32.decode | ||
15 | +++ b/target/riscv/insn32.decode | ||
16 | @@ -XXX,XX +XXX,XX @@ vmfgt_vf 011101 . ..... ..... 101 ..... 1010111 @r_vm | ||
17 | vmfge_vf 011111 . ..... ..... 101 ..... 1010111 @r_vm | ||
18 | vmford_vv 011010 . ..... ..... 001 ..... 1010111 @r_vm | ||
19 | vmford_vf 011010 . ..... ..... 101 ..... 1010111 @r_vm | ||
20 | -vfclass_v 100011 . ..... 10000 001 ..... 1010111 @r2_vm | ||
21 | +vfclass_v 010011 . ..... 10000 001 ..... 1010111 @r2_vm | ||
22 | vfmerge_vfm 010111 0 ..... ..... 101 ..... 1010111 @r_vm_0 | ||
23 | vfmv_v_f 010111 1 00000 ..... 101 ..... 1010111 @r2 | ||
24 | vfcvt_xu_f_v 100010 . ..... 00000 001 ..... 1010111 @r2_vm | ||
25 | -- | ||
26 | 2.31.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-30-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/helper.h | 2 +- | ||
10 | target/riscv/insn32.decode | 2 +- | ||
11 | target/riscv/vector_helper.c | 6 +++--- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 7 ++++--- | ||
13 | 4 files changed, 9 insertions(+), 8 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/helper.h | ||
18 | +++ b/target/riscv/helper.h | ||
19 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
20 | DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
21 | DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
22 | |||
23 | -DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32) | ||
24 | +DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32) | ||
25 | |||
26 | DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32) | ||
27 | |||
28 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/target/riscv/insn32.decode | ||
31 | +++ b/target/riscv/insn32.decode | ||
32 | @@ -XXX,XX +XXX,XX @@ vmor_mm 011010 - ..... ..... 010 ..... 1010111 @r | ||
33 | vmnor_mm 011110 - ..... ..... 010 ..... 1010111 @r | ||
34 | vmornot_mm 011100 - ..... ..... 010 ..... 1010111 @r | ||
35 | vmxnor_mm 011111 - ..... ..... 010 ..... 1010111 @r | ||
36 | -vmpopc_m 010100 . ..... ----- 010 ..... 1010111 @r2_vm | ||
37 | +vcpop_m 010000 . ..... 10000 010 ..... 1010111 @r2_vm | ||
38 | vmfirst_m 010101 . ..... ----- 010 ..... 1010111 @r2_vm | ||
39 | vmsbf_m 010110 . ..... 00001 010 ..... 1010111 @r2_vm | ||
40 | vmsif_m 010110 . ..... 00011 010 ..... 1010111 @r2_vm | ||
41 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/target/riscv/vector_helper.c | ||
44 | +++ b/target/riscv/vector_helper.c | ||
45 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR) | ||
46 | GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT) | ||
47 | GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR) | ||
48 | |||
49 | -/* Vector mask population count vmpopc */ | ||
50 | -target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env, | ||
51 | - uint32_t desc) | ||
52 | +/* Vector count population in mask vcpop */ | ||
53 | +target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env, | ||
54 | + uint32_t desc) | ||
55 | { | ||
56 | target_ulong cnt = 0; | ||
57 | uint32_t vm = vext_vm(desc); | ||
58 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
61 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
62 | @@ -XXX,XX +XXX,XX @@ GEN_MM_TRANS(vmnor_mm) | ||
63 | GEN_MM_TRANS(vmornot_mm) | ||
64 | GEN_MM_TRANS(vmxnor_mm) | ||
65 | |||
66 | -/* Vector mask population count vmpopc */ | ||
67 | -static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a) | ||
68 | +/* Vector count population in mask vcpop */ | ||
69 | +static bool trans_vcpop_m(DisasContext *s, arg_rmr *a) | ||
70 | { | ||
71 | if (require_rvv(s) && | ||
72 | vext_check_isa_ill(s)) { | ||
73 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a) | ||
74 | tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2)); | ||
75 | tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); | ||
76 | |||
77 | - gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc); | ||
78 | + gen_helper_vcpop_m(dst, mask, src2, cpu_env, desc); | ||
79 | gen_set_gpr(s, a->rd, dst); | ||
80 | |||
81 | tcg_temp_free_ptr(mask); | ||
82 | tcg_temp_free_ptr(src2); | ||
83 | + | ||
84 | return true; | ||
85 | } | ||
86 | return false; | ||
87 | -- | ||
88 | 2.31.1 | ||
89 | |||
90 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-31-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/helper.h | 2 +- | ||
10 | target/riscv/insn32.decode | 2 +- | ||
11 | target/riscv/vector_helper.c | 6 +++--- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
13 | 4 files changed, 7 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/helper.h | ||
18 | +++ b/target/riscv/helper.h | ||
19 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
20 | |||
21 | DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32) | ||
22 | |||
23 | -DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32) | ||
24 | +DEF_HELPER_4(vfirst_m, tl, ptr, ptr, env, i32) | ||
25 | |||
26 | DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32) | ||
27 | DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32) | ||
28 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/target/riscv/insn32.decode | ||
31 | +++ b/target/riscv/insn32.decode | ||
32 | @@ -XXX,XX +XXX,XX @@ vmnor_mm 011110 - ..... ..... 010 ..... 1010111 @r | ||
33 | vmornot_mm 011100 - ..... ..... 010 ..... 1010111 @r | ||
34 | vmxnor_mm 011111 - ..... ..... 010 ..... 1010111 @r | ||
35 | vcpop_m 010000 . ..... 10000 010 ..... 1010111 @r2_vm | ||
36 | -vmfirst_m 010101 . ..... ----- 010 ..... 1010111 @r2_vm | ||
37 | +vfirst_m 010000 . ..... 10001 010 ..... 1010111 @r2_vm | ||
38 | vmsbf_m 010110 . ..... 00001 010 ..... 1010111 @r2_vm | ||
39 | vmsif_m 010110 . ..... 00011 010 ..... 1010111 @r2_vm | ||
40 | vmsof_m 010110 . ..... 00010 010 ..... 1010111 @r2_vm | ||
41 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/target/riscv/vector_helper.c | ||
44 | +++ b/target/riscv/vector_helper.c | ||
45 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env, | ||
46 | return cnt; | ||
47 | } | ||
48 | |||
49 | -/* vmfirst find-first-set mask bit*/ | ||
50 | -target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env, | ||
51 | - uint32_t desc) | ||
52 | +/* vfirst find-first-set mask bit*/ | ||
53 | +target_ulong HELPER(vfirst_m)(void *v0, void *vs2, CPURISCVState *env, | ||
54 | + uint32_t desc) | ||
55 | { | ||
56 | uint32_t vm = vext_vm(desc); | ||
57 | uint32_t vl = env->vl; | ||
58 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
61 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
62 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a) | ||
63 | } | ||
64 | |||
65 | /* vmfirst find-first-set mask bit */ | ||
66 | -static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a) | ||
67 | +static bool trans_vfirst_m(DisasContext *s, arg_rmr *a) | ||
68 | { | ||
69 | if (require_rvv(s) && | ||
70 | vext_check_isa_ill(s)) { | ||
71 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a) | ||
72 | tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2)); | ||
73 | tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); | ||
74 | |||
75 | - gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc); | ||
76 | + gen_helper_vfirst_m(dst, mask, src2, cpu_env, desc); | ||
77 | gen_set_gpr(s, a->rd, dst); | ||
78 | |||
79 | tcg_temp_free_ptr(mask); | ||
80 | -- | ||
81 | 2.31.1 | ||
82 | |||
83 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-32-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/insn32.decode | 6 +++--- | ||
10 | target/riscv/vector_helper.c | 4 ---- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 5 ++++- | ||
12 | 3 files changed, 7 insertions(+), 8 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/insn32.decode | ||
17 | +++ b/target/riscv/insn32.decode | ||
18 | @@ -XXX,XX +XXX,XX @@ vmornot_mm 011100 - ..... ..... 010 ..... 1010111 @r | ||
19 | vmxnor_mm 011111 - ..... ..... 010 ..... 1010111 @r | ||
20 | vcpop_m 010000 . ..... 10000 010 ..... 1010111 @r2_vm | ||
21 | vfirst_m 010000 . ..... 10001 010 ..... 1010111 @r2_vm | ||
22 | -vmsbf_m 010110 . ..... 00001 010 ..... 1010111 @r2_vm | ||
23 | -vmsif_m 010110 . ..... 00011 010 ..... 1010111 @r2_vm | ||
24 | -vmsof_m 010110 . ..... 00010 010 ..... 1010111 @r2_vm | ||
25 | +vmsbf_m 010100 . ..... 00001 010 ..... 1010111 @r2_vm | ||
26 | +vmsif_m 010100 . ..... 00011 010 ..... 1010111 @r2_vm | ||
27 | +vmsof_m 010100 . ..... 00010 010 ..... 1010111 @r2_vm | ||
28 | viota_m 010110 . ..... 10000 010 ..... 1010111 @r2_vm | ||
29 | vid_v 010110 . 00000 10001 010 ..... 1010111 @r1_vm | ||
30 | vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
31 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/vector_helper.c | ||
34 | +++ b/target/riscv/vector_helper.c | ||
35 | @@ -XXX,XX +XXX,XX @@ enum set_mask_type { | ||
36 | static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
37 | uint32_t desc, enum set_mask_type type) | ||
38 | { | ||
39 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; | ||
40 | uint32_t vm = vext_vm(desc); | ||
41 | uint32_t vl = env->vl; | ||
42 | int i; | ||
43 | @@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | - for (; i < vlmax; i++) { | ||
48 | - vext_set_elem_mask(vd, i, 0); | ||
49 | - } | ||
50 | } | ||
51 | |||
52 | void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
53 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
56 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
57 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfirst_m(DisasContext *s, arg_rmr *a) | ||
58 | #define GEN_M_TRANS(NAME) \ | ||
59 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
60 | { \ | ||
61 | - if (vext_check_isa_ill(s)) { \ | ||
62 | + if (require_rvv(s) && \ | ||
63 | + vext_check_isa_ill(s) && \ | ||
64 | + require_vm(a->vm, a->rd) && \ | ||
65 | + (a->rd != a->rs2)) { \ | ||
66 | uint32_t data = 0; \ | ||
67 | gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \ | ||
68 | TCGLabel *over = gen_new_label(); \ | ||
69 | -- | ||
70 | 2.31.1 | ||
71 | |||
72 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-33-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/insn32.decode | 2 +- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 10 ++++++++-- | ||
11 | 2 files changed, 9 insertions(+), 3 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn32.decode | ||
16 | +++ b/target/riscv/insn32.decode | ||
17 | @@ -XXX,XX +XXX,XX @@ vfirst_m 010000 . ..... 10001 010 ..... 1010111 @r2_vm | ||
18 | vmsbf_m 010100 . ..... 00001 010 ..... 1010111 @r2_vm | ||
19 | vmsif_m 010100 . ..... 00011 010 ..... 1010111 @r2_vm | ||
20 | vmsof_m 010100 . ..... 00010 010 ..... 1010111 @r2_vm | ||
21 | -viota_m 010110 . ..... 10000 010 ..... 1010111 @r2_vm | ||
22 | +viota_m 010100 . ..... 10000 010 ..... 1010111 @r2_vm | ||
23 | vid_v 010110 . 00000 10001 010 ..... 1010111 @r1_vm | ||
24 | vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
25 | vmv_s_x 001101 1 00000 ..... 110 ..... 1010111 @r2 | ||
26 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
29 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
30 | @@ -XXX,XX +XXX,XX @@ GEN_M_TRANS(vmsbf_m) | ||
31 | GEN_M_TRANS(vmsif_m) | ||
32 | GEN_M_TRANS(vmsof_m) | ||
33 | |||
34 | -/* Vector Iota Instruction */ | ||
35 | +/* | ||
36 | + * Vector Iota Instruction | ||
37 | + * | ||
38 | + * 1. The destination register cannot overlap the source register. | ||
39 | + * 2. If masked, cannot overlap the mask register ('v0'). | ||
40 | + * 3. An illegal instruction exception is raised if vstart is non-zero. | ||
41 | + */ | ||
42 | static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
43 | { | ||
44 | if (require_rvv(s) && | ||
45 | vext_check_isa_ill(s) && | ||
46 | - require_noover(a->rd, s->lmul, a->rs2, 0) && | ||
47 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) && | ||
48 | require_vm(a->vm, a->rd) && | ||
49 | require_align(a->rd, s->lmul)) { | ||
50 | uint32_t data = 0; | ||
51 | -- | ||
52 | 2.31.1 | ||
53 | |||
54 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20211210075704.23951-34-frank.chang@sifive.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/insn32.decode | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/insn32.decode | ||
15 | +++ b/target/riscv/insn32.decode | ||
16 | @@ -XXX,XX +XXX,XX @@ vmsbf_m 010100 . ..... 00001 010 ..... 1010111 @r2_vm | ||
17 | vmsif_m 010100 . ..... 00011 010 ..... 1010111 @r2_vm | ||
18 | vmsof_m 010100 . ..... 00010 010 ..... 1010111 @r2_vm | ||
19 | viota_m 010100 . ..... 10000 010 ..... 1010111 @r2_vm | ||
20 | -vid_v 010110 . 00000 10001 010 ..... 1010111 @r1_vm | ||
21 | +vid_v 010100 . 00000 10001 010 ..... 1010111 @r1_vm | ||
22 | vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
23 | vmv_s_x 001101 1 00000 ..... 110 ..... 1010111 @r2 | ||
24 | vfmv_f_s 001100 1 ..... 00000 001 ..... 1010111 @r2rd | ||
25 | -- | ||
26 | 2.31.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | For some vector instructions (e.g. vmv.s.x), the element is loaded with | ||
4 | sign-extended. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-35-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 32 +++++++++++++++++-------- | ||
13 | 1 file changed, 22 insertions(+), 10 deletions(-) | ||
14 | |||
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 | ||
17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
19 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
20 | /* Integer Extract Instruction */ | ||
21 | |||
22 | static void load_element(TCGv_i64 dest, TCGv_ptr base, | ||
23 | - int ofs, int sew) | ||
24 | + int ofs, int sew, bool sign) | ||
25 | { | ||
26 | switch (sew) { | ||
27 | case MO_8: | ||
28 | - tcg_gen_ld8u_i64(dest, base, ofs); | ||
29 | + if (!sign) { | ||
30 | + tcg_gen_ld8u_i64(dest, base, ofs); | ||
31 | + } else { | ||
32 | + tcg_gen_ld8s_i64(dest, base, ofs); | ||
33 | + } | ||
34 | break; | ||
35 | case MO_16: | ||
36 | - tcg_gen_ld16u_i64(dest, base, ofs); | ||
37 | + if (!sign) { | ||
38 | + tcg_gen_ld16u_i64(dest, base, ofs); | ||
39 | + } else { | ||
40 | + tcg_gen_ld16s_i64(dest, base, ofs); | ||
41 | + } | ||
42 | break; | ||
43 | case MO_32: | ||
44 | - tcg_gen_ld32u_i64(dest, base, ofs); | ||
45 | + if (!sign) { | ||
46 | + tcg_gen_ld32u_i64(dest, base, ofs); | ||
47 | + } else { | ||
48 | + tcg_gen_ld32s_i64(dest, base, ofs); | ||
49 | + } | ||
50 | break; | ||
51 | case MO_64: | ||
52 | tcg_gen_ld_i64(dest, base, ofs); | ||
53 | @@ -XXX,XX +XXX,XX @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest, | ||
54 | |||
55 | /* Perform the load. */ | ||
56 | load_element(dest, base, | ||
57 | - vreg_ofs(s, vreg), s->sew); | ||
58 | + vreg_ofs(s, vreg), s->sew, false); | ||
59 | tcg_temp_free_ptr(base); | ||
60 | tcg_temp_free_i32(ofs); | ||
61 | |||
62 | @@ -XXX,XX +XXX,XX @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest, | ||
63 | } | ||
64 | |||
65 | static void vec_element_loadi(DisasContext *s, TCGv_i64 dest, | ||
66 | - int vreg, int idx) | ||
67 | + int vreg, int idx, bool sign) | ||
68 | { | ||
69 | - load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew); | ||
70 | + load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign); | ||
71 | } | ||
72 | |||
73 | static bool trans_vext_x_v(DisasContext *s, arg_r *a) | ||
74 | @@ -XXX,XX +XXX,XX @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a) | ||
75 | |||
76 | if (a->rs1 == 0) { | ||
77 | /* Special case vmv.x.s rd, vs2. */ | ||
78 | - vec_element_loadi(s, tmp, a->rs2, 0); | ||
79 | + vec_element_loadi(s, tmp, a->rs2, 0, false); | ||
80 | } else { | ||
81 | /* This instruction ignores LMUL and vector register groups */ | ||
82 | int vlmax = s->vlen >> (3 + s->sew); | ||
83 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) | ||
84 | (s->mstatus_fs != 0) && (s->sew != 0)) { | ||
85 | unsigned int len = 8 << s->sew; | ||
86 | |||
87 | - vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0); | ||
88 | + vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false); | ||
89 | if (len < 64) { | ||
90 | tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], | ||
91 | MAKE_64BIT_MASK(len, 64 - len)); | ||
92 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a) | ||
93 | TCGv_i64 dest = tcg_temp_new_i64(); | ||
94 | |||
95 | if (a->rs1 == 0) { | ||
96 | - vec_element_loadi(s, dest, a->rs2, 0); | ||
97 | + vec_element_loadi(s, dest, a->rs2, 0, false); | ||
98 | } else { | ||
99 | vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax); | ||
100 | } | ||
101 | -- | ||
102 | 2.31.1 | ||
103 | |||
104 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Add vrgatherei16.vv instruction. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-36-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/helper.h | 4 ++++ | ||
11 | target/riscv/insn32.decode | 1 + | ||
12 | target/riscv/vector_helper.c | 23 ++++++++++++--------- | ||
13 | target/riscv/insn_trans/trans_rvv.c.inc | 27 ++++++++++++++++++++++--- | ||
14 | 4 files changed, 43 insertions(+), 12 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/helper.h | ||
19 | +++ b/target/riscv/helper.h | ||
20 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
21 | DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
22 | DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | +DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | +DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
26 | +DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
27 | +DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
29 | DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
30 | DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn32.decode | ||
34 | +++ b/target/riscv/insn32.decode | ||
35 | @@ -XXX,XX +XXX,XX @@ vslidedown_vx 001111 . ..... ..... 100 ..... 1010111 @r_vm | ||
36 | vslidedown_vi 001111 . ..... ..... 011 ..... 1010111 @r_vm | ||
37 | vslide1down_vx 001111 . ..... ..... 110 ..... 1010111 @r_vm | ||
38 | vrgather_vv 001100 . ..... ..... 000 ..... 1010111 @r_vm | ||
39 | +vrgatherei16_vv 001110 . ..... ..... 000 ..... 1010111 @r_vm | ||
40 | vrgather_vx 001100 . ..... ..... 100 ..... 1010111 @r_vm | ||
41 | vrgather_vi 001100 . ..... ..... 011 ..... 1010111 @r_vm | ||
42 | vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r | ||
43 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/vector_helper.c | ||
46 | +++ b/target/riscv/vector_helper.c | ||
47 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4) | ||
48 | GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) | ||
49 | |||
50 | /* Vector Register Gather Instruction */ | ||
51 | -#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H) \ | ||
52 | +#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2) \ | ||
53 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
54 | CPURISCVState *env, uint32_t desc) \ | ||
55 | { \ | ||
56 | - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
57 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS1))); \ | ||
58 | uint32_t vm = vext_vm(desc); \ | ||
59 | uint32_t vl = env->vl; \ | ||
60 | uint64_t index; \ | ||
61 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
62 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
63 | continue; \ | ||
64 | } \ | ||
65 | - index = *((ETYPE *)vs1 + H(i)); \ | ||
66 | + index = *((TS1 *)vs1 + HS1(i)); \ | ||
67 | if (index >= vlmax) { \ | ||
68 | - *((ETYPE *)vd + H(i)) = 0; \ | ||
69 | + *((TS2 *)vd + HS2(i)) = 0; \ | ||
70 | } else { \ | ||
71 | - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ | ||
72 | + *((TS2 *)vd + HS2(i)) = *((TS2 *)vs2 + HS2(index)); \ | ||
73 | } \ | ||
74 | } \ | ||
75 | } | ||
76 | |||
77 | /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */ | ||
78 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, H1) | ||
79 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, H2) | ||
80 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, H4) | ||
81 | -GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8) | ||
82 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, uint8_t, H1, H1) | ||
83 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, uint16_t, H2, H2) | ||
84 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, uint32_t, H4, H4) | ||
85 | +GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, uint64_t, H8, H8) | ||
86 | + | ||
87 | +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_b, uint16_t, uint8_t, H2, H1) | ||
88 | +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_h, uint16_t, uint16_t, H2, H2) | ||
89 | +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_w, uint16_t, uint32_t, H2, H4) | ||
90 | +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_d, uint16_t, uint64_t, H2, H8) | ||
91 | |||
92 | #define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H) \ | ||
93 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
94 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
95 | index XXXXXXX..XXXXXXX 100644 | ||
96 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
97 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
98 | @@ -XXX,XX +XXX,XX @@ static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a) | ||
99 | require_vm(a->vm, a->rd); | ||
100 | } | ||
101 | |||
102 | +static bool vrgatherei16_vv_check(DisasContext *s, arg_rmrr *a) | ||
103 | +{ | ||
104 | + int8_t emul = MO_16 - s->sew + s->lmul; | ||
105 | + return require_rvv(s) && | ||
106 | + vext_check_isa_ill(s) && | ||
107 | + (emul >= -3 && emul <= 3) && | ||
108 | + require_align(a->rd, s->lmul) && | ||
109 | + require_align(a->rs1, emul) && | ||
110 | + require_align(a->rs2, s->lmul) && | ||
111 | + (a->rd != a->rs2 && a->rd != a->rs1) && | ||
112 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), | ||
113 | + a->rs1, 1 << MAX(emul, 0)) && | ||
114 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), | ||
115 | + a->rs2, 1 << MAX(s->lmul, 0)) && | ||
116 | + require_vm(a->vm, a->rd); | ||
117 | +} | ||
118 | + | ||
119 | GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check) | ||
120 | +GEN_OPIVV_TRANS(vrgatherei16_vv, vrgatherei16_vv_check) | ||
121 | |||
122 | static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a) | ||
123 | { | ||
124 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a) | ||
125 | } | ||
126 | |||
127 | if (a->vm && s->vl_eq_vlmax) { | ||
128 | - int vlmax = s->vlen; | ||
129 | + int scale = s->lmul - (s->sew + 3); | ||
130 | + int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale; | ||
131 | TCGv_i64 dest = tcg_temp_new_i64(); | ||
132 | |||
133 | if (a->rs1 == 0) { | ||
134 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) | ||
135 | } | ||
136 | |||
137 | if (a->vm && s->vl_eq_vlmax) { | ||
138 | - if (a->rs1 >= s->vlen) { | ||
139 | - tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), | ||
140 | + int scale = s->lmul - (s->sew + 3); | ||
141 | + int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale; | ||
142 | + if (a->rs1 >= vlmax) { | ||
143 | + tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd), | ||
144 | MAXSZ(s), MAXSZ(s), 0); | ||
145 | } else { | ||
146 | tcg_gen_gvec_dup_mem(s->sew, vreg_ofs(s, a->rd), | ||
147 | -- | ||
148 | 2.31.1 | ||
149 | |||
150 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Remove "vmv.s.x: dothing if rs1 == 0" constraint. | ||
4 | * Add vmv.x.s instruction. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-37-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/insn32.decode | 3 +- | ||
13 | target/riscv/insn_trans/trans_rvv.c.inc | 43 ++++++++++++++++++++----- | ||
14 | 2 files changed, 37 insertions(+), 9 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/insn32.decode | ||
19 | +++ b/target/riscv/insn32.decode | ||
20 | @@ -XXX,XX +XXX,XX @@ vmsif_m 010100 . ..... 00011 010 ..... 1010111 @r2_vm | ||
21 | vmsof_m 010100 . ..... 00010 010 ..... 1010111 @r2_vm | ||
22 | viota_m 010100 . ..... 10000 010 ..... 1010111 @r2_vm | ||
23 | vid_v 010100 . 00000 10001 010 ..... 1010111 @r1_vm | ||
24 | +vmv_x_s 010000 1 ..... 00000 010 ..... 1010111 @r2rd | ||
25 | +vmv_s_x 010000 1 00000 ..... 110 ..... 1010111 @r2 | ||
26 | vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
27 | -vmv_s_x 001101 1 00000 ..... 110 ..... 1010111 @r2 | ||
28 | vfmv_f_s 001100 1 ..... 00000 001 ..... 1010111 @r2rd | ||
29 | vfmv_s_f 001101 1 00000 ..... 101 ..... 1010111 @r2 | ||
30 | vslideup_vx 001110 . ..... ..... 100 ..... 1010111 @r_vm | ||
31 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
34 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
35 | @@ -XXX,XX +XXX,XX @@ static void vec_element_storei(DisasContext *s, int vreg, | ||
36 | store_element(val, cpu_env, endian_ofs(s, vreg, idx), s->sew); | ||
37 | } | ||
38 | |||
39 | +/* vmv.x.s rd, vs2 # x[rd] = vs2[0] */ | ||
40 | +static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a) | ||
41 | +{ | ||
42 | + if (require_rvv(s) && | ||
43 | + vext_check_isa_ill(s)) { | ||
44 | + TCGv_i64 t1; | ||
45 | + TCGv dest; | ||
46 | + | ||
47 | + t1 = tcg_temp_new_i64(); | ||
48 | + dest = tcg_temp_new(); | ||
49 | + /* | ||
50 | + * load vreg and sign-extend to 64 bits, | ||
51 | + * then truncate to XLEN bits before storing to gpr. | ||
52 | + */ | ||
53 | + vec_element_loadi(s, t1, a->rs2, 0, true); | ||
54 | + tcg_gen_trunc_i64_tl(dest, t1); | ||
55 | + gen_set_gpr(s, a->rd, dest); | ||
56 | + tcg_temp_free_i64(t1); | ||
57 | + tcg_temp_free(dest); | ||
58 | + | ||
59 | + return true; | ||
60 | + } | ||
61 | + return false; | ||
62 | +} | ||
63 | + | ||
64 | /* vmv.s.x vd, rs1 # vd[0] = rs1 */ | ||
65 | static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) | ||
66 | { | ||
67 | - if (vext_check_isa_ill(s)) { | ||
68 | + if (require_rvv(s) && | ||
69 | + vext_check_isa_ill(s)) { | ||
70 | /* This instruction ignores LMUL and vector register groups */ | ||
71 | - int maxsz = s->vlen >> 3; | ||
72 | TCGv_i64 t1; | ||
73 | + TCGv s1; | ||
74 | TCGLabel *over = gen_new_label(); | ||
75 | |||
76 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
77 | - tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), maxsz, maxsz, 0); | ||
78 | - if (a->rs1 == 0) { | ||
79 | - goto done; | ||
80 | - } | ||
81 | |||
82 | t1 = tcg_temp_new_i64(); | ||
83 | - tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]); | ||
84 | + | ||
85 | + /* | ||
86 | + * load gpr and sign-extend to 64 bits, | ||
87 | + * then truncate to SEW bits when storing to vreg. | ||
88 | + */ | ||
89 | + s1 = get_gpr(s, a->rs1, EXT_NONE); | ||
90 | + tcg_gen_ext_tl_i64(t1, s1); | ||
91 | vec_element_storei(s, a->rd, 0, t1); | ||
92 | tcg_temp_free_i64(t1); | ||
93 | mark_vs_dirty(s); | ||
94 | - done: | ||
95 | gen_set_label(over); | ||
96 | return true; | ||
97 | } | ||
98 | -- | ||
99 | 2.31.1 | ||
100 | |||
101 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | NaN-boxed the scalar floating-point register based on RVV 1.0's rules. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-38-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++++++++++++-- | ||
11 | 1 file changed, 14 insertions(+), 2 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
17 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
18 | require_rvf(s) && | ||
19 | vext_check_isa_ill(s) && | ||
20 | require_align(a->rd, s->lmul)) { | ||
21 | + TCGv_i64 t1; | ||
22 | + | ||
23 | if (s->vl_eq_vlmax) { | ||
24 | + t1 = tcg_temp_new_i64(); | ||
25 | + /* NaN-box f[rs1] */ | ||
26 | + do_nanbox(s, t1, cpu_fpr[a->rs1]); | ||
27 | + | ||
28 | tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd), | ||
29 | - MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]); | ||
30 | + MAXSZ(s), MAXSZ(s), t1); | ||
31 | mark_vs_dirty(s); | ||
32 | } else { | ||
33 | TCGv_ptr dest; | ||
34 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
35 | TCGLabel *over = gen_new_label(); | ||
36 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
37 | |||
38 | + t1 = tcg_temp_new_i64(); | ||
39 | + /* NaN-box f[rs1] */ | ||
40 | + do_nanbox(s, t1, cpu_fpr[a->rs1]); | ||
41 | + | ||
42 | dest = tcg_temp_new_ptr(); | ||
43 | desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data)); | ||
44 | tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd)); | ||
45 | - fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc); | ||
46 | + | ||
47 | + fns[s->sew - 1](dest, t1, cpu_env, desc); | ||
48 | |||
49 | tcg_temp_free_ptr(dest); | ||
50 | mark_vs_dirty(s); | ||
51 | gen_set_label(over); | ||
52 | } | ||
53 | + tcg_temp_free_i64(t1); | ||
54 | return true; | ||
55 | } | ||
56 | return false; | ||
57 | -- | ||
58 | 2.31.1 | ||
59 | |||
60 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | NaN-boxed the scalar floating-point register based on RVV 1.0's rules. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-39-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/internals.h | 5 ---- | ||
11 | target/riscv/insn32.decode | 4 +-- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 38 ++++++++++++------------- | ||
13 | 3 files changed, 21 insertions(+), 26 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/internals.h | ||
18 | +++ b/target/riscv/internals.h | ||
19 | @@ -XXX,XX +XXX,XX @@ target_ulong fclass_h(uint64_t frs1); | ||
20 | target_ulong fclass_s(uint64_t frs1); | ||
21 | target_ulong fclass_d(uint64_t frs1); | ||
22 | |||
23 | -#define SEW8 0 | ||
24 | -#define SEW16 1 | ||
25 | -#define SEW32 2 | ||
26 | -#define SEW64 3 | ||
27 | - | ||
28 | #ifndef CONFIG_USER_ONLY | ||
29 | extern const VMStateDescription vmstate_riscv_cpu; | ||
30 | #endif | ||
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn32.decode | ||
34 | +++ b/target/riscv/insn32.decode | ||
35 | @@ -XXX,XX +XXX,XX @@ vid_v 010100 . 00000 10001 010 ..... 1010111 @r1_vm | ||
36 | vmv_x_s 010000 1 ..... 00000 010 ..... 1010111 @r2rd | ||
37 | vmv_s_x 010000 1 00000 ..... 110 ..... 1010111 @r2 | ||
38 | vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
39 | -vfmv_f_s 001100 1 ..... 00000 001 ..... 1010111 @r2rd | ||
40 | -vfmv_s_f 001101 1 00000 ..... 101 ..... 1010111 @r2 | ||
41 | +vfmv_f_s 010000 1 ..... 00000 001 ..... 1010111 @r2rd | ||
42 | +vfmv_s_f 010000 1 00000 ..... 101 ..... 1010111 @r2 | ||
43 | vslideup_vx 001110 . ..... ..... 100 ..... 1010111 @r_vm | ||
44 | vslideup_vi 001110 . ..... ..... 011 ..... 1010111 @r_vm | ||
45 | vslide1up_vx 001110 . ..... ..... 110 ..... 1010111 @r_vm | ||
46 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
47 | index XXXXXXX..XXXXXXX 100644 | ||
48 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
49 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
50 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) | ||
51 | /* Floating-Point Scalar Move Instructions */ | ||
52 | static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) | ||
53 | { | ||
54 | - if (!s->vill && has_ext(s, RVF) && | ||
55 | - (s->mstatus_fs != 0) && (s->sew != 0)) { | ||
56 | - unsigned int len = 8 << s->sew; | ||
57 | + if (require_rvv(s) && | ||
58 | + require_rvf(s) && | ||
59 | + vext_check_isa_ill(s)) { | ||
60 | + unsigned int ofs = (8 << s->sew); | ||
61 | + unsigned int len = 64 - ofs; | ||
62 | + TCGv_i64 t_nan; | ||
63 | |||
64 | vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false); | ||
65 | - if (len < 64) { | ||
66 | - tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], | ||
67 | - MAKE_64BIT_MASK(len, 64 - len)); | ||
68 | + /* NaN-box f[rd] as necessary for SEW */ | ||
69 | + if (len) { | ||
70 | + t_nan = tcg_constant_i64(UINT64_MAX); | ||
71 | + tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], | ||
72 | + t_nan, ofs, len); | ||
73 | } | ||
74 | |||
75 | mark_fs_dirty(s); | ||
76 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) | ||
77 | /* vfmv.s.f vd, rs1 # vd[0] = rs1 (vs2=0) */ | ||
78 | static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
79 | { | ||
80 | - if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) { | ||
81 | - TCGv_i64 t1; | ||
82 | + if (require_rvv(s) && | ||
83 | + require_rvf(s) && | ||
84 | + vext_check_isa_ill(s)) { | ||
85 | /* The instructions ignore LMUL and vector register group. */ | ||
86 | - uint32_t vlmax = s->vlen >> 3; | ||
87 | + TCGv_i64 t1; | ||
88 | + TCGLabel *over = gen_new_label(); | ||
89 | |||
90 | /* if vl == 0, skip vector register write back */ | ||
91 | - TCGLabel *over = gen_new_label(); | ||
92 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
93 | |||
94 | - /* zeroed all elements */ | ||
95 | - tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), vlmax, vlmax, 0); | ||
96 | - | ||
97 | - /* NaN-box f[rs1] as necessary for SEW */ | ||
98 | + /* NaN-box f[rs1] */ | ||
99 | t1 = tcg_temp_new_i64(); | ||
100 | - if (s->sew == MO_64 && !has_ext(s, RVD)) { | ||
101 | - tcg_gen_ori_i64(t1, cpu_fpr[a->rs1], MAKE_64BIT_MASK(32, 32)); | ||
102 | - } else { | ||
103 | - tcg_gen_mov_i64(t1, cpu_fpr[a->rs1]); | ||
104 | - } | ||
105 | + do_nanbox(s, t1, cpu_fpr[a->rs1]); | ||
106 | + | ||
107 | vec_element_storei(s, a->rd, 0, t1); | ||
108 | tcg_temp_free_i64(t1); | ||
109 | mark_vs_dirty(s); | ||
110 | -- | ||
111 | 2.31.1 | ||
112 | |||
113 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Add the following instructions: | ||
4 | |||
5 | * vmv1r.v | ||
6 | * vmv2r.v | ||
7 | * vmv4r.v | ||
8 | * vmv8r.v | ||
9 | |||
10 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
11 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20211210075704.23951-40-frank.chang@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/insn32.decode | 4 ++++ | ||
16 | target/riscv/insn_trans/trans_rvv.c.inc | 25 +++++++++++++++++++++++++ | ||
17 | 2 files changed, 29 insertions(+) | ||
18 | |||
19 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/insn32.decode | ||
22 | +++ b/target/riscv/insn32.decode | ||
23 | @@ -XXX,XX +XXX,XX @@ vrgatherei16_vv 001110 . ..... ..... 000 ..... 1010111 @r_vm | ||
24 | vrgather_vx 001100 . ..... ..... 100 ..... 1010111 @r_vm | ||
25 | vrgather_vi 001100 . ..... ..... 011 ..... 1010111 @r_vm | ||
26 | vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r | ||
27 | +vmv1r_v 100111 1 ..... 00000 011 ..... 1010111 @r2rd | ||
28 | +vmv2r_v 100111 1 ..... 00001 011 ..... 1010111 @r2rd | ||
29 | +vmv4r_v 100111 1 ..... 00011 011 ..... 1010111 @r2rd | ||
30 | +vmv8r_v 100111 1 ..... 00111 011 ..... 1010111 @r2rd | ||
31 | |||
32 | vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm | ||
33 | vsetvl 1000000 ..... ..... 111 ..... 1010111 @r | ||
34 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
37 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
38 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
39 | } | ||
40 | return false; | ||
41 | } | ||
42 | + | ||
43 | +/* | ||
44 | + * Whole Vector Register Move Instructions ignore vtype and vl setting. | ||
45 | + * Thus, we don't need to check vill bit. (Section 16.6) | ||
46 | + */ | ||
47 | +#define GEN_VMV_WHOLE_TRANS(NAME, LEN) \ | ||
48 | +static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
49 | +{ \ | ||
50 | + if (require_rvv(s) && \ | ||
51 | + QEMU_IS_ALIGNED(a->rd, LEN) && \ | ||
52 | + QEMU_IS_ALIGNED(a->rs2, LEN)) { \ | ||
53 | + /* EEW = 8 */ \ | ||
54 | + tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd), \ | ||
55 | + vreg_ofs(s, a->rs2), \ | ||
56 | + s->vlen / 8 * LEN, s->vlen / 8 * LEN); \ | ||
57 | + mark_vs_dirty(s); \ | ||
58 | + return true; \ | ||
59 | + } \ | ||
60 | + return false; \ | ||
61 | +} | ||
62 | + | ||
63 | +GEN_VMV_WHOLE_TRANS(vmv1r_v, 1) | ||
64 | +GEN_VMV_WHOLE_TRANS(vmv2r_v, 2) | ||
65 | +GEN_VMV_WHOLE_TRANS(vmv4r_v, 4) | ||
66 | +GEN_VMV_WHOLE_TRANS(vmv8r_v, 8) | ||
67 | -- | ||
68 | 2.31.1 | ||
69 | |||
70 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Add the following instructions: | ||
4 | |||
5 | * vzext.vf2 | ||
6 | * vzext.vf4 | ||
7 | * vzext.vf8 | ||
8 | * vsext.vf2 | ||
9 | * vsext.vf4 | ||
10 | * vsext.vf8 | ||
11 | |||
12 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
13 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Message-Id: <20211210075704.23951-41-frank.chang@sifive.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | target/riscv/helper.h | 14 +++++ | ||
18 | target/riscv/insn32.decode | 8 +++ | ||
19 | target/riscv/vector_helper.c | 31 ++++++++++ | ||
20 | target/riscv/insn_trans/trans_rvv.c.inc | 80 +++++++++++++++++++++++++ | ||
21 | 4 files changed, 133 insertions(+) | ||
22 | |||
23 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/target/riscv/helper.h | ||
26 | +++ b/target/riscv/helper.h | ||
27 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
29 | DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
31 | + | ||
32 | +DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32) | ||
33 | +DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32) | ||
34 | +DEF_HELPER_5(vzext_vf2_d, void, ptr, ptr, ptr, env, i32) | ||
35 | +DEF_HELPER_5(vzext_vf4_w, void, ptr, ptr, ptr, env, i32) | ||
36 | +DEF_HELPER_5(vzext_vf4_d, void, ptr, ptr, ptr, env, i32) | ||
37 | +DEF_HELPER_5(vzext_vf8_d, void, ptr, ptr, ptr, env, i32) | ||
38 | + | ||
39 | +DEF_HELPER_5(vsext_vf2_h, void, ptr, ptr, ptr, env, i32) | ||
40 | +DEF_HELPER_5(vsext_vf2_w, void, ptr, ptr, ptr, env, i32) | ||
41 | +DEF_HELPER_5(vsext_vf2_d, void, ptr, ptr, ptr, env, i32) | ||
42 | +DEF_HELPER_5(vsext_vf4_w, void, ptr, ptr, ptr, env, i32) | ||
43 | +DEF_HELPER_5(vsext_vf4_d, void, ptr, ptr, ptr, env, i32) | ||
44 | +DEF_HELPER_5(vsext_vf8_d, void, ptr, ptr, ptr, env, i32) | ||
45 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/target/riscv/insn32.decode | ||
48 | +++ b/target/riscv/insn32.decode | ||
49 | @@ -XXX,XX +XXX,XX @@ vmv2r_v 100111 1 ..... 00001 011 ..... 1010111 @r2rd | ||
50 | vmv4r_v 100111 1 ..... 00011 011 ..... 1010111 @r2rd | ||
51 | vmv8r_v 100111 1 ..... 00111 011 ..... 1010111 @r2rd | ||
52 | |||
53 | +# Vector Integer Extension | ||
54 | +vzext_vf2 010010 . ..... 00110 010 ..... 1010111 @r2_vm | ||
55 | +vzext_vf4 010010 . ..... 00100 010 ..... 1010111 @r2_vm | ||
56 | +vzext_vf8 010010 . ..... 00010 010 ..... 1010111 @r2_vm | ||
57 | +vsext_vf2 010010 . ..... 00111 010 ..... 1010111 @r2_vm | ||
58 | +vsext_vf4 010010 . ..... 00101 010 ..... 1010111 @r2_vm | ||
59 | +vsext_vf8 010010 . ..... 00011 010 ..... 1010111 @r2_vm | ||
60 | + | ||
61 | vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm | ||
62 | vsetvl 1000000 ..... ..... 111 ..... 1010111 @r | ||
63 | |||
64 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/target/riscv/vector_helper.c | ||
67 | +++ b/target/riscv/vector_helper.c | ||
68 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_b, uint8_t, H1) | ||
69 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_h, uint16_t, H2) | ||
70 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4) | ||
71 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8) | ||
72 | + | ||
73 | +/* Vector Integer Extension */ | ||
74 | +#define GEN_VEXT_INT_EXT(NAME, ETYPE, DTYPE, HD, HS1) \ | ||
75 | +void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
76 | + CPURISCVState *env, uint32_t desc) \ | ||
77 | +{ \ | ||
78 | + uint32_t vl = env->vl; \ | ||
79 | + uint32_t vm = vext_vm(desc); \ | ||
80 | + uint32_t i; \ | ||
81 | + \ | ||
82 | + for (i = 0; i < vl; i++) { \ | ||
83 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
84 | + continue; \ | ||
85 | + } \ | ||
86 | + *((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i)); \ | ||
87 | + } \ | ||
88 | +} | ||
89 | + | ||
90 | +GEN_VEXT_INT_EXT(vzext_vf2_h, uint16_t, uint8_t, H2, H1) | ||
91 | +GEN_VEXT_INT_EXT(vzext_vf2_w, uint32_t, uint16_t, H4, H2) | ||
92 | +GEN_VEXT_INT_EXT(vzext_vf2_d, uint64_t, uint32_t, H8, H4) | ||
93 | +GEN_VEXT_INT_EXT(vzext_vf4_w, uint32_t, uint8_t, H4, H1) | ||
94 | +GEN_VEXT_INT_EXT(vzext_vf4_d, uint64_t, uint16_t, H8, H2) | ||
95 | +GEN_VEXT_INT_EXT(vzext_vf8_d, uint64_t, uint8_t, H8, H1) | ||
96 | + | ||
97 | +GEN_VEXT_INT_EXT(vsext_vf2_h, int16_t, int8_t, H2, H1) | ||
98 | +GEN_VEXT_INT_EXT(vsext_vf2_w, int32_t, int16_t, H4, H2) | ||
99 | +GEN_VEXT_INT_EXT(vsext_vf2_d, int64_t, int32_t, H8, H4) | ||
100 | +GEN_VEXT_INT_EXT(vsext_vf4_w, int32_t, int8_t, H4, H1) | ||
101 | +GEN_VEXT_INT_EXT(vsext_vf4_d, int64_t, int16_t, H8, H2) | ||
102 | +GEN_VEXT_INT_EXT(vsext_vf8_d, int64_t, int8_t, H8, H1) | ||
103 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
106 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
107 | @@ -XXX,XX +XXX,XX @@ GEN_VMV_WHOLE_TRANS(vmv1r_v, 1) | ||
108 | GEN_VMV_WHOLE_TRANS(vmv2r_v, 2) | ||
109 | GEN_VMV_WHOLE_TRANS(vmv4r_v, 4) | ||
110 | GEN_VMV_WHOLE_TRANS(vmv8r_v, 8) | ||
111 | + | ||
112 | +static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div) | ||
113 | +{ | ||
114 | + uint8_t from = (s->sew + 3) - div; | ||
115 | + bool ret = require_rvv(s) && | ||
116 | + (from >= 3 && from <= 8) && | ||
117 | + (a->rd != a->rs2) && | ||
118 | + require_align(a->rd, s->lmul) && | ||
119 | + require_align(a->rs2, s->lmul - div) && | ||
120 | + require_vm(a->vm, a->rd) && | ||
121 | + require_noover(a->rd, s->lmul, a->rs2, s->lmul - div); | ||
122 | + return ret; | ||
123 | +} | ||
124 | + | ||
125 | +static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq) | ||
126 | +{ | ||
127 | + uint32_t data = 0; | ||
128 | + gen_helper_gvec_3_ptr *fn; | ||
129 | + TCGLabel *over = gen_new_label(); | ||
130 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
131 | + | ||
132 | + static gen_helper_gvec_3_ptr * const fns[6][4] = { | ||
133 | + { | ||
134 | + NULL, gen_helper_vzext_vf2_h, | ||
135 | + gen_helper_vzext_vf2_w, gen_helper_vzext_vf2_d | ||
136 | + }, | ||
137 | + { | ||
138 | + NULL, NULL, | ||
139 | + gen_helper_vzext_vf4_w, gen_helper_vzext_vf4_d, | ||
140 | + }, | ||
141 | + { | ||
142 | + NULL, NULL, | ||
143 | + NULL, gen_helper_vzext_vf8_d | ||
144 | + }, | ||
145 | + { | ||
146 | + NULL, gen_helper_vsext_vf2_h, | ||
147 | + gen_helper_vsext_vf2_w, gen_helper_vsext_vf2_d | ||
148 | + }, | ||
149 | + { | ||
150 | + NULL, NULL, | ||
151 | + gen_helper_vsext_vf4_w, gen_helper_vsext_vf4_d, | ||
152 | + }, | ||
153 | + { | ||
154 | + NULL, NULL, | ||
155 | + NULL, gen_helper_vsext_vf8_d | ||
156 | + } | ||
157 | + }; | ||
158 | + | ||
159 | + fn = fns[seq][s->sew]; | ||
160 | + if (fn == NULL) { | ||
161 | + return false; | ||
162 | + } | ||
163 | + | ||
164 | + data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
165 | + | ||
166 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
167 | + vreg_ofs(s, a->rs2), cpu_env, | ||
168 | + s->vlen / 8, s->vlen / 8, data, fn); | ||
169 | + | ||
170 | + mark_vs_dirty(s); | ||
171 | + gen_set_label(over); | ||
172 | + return true; | ||
173 | +} | ||
174 | + | ||
175 | +/* Vector Integer Extension */ | ||
176 | +#define GEN_INT_EXT_TRANS(NAME, DIV, SEQ) \ | ||
177 | +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
178 | +{ \ | ||
179 | + if (int_ext_check(s, a, DIV)) { \ | ||
180 | + return int_ext_op(s, a, SEQ); \ | ||
181 | + } \ | ||
182 | + return false; \ | ||
183 | +} | ||
184 | + | ||
185 | +GEN_INT_EXT_TRANS(vzext_vf2, 1, 0) | ||
186 | +GEN_INT_EXT_TRANS(vzext_vf4, 2, 1) | ||
187 | +GEN_INT_EXT_TRANS(vzext_vf8, 3, 2) | ||
188 | +GEN_INT_EXT_TRANS(vsext_vf2, 1, 3) | ||
189 | +GEN_INT_EXT_TRANS(vsext_vf4, 2, 4) | ||
190 | +GEN_INT_EXT_TRANS(vsext_vf8, 3, 5) | ||
191 | -- | ||
192 | 2.31.1 | ||
193 | |||
194 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Add the following instructions: | ||
4 | |||
5 | * vaaddu.vv | ||
6 | * vaaddu.vx | ||
7 | * vasubu.vv | ||
8 | * vasubu.vx | ||
9 | |||
10 | Remove the following instructions: | ||
11 | |||
12 | * vadd.vi | ||
13 | |||
14 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
15 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
16 | Message-Id: <20211210075704.23951-42-frank.chang@sifive.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | --- | ||
19 | target/riscv/helper.h | 16 ++++++ | ||
20 | target/riscv/insn32.decode | 13 +++-- | ||
21 | target/riscv/vector_helper.c | 74 +++++++++++++++++++++++++ | ||
22 | target/riscv/insn_trans/trans_rvv.c.inc | 5 +- | ||
23 | 4 files changed, 102 insertions(+), 6 deletions(-) | ||
24 | |||
25 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/target/riscv/helper.h | ||
28 | +++ b/target/riscv/helper.h | ||
29 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vaadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | DEF_HELPER_6(vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
31 | DEF_HELPER_6(vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
32 | DEF_HELPER_6(vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
33 | +DEF_HELPER_6(vaaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
34 | +DEF_HELPER_6(vaaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
35 | +DEF_HELPER_6(vaaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
36 | +DEF_HELPER_6(vaaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
37 | DEF_HELPER_6(vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
38 | DEF_HELPER_6(vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
39 | DEF_HELPER_6(vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
40 | DEF_HELPER_6(vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
41 | +DEF_HELPER_6(vasubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
42 | +DEF_HELPER_6(vasubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
43 | +DEF_HELPER_6(vasubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
44 | +DEF_HELPER_6(vasubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
45 | DEF_HELPER_6(vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
46 | DEF_HELPER_6(vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
47 | DEF_HELPER_6(vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
48 | DEF_HELPER_6(vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
49 | +DEF_HELPER_6(vaaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
50 | +DEF_HELPER_6(vaaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
51 | +DEF_HELPER_6(vaaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
52 | +DEF_HELPER_6(vaaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
53 | DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
54 | DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
55 | DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
56 | DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
57 | +DEF_HELPER_6(vasubu_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
58 | +DEF_HELPER_6(vasubu_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
59 | +DEF_HELPER_6(vasubu_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
60 | +DEF_HELPER_6(vasubu_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
61 | |||
62 | DEF_HELPER_6(vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
63 | DEF_HELPER_6(vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
64 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/target/riscv/insn32.decode | ||
67 | +++ b/target/riscv/insn32.decode | ||
68 | @@ -XXX,XX +XXX,XX @@ vssubu_vv 100010 . ..... ..... 000 ..... 1010111 @r_vm | ||
69 | vssubu_vx 100010 . ..... ..... 100 ..... 1010111 @r_vm | ||
70 | vssub_vv 100011 . ..... ..... 000 ..... 1010111 @r_vm | ||
71 | vssub_vx 100011 . ..... ..... 100 ..... 1010111 @r_vm | ||
72 | -vaadd_vv 100100 . ..... ..... 000 ..... 1010111 @r_vm | ||
73 | -vaadd_vx 100100 . ..... ..... 100 ..... 1010111 @r_vm | ||
74 | -vaadd_vi 100100 . ..... ..... 011 ..... 1010111 @r_vm | ||
75 | -vasub_vv 100110 . ..... ..... 000 ..... 1010111 @r_vm | ||
76 | -vasub_vx 100110 . ..... ..... 100 ..... 1010111 @r_vm | ||
77 | +vaadd_vv 001001 . ..... ..... 010 ..... 1010111 @r_vm | ||
78 | +vaadd_vx 001001 . ..... ..... 110 ..... 1010111 @r_vm | ||
79 | +vaaddu_vv 001000 . ..... ..... 010 ..... 1010111 @r_vm | ||
80 | +vaaddu_vx 001000 . ..... ..... 110 ..... 1010111 @r_vm | ||
81 | +vasub_vv 001011 . ..... ..... 010 ..... 1010111 @r_vm | ||
82 | +vasub_vx 001011 . ..... ..... 110 ..... 1010111 @r_vm | ||
83 | +vasubu_vv 001010 . ..... ..... 010 ..... 1010111 @r_vm | ||
84 | +vasubu_vx 001010 . ..... ..... 110 ..... 1010111 @r_vm | ||
85 | vsmul_vv 100111 . ..... ..... 000 ..... 1010111 @r_vm | ||
86 | vsmul_vx 100111 . ..... ..... 100 ..... 1010111 @r_vm | ||
87 | vwsmaccu_vv 111100 . ..... ..... 000 ..... 1010111 @r_vm | ||
88 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/target/riscv/vector_helper.c | ||
91 | +++ b/target/riscv/vector_helper.c | ||
92 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VX_RM(vaadd_vx_h, 2, 2) | ||
93 | GEN_VEXT_VX_RM(vaadd_vx_w, 4, 4) | ||
94 | GEN_VEXT_VX_RM(vaadd_vx_d, 8, 8) | ||
95 | |||
96 | +static inline uint32_t aaddu32(CPURISCVState *env, int vxrm, | ||
97 | + uint32_t a, uint32_t b) | ||
98 | +{ | ||
99 | + uint64_t res = (uint64_t)a + b; | ||
100 | + uint8_t round = get_round(vxrm, res, 1); | ||
101 | + | ||
102 | + return (res >> 1) + round; | ||
103 | +} | ||
104 | + | ||
105 | +static inline uint64_t aaddu64(CPURISCVState *env, int vxrm, | ||
106 | + uint64_t a, uint64_t b) | ||
107 | +{ | ||
108 | + uint64_t res = a + b; | ||
109 | + uint8_t round = get_round(vxrm, res, 1); | ||
110 | + uint64_t over = (uint64_t)(res < a) << 63; | ||
111 | + | ||
112 | + return ((res >> 1) | over) + round; | ||
113 | +} | ||
114 | + | ||
115 | +RVVCALL(OPIVV2_RM, vaaddu_vv_b, OP_UUU_B, H1, H1, H1, aaddu32) | ||
116 | +RVVCALL(OPIVV2_RM, vaaddu_vv_h, OP_UUU_H, H2, H2, H2, aaddu32) | ||
117 | +RVVCALL(OPIVV2_RM, vaaddu_vv_w, OP_UUU_W, H4, H4, H4, aaddu32) | ||
118 | +RVVCALL(OPIVV2_RM, vaaddu_vv_d, OP_UUU_D, H8, H8, H8, aaddu64) | ||
119 | +GEN_VEXT_VV_RM(vaaddu_vv_b, 1, 1) | ||
120 | +GEN_VEXT_VV_RM(vaaddu_vv_h, 2, 2) | ||
121 | +GEN_VEXT_VV_RM(vaaddu_vv_w, 4, 4) | ||
122 | +GEN_VEXT_VV_RM(vaaddu_vv_d, 8, 8) | ||
123 | + | ||
124 | +RVVCALL(OPIVX2_RM, vaaddu_vx_b, OP_UUU_B, H1, H1, aaddu32) | ||
125 | +RVVCALL(OPIVX2_RM, vaaddu_vx_h, OP_UUU_H, H2, H2, aaddu32) | ||
126 | +RVVCALL(OPIVX2_RM, vaaddu_vx_w, OP_UUU_W, H4, H4, aaddu32) | ||
127 | +RVVCALL(OPIVX2_RM, vaaddu_vx_d, OP_UUU_D, H8, H8, aaddu64) | ||
128 | +GEN_VEXT_VX_RM(vaaddu_vx_b, 1, 1) | ||
129 | +GEN_VEXT_VX_RM(vaaddu_vx_h, 2, 2) | ||
130 | +GEN_VEXT_VX_RM(vaaddu_vx_w, 4, 4) | ||
131 | +GEN_VEXT_VX_RM(vaaddu_vx_d, 8, 8) | ||
132 | + | ||
133 | static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t b) | ||
134 | { | ||
135 | int64_t res = (int64_t)a - b; | ||
136 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VX_RM(vasub_vx_h, 2, 2) | ||
137 | GEN_VEXT_VX_RM(vasub_vx_w, 4, 4) | ||
138 | GEN_VEXT_VX_RM(vasub_vx_d, 8, 8) | ||
139 | |||
140 | +static inline uint32_t asubu32(CPURISCVState *env, int vxrm, | ||
141 | + uint32_t a, uint32_t b) | ||
142 | +{ | ||
143 | + int64_t res = (int64_t)a - b; | ||
144 | + uint8_t round = get_round(vxrm, res, 1); | ||
145 | + | ||
146 | + return (res >> 1) + round; | ||
147 | +} | ||
148 | + | ||
149 | +static inline uint64_t asubu64(CPURISCVState *env, int vxrm, | ||
150 | + uint64_t a, uint64_t b) | ||
151 | +{ | ||
152 | + uint64_t res = (uint64_t)a - b; | ||
153 | + uint8_t round = get_round(vxrm, res, 1); | ||
154 | + uint64_t over = (uint64_t)(res > a) << 63; | ||
155 | + | ||
156 | + return ((res >> 1) | over) + round; | ||
157 | +} | ||
158 | + | ||
159 | +RVVCALL(OPIVV2_RM, vasubu_vv_b, OP_UUU_B, H1, H1, H1, asubu32) | ||
160 | +RVVCALL(OPIVV2_RM, vasubu_vv_h, OP_UUU_H, H2, H2, H2, asubu32) | ||
161 | +RVVCALL(OPIVV2_RM, vasubu_vv_w, OP_UUU_W, H4, H4, H4, asubu32) | ||
162 | +RVVCALL(OPIVV2_RM, vasubu_vv_d, OP_UUU_D, H8, H8, H8, asubu64) | ||
163 | +GEN_VEXT_VV_RM(vasubu_vv_b, 1, 1) | ||
164 | +GEN_VEXT_VV_RM(vasubu_vv_h, 2, 2) | ||
165 | +GEN_VEXT_VV_RM(vasubu_vv_w, 4, 4) | ||
166 | +GEN_VEXT_VV_RM(vasubu_vv_d, 8, 8) | ||
167 | + | ||
168 | +RVVCALL(OPIVX2_RM, vasubu_vx_b, OP_UUU_B, H1, H1, asubu32) | ||
169 | +RVVCALL(OPIVX2_RM, vasubu_vx_h, OP_UUU_H, H2, H2, asubu32) | ||
170 | +RVVCALL(OPIVX2_RM, vasubu_vx_w, OP_UUU_W, H4, H4, asubu32) | ||
171 | +RVVCALL(OPIVX2_RM, vasubu_vx_d, OP_UUU_D, H8, H8, asubu64) | ||
172 | +GEN_VEXT_VX_RM(vasubu_vx_b, 1, 1) | ||
173 | +GEN_VEXT_VX_RM(vasubu_vx_h, 2, 2) | ||
174 | +GEN_VEXT_VX_RM(vasubu_vx_w, 4, 4) | ||
175 | +GEN_VEXT_VX_RM(vasubu_vx_d, 8, 8) | ||
176 | + | ||
177 | /* Vector Single-Width Fractional Multiply with Rounding and Saturation */ | ||
178 | static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b) | ||
179 | { | ||
180 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
181 | index XXXXXXX..XXXXXXX 100644 | ||
182 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
183 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
184 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check) | ||
185 | |||
186 | /* Vector Single-Width Averaging Add and Subtract */ | ||
187 | GEN_OPIVV_TRANS(vaadd_vv, opivv_check) | ||
188 | +GEN_OPIVV_TRANS(vaaddu_vv, opivv_check) | ||
189 | GEN_OPIVV_TRANS(vasub_vv, opivv_check) | ||
190 | +GEN_OPIVV_TRANS(vasubu_vv, opivv_check) | ||
191 | GEN_OPIVX_TRANS(vaadd_vx, opivx_check) | ||
192 | +GEN_OPIVX_TRANS(vaaddu_vx, opivx_check) | ||
193 | GEN_OPIVX_TRANS(vasub_vx, opivx_check) | ||
194 | -GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check) | ||
195 | +GEN_OPIVX_TRANS(vasubu_vx, opivx_check) | ||
196 | |||
197 | /* Vector Single-Width Fractional Multiply with Rounding and Saturation */ | ||
198 | GEN_OPIVV_TRANS(vsmul_vv, opivv_check) | ||
199 | -- | ||
200 | 2.31.1 | ||
201 | |||
202 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Truncate vsll.vi, vsrl.vi, vsra.vi's immediate values to lg2(SEW) bits. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Message-Id: <20211210075704.23951-43-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 6 +++--- | ||
11 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
17 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_GVEC_SHIFT_TRANS(vsll_vx, shls) | ||
18 | GEN_OPIVX_GVEC_SHIFT_TRANS(vsrl_vx, shrs) | ||
19 | GEN_OPIVX_GVEC_SHIFT_TRANS(vsra_vx, sars) | ||
20 | |||
21 | -GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_ZX, vsll_vx, shli) | ||
22 | -GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_ZX, vsrl_vx, shri) | ||
23 | -GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_ZX, vsra_vx, sari) | ||
24 | +GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_TRUNC_SEW, vsll_vx, shli) | ||
25 | +GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, shri) | ||
26 | +GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari) | ||
27 | |||
28 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
29 | static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
30 | -- | ||
31 | 2.31.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Only do carry-in or borrow-in if is masked (vm=0). | ||
4 | * Remove clear function from helper functions as the tail elements | ||
5 | are unchanged in RVV 1.0. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-44-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/insn32.decode | 20 ++++++++++---------- | ||
13 | target/riscv/vector_helper.c | 21 ++++++--------------- | ||
14 | target/riscv/insn_trans/trans_rvv.c.inc | 2 +- | ||
15 | 3 files changed, 17 insertions(+), 26 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/insn32.decode | ||
20 | +++ b/target/riscv/insn32.decode | ||
21 | @@ -XXX,XX +XXX,XX @@ vwsubu_wv 110110 . ..... ..... 010 ..... 1010111 @r_vm | ||
22 | vwsubu_wx 110110 . ..... ..... 110 ..... 1010111 @r_vm | ||
23 | vwsub_wv 110111 . ..... ..... 010 ..... 1010111 @r_vm | ||
24 | vwsub_wx 110111 . ..... ..... 110 ..... 1010111 @r_vm | ||
25 | -vadc_vvm 010000 1 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
26 | -vadc_vxm 010000 1 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
27 | -vadc_vim 010000 1 ..... ..... 011 ..... 1010111 @r_vm_1 | ||
28 | -vmadc_vvm 010001 1 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
29 | -vmadc_vxm 010001 1 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
30 | -vmadc_vim 010001 1 ..... ..... 011 ..... 1010111 @r_vm_1 | ||
31 | -vsbc_vvm 010010 1 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
32 | -vsbc_vxm 010010 1 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
33 | -vmsbc_vvm 010011 1 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
34 | -vmsbc_vxm 010011 1 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
35 | +vadc_vvm 010000 0 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
36 | +vadc_vxm 010000 0 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
37 | +vadc_vim 010000 0 ..... ..... 011 ..... 1010111 @r_vm_1 | ||
38 | +vmadc_vvm 010001 . ..... ..... 000 ..... 1010111 @r_vm | ||
39 | +vmadc_vxm 010001 . ..... ..... 100 ..... 1010111 @r_vm | ||
40 | +vmadc_vim 010001 . ..... ..... 011 ..... 1010111 @r_vm | ||
41 | +vsbc_vvm 010010 0 ..... ..... 000 ..... 1010111 @r_vm_1 | ||
42 | +vsbc_vxm 010010 0 ..... ..... 100 ..... 1010111 @r_vm_1 | ||
43 | +vmsbc_vvm 010011 . ..... ..... 000 ..... 1010111 @r_vm | ||
44 | +vmsbc_vxm 010011 . ..... ..... 100 ..... 1010111 @r_vm | ||
45 | vand_vv 001001 . ..... ..... 000 ..... 1010111 @r_vm | ||
46 | vand_vx 001001 . ..... ..... 100 ..... 1010111 @r_vm | ||
47 | vand_vi 001001 . ..... ..... 011 ..... 1010111 @r_vm | ||
48 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/riscv/vector_helper.c | ||
51 | +++ b/target/riscv/vector_helper.c | ||
52 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
53 | for (i = 0; i < vl; i++) { \ | ||
54 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
55 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
56 | - uint8_t carry = vext_elem_mask(v0, i); \ | ||
57 | + ETYPE carry = vext_elem_mask(v0, i); \ | ||
58 | \ | ||
59 | *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \ | ||
60 | } \ | ||
61 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
62 | \ | ||
63 | for (i = 0; i < vl; i++) { \ | ||
64 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
65 | - uint8_t carry = vext_elem_mask(v0, i); \ | ||
66 | + ETYPE carry = vext_elem_mask(v0, i); \ | ||
67 | \ | ||
68 | *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\ | ||
69 | } \ | ||
70 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
71 | CPURISCVState *env, uint32_t desc) \ | ||
72 | { \ | ||
73 | uint32_t vl = env->vl; \ | ||
74 | - uint32_t vlmax = vext_max_elems(desc, \ | ||
75 | - ctzl(sizeof(ETYPE))); \ | ||
76 | + uint32_t vm = vext_vm(desc); \ | ||
77 | uint32_t i; \ | ||
78 | \ | ||
79 | for (i = 0; i < vl; i++) { \ | ||
80 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
81 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
82 | - uint8_t carry = vext_elem_mask(v0, i); \ | ||
83 | - \ | ||
84 | + ETYPE carry = !vm && vext_elem_mask(v0, i); \ | ||
85 | vext_set_elem_mask(vd, i, DO_OP(s2, s1, carry)); \ | ||
86 | } \ | ||
87 | - for (; i < vlmax; i++) { \ | ||
88 | - vext_set_elem_mask(vd, i, 0); \ | ||
89 | - } \ | ||
90 | } | ||
91 | |||
92 | GEN_VEXT_VMADC_VVM(vmadc_vvm_b, uint8_t, H1, DO_MADC) | ||
93 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
94 | void *vs2, CPURISCVState *env, uint32_t desc) \ | ||
95 | { \ | ||
96 | uint32_t vl = env->vl; \ | ||
97 | - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
98 | + uint32_t vm = vext_vm(desc); \ | ||
99 | uint32_t i; \ | ||
100 | \ | ||
101 | for (i = 0; i < vl; i++) { \ | ||
102 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
103 | - uint8_t carry = vext_elem_mask(v0, i); \ | ||
104 | - \ | ||
105 | + ETYPE carry = !vm && vext_elem_mask(v0, i); \ | ||
106 | vext_set_elem_mask(vd, i, \ | ||
107 | DO_OP(s2, (ETYPE)(target_long)s1, carry)); \ | ||
108 | } \ | ||
109 | - for (; i < vlmax; i++) { \ | ||
110 | - vext_set_elem_mask(vd, i, 0); \ | ||
111 | - } \ | ||
112 | } | ||
113 | |||
114 | GEN_VEXT_VMADC_VXM(vmadc_vxm_b, uint8_t, H1, DO_MADC) | ||
115 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
116 | index XXXXXXX..XXXXXXX 100644 | ||
117 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
118 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
119 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
120 | |||
121 | /* | ||
122 | * For vadc and vsbc, an illegal instruction exception is raised if the | ||
123 | - * destination vector register is v0 and LMUL > 1. (Section 12.3) | ||
124 | + * destination vector register is v0 and LMUL > 1. (Section 12.4) | ||
125 | */ | ||
126 | static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a) | ||
127 | { | ||
128 | -- | ||
129 | 2.31.1 | ||
130 | |||
131 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-45-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 24 +++++++------- | ||
9 | target/riscv/insn32.decode | 12 +++---- | ||
10 | target/riscv/vector_helper.c | 24 +++++++------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 42 ++++++++++++------------- | ||
12 | 4 files changed, 51 insertions(+), 51 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
19 | DEF_HELPER_6(vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
20 | DEF_HELPER_6(vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
21 | |||
22 | -DEF_HELPER_6(vnsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | -DEF_HELPER_6(vnsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | -DEF_HELPER_6(vnsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | -DEF_HELPER_6(vnsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
26 | -DEF_HELPER_6(vnsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vnsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | -DEF_HELPER_6(vnsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
29 | -DEF_HELPER_6(vnsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
30 | -DEF_HELPER_6(vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
31 | -DEF_HELPER_6(vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
32 | -DEF_HELPER_6(vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
33 | -DEF_HELPER_6(vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
34 | +DEF_HELPER_6(vnsrl_wv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
35 | +DEF_HELPER_6(vnsrl_wv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
36 | +DEF_HELPER_6(vnsrl_wv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
37 | +DEF_HELPER_6(vnsra_wv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
38 | +DEF_HELPER_6(vnsra_wv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
39 | +DEF_HELPER_6(vnsra_wv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
40 | +DEF_HELPER_6(vnsrl_wx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
41 | +DEF_HELPER_6(vnsrl_wx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
42 | +DEF_HELPER_6(vnsrl_wx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
43 | +DEF_HELPER_6(vnsra_wx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
44 | +DEF_HELPER_6(vnsra_wx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
45 | +DEF_HELPER_6(vnsra_wx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
46 | |||
47 | DEF_HELPER_6(vmseq_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
48 | DEF_HELPER_6(vmseq_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
49 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/target/riscv/insn32.decode | ||
52 | +++ b/target/riscv/insn32.decode | ||
53 | @@ -XXX,XX +XXX,XX @@ vsrl_vi 101000 . ..... ..... 011 ..... 1010111 @r_vm | ||
54 | vsra_vv 101001 . ..... ..... 000 ..... 1010111 @r_vm | ||
55 | vsra_vx 101001 . ..... ..... 100 ..... 1010111 @r_vm | ||
56 | vsra_vi 101001 . ..... ..... 011 ..... 1010111 @r_vm | ||
57 | -vnsrl_vv 101100 . ..... ..... 000 ..... 1010111 @r_vm | ||
58 | -vnsrl_vx 101100 . ..... ..... 100 ..... 1010111 @r_vm | ||
59 | -vnsrl_vi 101100 . ..... ..... 011 ..... 1010111 @r_vm | ||
60 | -vnsra_vv 101101 . ..... ..... 000 ..... 1010111 @r_vm | ||
61 | -vnsra_vx 101101 . ..... ..... 100 ..... 1010111 @r_vm | ||
62 | -vnsra_vi 101101 . ..... ..... 011 ..... 1010111 @r_vm | ||
63 | +vnsrl_wv 101100 . ..... ..... 000 ..... 1010111 @r_vm | ||
64 | +vnsrl_wx 101100 . ..... ..... 100 ..... 1010111 @r_vm | ||
65 | +vnsrl_wi 101100 . ..... ..... 011 ..... 1010111 @r_vm | ||
66 | +vnsra_wv 101101 . ..... ..... 000 ..... 1010111 @r_vm | ||
67 | +vnsra_wx 101101 . ..... ..... 100 ..... 1010111 @r_vm | ||
68 | +vnsra_wi 101101 . ..... ..... 011 ..... 1010111 @r_vm | ||
69 | vmseq_vv 011000 . ..... ..... 000 ..... 1010111 @r_vm | ||
70 | vmseq_vx 011000 . ..... ..... 100 ..... 1010111 @r_vm | ||
71 | vmseq_vi 011000 . ..... ..... 011 ..... 1010111 @r_vm | ||
72 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/target/riscv/vector_helper.c | ||
75 | +++ b/target/riscv/vector_helper.c | ||
76 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_SHIFT_VX(vsra_vx_w, int32_t, int32_t, H4, H4, DO_SRL, 0x1f) | ||
77 | GEN_VEXT_SHIFT_VX(vsra_vx_d, int64_t, int64_t, H8, H8, DO_SRL, 0x3f) | ||
78 | |||
79 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
80 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
81 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
82 | -GEN_VEXT_SHIFT_VV(vnsrl_vv_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
83 | -GEN_VEXT_SHIFT_VV(vnsra_vv_b, uint8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
84 | -GEN_VEXT_SHIFT_VV(vnsra_vv_h, uint16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
85 | -GEN_VEXT_SHIFT_VV(vnsra_vv_w, uint32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
86 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
87 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
88 | -GEN_VEXT_SHIFT_VX(vnsrl_vx_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
89 | -GEN_VEXT_SHIFT_VX(vnsra_vx_b, int8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
90 | -GEN_VEXT_SHIFT_VX(vnsra_vx_h, int16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
91 | -GEN_VEXT_SHIFT_VX(vnsra_vx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
92 | +GEN_VEXT_SHIFT_VV(vnsrl_wv_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
93 | +GEN_VEXT_SHIFT_VV(vnsrl_wv_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
94 | +GEN_VEXT_SHIFT_VV(vnsrl_wv_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
95 | +GEN_VEXT_SHIFT_VV(vnsra_wv_b, uint8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
96 | +GEN_VEXT_SHIFT_VV(vnsra_wv_h, uint16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
97 | +GEN_VEXT_SHIFT_VV(vnsra_wv_w, uint32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
98 | +GEN_VEXT_SHIFT_VX(vnsrl_wx_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf) | ||
99 | +GEN_VEXT_SHIFT_VX(vnsrl_wx_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f) | ||
100 | +GEN_VEXT_SHIFT_VX(vnsrl_wx_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f) | ||
101 | +GEN_VEXT_SHIFT_VX(vnsra_wx_b, int8_t, int16_t, H1, H2, DO_SRL, 0xf) | ||
102 | +GEN_VEXT_SHIFT_VX(vnsra_wx_h, int16_t, int32_t, H2, H4, DO_SRL, 0x1f) | ||
103 | +GEN_VEXT_SHIFT_VX(vnsra_wx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f) | ||
104 | |||
105 | /* Vector Integer Comparison Instructions */ | ||
106 | #define DO_MSEQ(N, M) (N == M) | ||
107 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
108 | index XXXXXXX..XXXXXXX 100644 | ||
109 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
110 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
111 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, shri) | ||
112 | GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari) | ||
113 | |||
114 | /* Vector Narrowing Integer Right Shift Instructions */ | ||
115 | -static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
116 | +static bool opiwv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
117 | { | ||
118 | return require_rvv(s) && | ||
119 | vext_check_isa_ill(s) && | ||
120 | @@ -XXX,XX +XXX,XX @@ static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a) | ||
121 | } | ||
122 | |||
123 | /* OPIVV with NARROW */ | ||
124 | -#define GEN_OPIVV_NARROW_TRANS(NAME) \ | ||
125 | +#define GEN_OPIWV_NARROW_TRANS(NAME) \ | ||
126 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
127 | { \ | ||
128 | - if (opivv_narrow_check(s, a)) { \ | ||
129 | + if (opiwv_narrow_check(s, a)) { \ | ||
130 | uint32_t data = 0; \ | ||
131 | static gen_helper_gvec_4_ptr * const fns[3] = { \ | ||
132 | gen_helper_##NAME##_b, \ | ||
133 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
134 | } \ | ||
135 | return false; \ | ||
136 | } | ||
137 | -GEN_OPIVV_NARROW_TRANS(vnsra_vv) | ||
138 | -GEN_OPIVV_NARROW_TRANS(vnsrl_vv) | ||
139 | +GEN_OPIWV_NARROW_TRANS(vnsra_wv) | ||
140 | +GEN_OPIWV_NARROW_TRANS(vnsrl_wv) | ||
141 | |||
142 | -static bool opivx_narrow_check(DisasContext *s, arg_rmrr *a) | ||
143 | +static bool opiwx_narrow_check(DisasContext *s, arg_rmrr *a) | ||
144 | { | ||
145 | return require_rvv(s) && | ||
146 | vext_check_isa_ill(s) && | ||
147 | @@ -XXX,XX +XXX,XX @@ static bool opivx_narrow_check(DisasContext *s, arg_rmrr *a) | ||
148 | } | ||
149 | |||
150 | /* OPIVX with NARROW */ | ||
151 | -#define GEN_OPIVX_NARROW_TRANS(NAME) \ | ||
152 | +#define GEN_OPIWX_NARROW_TRANS(NAME) \ | ||
153 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
154 | { \ | ||
155 | - if (opivx_narrow_check(s, a)) { \ | ||
156 | + if (opiwx_narrow_check(s, a)) { \ | ||
157 | static gen_helper_opivx * const fns[3] = { \ | ||
158 | gen_helper_##NAME##_b, \ | ||
159 | gen_helper_##NAME##_h, \ | ||
160 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
161 | return false; \ | ||
162 | } | ||
163 | |||
164 | -GEN_OPIVX_NARROW_TRANS(vnsra_vx) | ||
165 | -GEN_OPIVX_NARROW_TRANS(vnsrl_vx) | ||
166 | +GEN_OPIWX_NARROW_TRANS(vnsra_wx) | ||
167 | +GEN_OPIWX_NARROW_TRANS(vnsrl_wx) | ||
168 | |||
169 | -/* OPIVI with NARROW */ | ||
170 | -#define GEN_OPIVI_NARROW_TRANS(NAME, IMM_MODE, OPIVX) \ | ||
171 | +/* OPIWI with NARROW */ | ||
172 | +#define GEN_OPIWI_NARROW_TRANS(NAME, IMM_MODE, OPIVX) \ | ||
173 | static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
174 | { \ | ||
175 | - if (opivx_narrow_check(s, a)) { \ | ||
176 | + if (opiwx_narrow_check(s, a)) { \ | ||
177 | static gen_helper_opivx * const fns[3] = { \ | ||
178 | gen_helper_##OPIVX##_b, \ | ||
179 | gen_helper_##OPIVX##_h, \ | ||
180 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
181 | return false; \ | ||
182 | } | ||
183 | |||
184 | -GEN_OPIVI_NARROW_TRANS(vnsra_vi, IMM_ZX, vnsra_vx) | ||
185 | -GEN_OPIVI_NARROW_TRANS(vnsrl_vi, IMM_ZX, vnsrl_vx) | ||
186 | +GEN_OPIWI_NARROW_TRANS(vnsra_wi, IMM_ZX, vnsra_wx) | ||
187 | +GEN_OPIWI_NARROW_TRANS(vnsrl_wi, IMM_ZX, vnsrl_wx) | ||
188 | |||
189 | /* Vector Integer Comparison Instructions */ | ||
190 | /* | ||
191 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check) | ||
192 | GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check) | ||
193 | |||
194 | /* Vector Narrowing Fixed-Point Clip Instructions */ | ||
195 | -GEN_OPIVV_NARROW_TRANS(vnclipu_vv) | ||
196 | -GEN_OPIVV_NARROW_TRANS(vnclip_vv) | ||
197 | -GEN_OPIVX_NARROW_TRANS(vnclipu_vx) | ||
198 | -GEN_OPIVX_NARROW_TRANS(vnclip_vx) | ||
199 | -GEN_OPIVI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx) | ||
200 | -GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) | ||
201 | +GEN_OPIWV_NARROW_TRANS(vnclipu_vv) | ||
202 | +GEN_OPIWV_NARROW_TRANS(vnclip_vv) | ||
203 | +GEN_OPIWX_NARROW_TRANS(vnclipu_vx) | ||
204 | +GEN_OPIWX_NARROW_TRANS(vnclip_vx) | ||
205 | +GEN_OPIWI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx) | ||
206 | +GEN_OPIWI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) | ||
207 | |||
208 | /* | ||
209 | *** Vector Float Point Arithmetic Instructions | ||
210 | -- | ||
211 | 2.31.1 | ||
212 | |||
213 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-46-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/insn32.decode | 6 +++--- | ||
9 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
10 | |||
11 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/insn32.decode | ||
14 | +++ b/target/riscv/insn32.decode | ||
15 | @@ -XXX,XX +XXX,XX @@ vwmaccu_vv 111100 . ..... ..... 010 ..... 1010111 @r_vm | ||
16 | vwmaccu_vx 111100 . ..... ..... 110 ..... 1010111 @r_vm | ||
17 | vwmacc_vv 111101 . ..... ..... 010 ..... 1010111 @r_vm | ||
18 | vwmacc_vx 111101 . ..... ..... 110 ..... 1010111 @r_vm | ||
19 | -vwmaccsu_vv 111110 . ..... ..... 010 ..... 1010111 @r_vm | ||
20 | -vwmaccsu_vx 111110 . ..... ..... 110 ..... 1010111 @r_vm | ||
21 | -vwmaccus_vx 111111 . ..... ..... 110 ..... 1010111 @r_vm | ||
22 | +vwmaccsu_vv 111111 . ..... ..... 010 ..... 1010111 @r_vm | ||
23 | +vwmaccsu_vx 111111 . ..... ..... 110 ..... 1010111 @r_vm | ||
24 | +vwmaccus_vx 111110 . ..... ..... 110 ..... 1010111 @r_vm | ||
25 | vmv_v_v 010111 1 00000 ..... 000 ..... 1010111 @r2 | ||
26 | vmv_v_x 010111 1 00000 ..... 100 ..... 1010111 @r2 | ||
27 | vmv_v_i 010111 1 00000 ..... 011 ..... 1010111 @r2 | ||
28 | -- | ||
29 | 2.31.1 | ||
30 | |||
31 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Sign-extend vsaddu.vi immediate value. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Message-Id: <20211210075704.23951-47-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 2 +- | ||
11 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
17 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vsaddu_vx, opivx_check) | ||
18 | GEN_OPIVX_TRANS(vsadd_vx, opivx_check) | ||
19 | GEN_OPIVX_TRANS(vssubu_vx, opivx_check) | ||
20 | GEN_OPIVX_TRANS(vssub_vx, opivx_check) | ||
21 | -GEN_OPIVI_TRANS(vsaddu_vi, IMM_ZX, vsaddu_vx, opivx_check) | ||
22 | +GEN_OPIVI_TRANS(vsaddu_vi, IMM_SX, vsaddu_vx, opivx_check) | ||
23 | GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check) | ||
24 | |||
25 | /* Vector Single-Width Averaging Add and Subtract */ | ||
26 | -- | ||
27 | 2.31.1 | ||
28 | |||
29 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Sign-extend vmselu.vi and vmsgtu.vi immediate values. | ||
4 | * Remove "set tail elements to zeros" as tail elements can be unchanged | ||
5 | for either VTA to have undisturbed or agnostic setting. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Message-Id: <20211210075704.23951-48-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/vector_helper.c | 9 --------- | ||
13 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
14 | 2 files changed, 2 insertions(+), 11 deletions(-) | ||
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 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
21 | { \ | ||
22 | uint32_t vm = vext_vm(desc); \ | ||
23 | uint32_t vl = env->vl; \ | ||
24 | - uint32_t vlmax = vext_max_elems(desc, \ | ||
25 | - ctzl(sizeof(ETYPE))); \ | ||
26 | uint32_t i; \ | ||
27 | \ | ||
28 | for (i = 0; i < vl; i++) { \ | ||
29 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
30 | } \ | ||
31 | vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \ | ||
32 | } \ | ||
33 | - for (; i < vlmax; i++) { \ | ||
34 | - vext_set_elem_mask(vd, i, 0); \ | ||
35 | - } \ | ||
36 | } | ||
37 | |||
38 | GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t, H1, DO_MSEQ) | ||
39 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
40 | { \ | ||
41 | uint32_t vm = vext_vm(desc); \ | ||
42 | uint32_t vl = env->vl; \ | ||
43 | - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
44 | uint32_t i; \ | ||
45 | \ | ||
46 | for (i = 0; i < vl; i++) { \ | ||
47 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
48 | vext_set_elem_mask(vd, i, \ | ||
49 | DO_OP(s2, (ETYPE)(target_long)s1)); \ | ||
50 | } \ | ||
51 | - for (; i < vlmax; i++) { \ | ||
52 | - vext_set_elem_mask(vd, i, 0); \ | ||
53 | - } \ | ||
54 | } | ||
55 | |||
56 | GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t, H1, DO_MSEQ) | ||
57 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
60 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
61 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vmsgt_vx, opivx_cmp_check) | ||
62 | |||
63 | GEN_OPIVI_TRANS(vmseq_vi, IMM_SX, vmseq_vx, opivx_cmp_check) | ||
64 | GEN_OPIVI_TRANS(vmsne_vi, IMM_SX, vmsne_vx, opivx_cmp_check) | ||
65 | -GEN_OPIVI_TRANS(vmsleu_vi, IMM_ZX, vmsleu_vx, opivx_cmp_check) | ||
66 | +GEN_OPIVI_TRANS(vmsleu_vi, IMM_SX, vmsleu_vx, opivx_cmp_check) | ||
67 | GEN_OPIVI_TRANS(vmsle_vi, IMM_SX, vmsle_vx, opivx_cmp_check) | ||
68 | -GEN_OPIVI_TRANS(vmsgtu_vi, IMM_ZX, vmsgtu_vx, opivx_cmp_check) | ||
69 | +GEN_OPIVI_TRANS(vmsgtu_vi, IMM_SX, vmsgtu_vx, opivx_cmp_check) | ||
70 | GEN_OPIVI_TRANS(vmsgt_vi, IMM_SX, vmsgt_vx, opivx_cmp_check) | ||
71 | |||
72 | /* Vector Integer Min/Max Instructions */ | ||
73 | -- | ||
74 | 2.31.1 | ||
75 | |||
76 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-49-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/vector_helper.c | 9 --------- | ||
9 | 1 file changed, 9 deletions(-) | ||
10 | |||
11 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/vector_helper.c | ||
14 | +++ b/target/riscv/vector_helper.c | ||
15 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
16 | { \ | ||
17 | uint32_t vm = vext_vm(desc); \ | ||
18 | uint32_t vl = env->vl; \ | ||
19 | - uint32_t vlmax = vext_max_elems(desc, \ | ||
20 | - ctzl(sizeof(ETYPE))); \ | ||
21 | uint32_t i; \ | ||
22 | \ | ||
23 | for (i = 0; i < vl; i++) { \ | ||
24 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
25 | vext_set_elem_mask(vd, i, \ | ||
26 | DO_OP(s2, s1, &env->fp_status)); \ | ||
27 | } \ | ||
28 | - for (; i < vlmax; i++) { \ | ||
29 | - vext_set_elem_mask(vd, i, 0); \ | ||
30 | - } \ | ||
31 | } | ||
32 | |||
33 | GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet) | ||
34 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
35 | { \ | ||
36 | uint32_t vm = vext_vm(desc); \ | ||
37 | uint32_t vl = env->vl; \ | ||
38 | - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
39 | uint32_t i; \ | ||
40 | \ | ||
41 | for (i = 0; i < vl; i++) { \ | ||
42 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
43 | vext_set_elem_mask(vd, i, \ | ||
44 | DO_OP(s2, (ETYPE)s1, &env->fp_status)); \ | ||
45 | } \ | ||
46 | - for (; i < vlmax; i++) { \ | ||
47 | - vext_set_elem_mask(vd, i, 0); \ | ||
48 | - } \ | ||
49 | } | ||
50 | |||
51 | GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet) | ||
52 | -- | ||
53 | 2.31.1 | ||
54 | |||
55 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-50-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/vector_helper.c | 4 ---- | ||
9 | target/riscv/insn_trans/trans_rvv.c.inc | 3 ++- | ||
10 | 2 files changed, 2 insertions(+), 5 deletions(-) | ||
11 | |||
12 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/vector_helper.c | ||
15 | +++ b/target/riscv/vector_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
17 | void *vs2, CPURISCVState *env, \ | ||
18 | uint32_t desc) \ | ||
19 | { \ | ||
20 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
21 | uint32_t vl = env->vl; \ | ||
22 | uint32_t i; \ | ||
23 | int a, b; \ | ||
24 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
25 | b = vext_elem_mask(vs2, i); \ | ||
26 | vext_set_elem_mask(vd, i, OP(b, a)); \ | ||
27 | } \ | ||
28 | - for (; i < vlmax; i++) { \ | ||
29 | - vext_set_elem_mask(vd, i, 0); \ | ||
30 | - } \ | ||
31 | } | ||
32 | |||
33 | #define DO_NAND(N, M) (!(N & M)) | ||
34 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
37 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
38 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check) | ||
39 | #define GEN_MM_TRANS(NAME) \ | ||
40 | static bool trans_##NAME(DisasContext *s, arg_r *a) \ | ||
41 | { \ | ||
42 | - if (vext_check_isa_ill(s)) { \ | ||
43 | + if (require_rvv(s) && \ | ||
44 | + vext_check_isa_ill(s)) { \ | ||
45 | uint32_t data = 0; \ | ||
46 | gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \ | ||
47 | TCGLabel *over = gen_new_label(); \ | ||
48 | -- | ||
49 | 2.31.1 | ||
50 | |||
51 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | * Remove clear function from helper functions as the tail elements | ||
4 | are unchanged in RVV 1.0. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
8 | Message-Id: <20211210075704.23951-51-frank.chang@sifive.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/vector_helper.c | 19 ++++++++++++------- | ||
12 | 1 file changed, 12 insertions(+), 7 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8) | ||
19 | void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
20 | CPURISCVState *env, uint32_t desc) \ | ||
21 | { \ | ||
22 | - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \ | ||
23 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ | ||
24 | uint32_t vm = vext_vm(desc); \ | ||
25 | uint32_t vl = env->vl; \ | ||
26 | - target_ulong offset = s1, i; \ | ||
27 | + target_ulong i_max, i; \ | ||
28 | \ | ||
29 | - for (i = 0; i < vl; ++i) { \ | ||
30 | - target_ulong j = i + offset; \ | ||
31 | - if (!vm && !vext_elem_mask(v0, i)) { \ | ||
32 | - continue; \ | ||
33 | + i_max = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \ | ||
34 | + for (i = 0; i < i_max; ++i) { \ | ||
35 | + if (vm || vext_elem_mask(v0, i)) { \ | ||
36 | + *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \ | ||
37 | + } \ | ||
38 | + } \ | ||
39 | + \ | ||
40 | + for (i = i_max; i < vl; ++i) { \ | ||
41 | + if (vm || vext_elem_mask(v0, i)) { \ | ||
42 | + *((ETYPE *)vd + H(i)) = 0; \ | ||
43 | } \ | ||
44 | - *((ETYPE *)vd + H(i)) = j >= vlmax ? 0 : *((ETYPE *)vs2 + H(j)); \ | ||
45 | } \ | ||
46 | } | ||
47 | |||
48 | -- | ||
49 | 2.31.1 | ||
50 | |||
51 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Add the following instructions: | ||
4 | |||
5 | * vfslide1up.vf | ||
6 | * vfslide1down.vf | ||
7 | |||
8 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-Id: <20211210075704.23951-52-frank.chang@sifive.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/helper.h | 7 ++ | ||
14 | target/riscv/insn32.decode | 2 + | ||
15 | target/riscv/vector_helper.c | 141 ++++++++++++++++-------- | ||
16 | target/riscv/insn_trans/trans_rvv.c.inc | 16 +++ | ||
17 | 4 files changed, 121 insertions(+), 45 deletions(-) | ||
18 | |||
19 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/helper.h | ||
22 | +++ b/target/riscv/helper.h | ||
23 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
24 | DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
25 | DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
26 | |||
27 | +DEF_HELPER_6(vfslide1up_vf_h, void, ptr, ptr, i64, ptr, env, i32) | ||
28 | +DEF_HELPER_6(vfslide1up_vf_w, void, ptr, ptr, i64, ptr, env, i32) | ||
29 | +DEF_HELPER_6(vfslide1up_vf_d, void, ptr, ptr, i64, ptr, env, i32) | ||
30 | +DEF_HELPER_6(vfslide1down_vf_h, void, ptr, ptr, i64, ptr, env, i32) | ||
31 | +DEF_HELPER_6(vfslide1down_vf_w, void, ptr, ptr, i64, ptr, env, i32) | ||
32 | +DEF_HELPER_6(vfslide1down_vf_d, void, ptr, ptr, i64, ptr, env, i32) | ||
33 | + | ||
34 | DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
35 | DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
36 | DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
37 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/target/riscv/insn32.decode | ||
40 | +++ b/target/riscv/insn32.decode | ||
41 | @@ -XXX,XX +XXX,XX @@ vfsgnjn_vv 001001 . ..... ..... 001 ..... 1010111 @r_vm | ||
42 | vfsgnjn_vf 001001 . ..... ..... 101 ..... 1010111 @r_vm | ||
43 | vfsgnjx_vv 001010 . ..... ..... 001 ..... 1010111 @r_vm | ||
44 | vfsgnjx_vf 001010 . ..... ..... 101 ..... 1010111 @r_vm | ||
45 | +vfslide1up_vf 001110 . ..... ..... 101 ..... 1010111 @r_vm | ||
46 | +vfslide1down_vf 001111 . ..... ..... 101 ..... 1010111 @r_vm | ||
47 | vmfeq_vv 011000 . ..... ..... 001 ..... 1010111 @r_vm | ||
48 | vmfeq_vf 011000 . ..... ..... 101 ..... 1010111 @r_vm | ||
49 | vmfne_vv 011100 . ..... ..... 001 ..... 1010111 @r_vm | ||
50 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/target/riscv/vector_helper.c | ||
53 | +++ b/target/riscv/vector_helper.c | ||
54 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2) | ||
55 | GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4) | ||
56 | GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8) | ||
57 | |||
58 | -#define GEN_VEXT_VSLIDE1UP_VX(NAME, ETYPE, H) \ | ||
59 | -void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
60 | - CPURISCVState *env, uint32_t desc) \ | ||
61 | -{ \ | ||
62 | - uint32_t vm = vext_vm(desc); \ | ||
63 | - uint32_t vl = env->vl; \ | ||
64 | - uint32_t i; \ | ||
65 | - \ | ||
66 | - for (i = 0; i < vl; i++) { \ | ||
67 | - if (!vm && !vext_elem_mask(v0, i)) { \ | ||
68 | - continue; \ | ||
69 | - } \ | ||
70 | - if (i == 0) { \ | ||
71 | - *((ETYPE *)vd + H(i)) = s1; \ | ||
72 | - } else { \ | ||
73 | - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1)); \ | ||
74 | - } \ | ||
75 | - } \ | ||
76 | +#define GEN_VEXT_VSLIE1UP(ESZ, H) \ | ||
77 | +static void vslide1up_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
78 | + CPURISCVState *env, uint32_t desc) \ | ||
79 | +{ \ | ||
80 | + typedef uint##ESZ##_t ETYPE; \ | ||
81 | + uint32_t vm = vext_vm(desc); \ | ||
82 | + uint32_t vl = env->vl; \ | ||
83 | + uint32_t i; \ | ||
84 | + \ | ||
85 | + for (i = 0; i < vl; i++) { \ | ||
86 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
87 | + continue; \ | ||
88 | + } \ | ||
89 | + if (i == 0) { \ | ||
90 | + *((ETYPE *)vd + H(i)) = s1; \ | ||
91 | + } else { \ | ||
92 | + *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1)); \ | ||
93 | + } \ | ||
94 | + } \ | ||
95 | +} | ||
96 | + | ||
97 | +GEN_VEXT_VSLIE1UP(8, H1) | ||
98 | +GEN_VEXT_VSLIE1UP(16, H2) | ||
99 | +GEN_VEXT_VSLIE1UP(32, H4) | ||
100 | +GEN_VEXT_VSLIE1UP(64, H8) | ||
101 | + | ||
102 | +#define GEN_VEXT_VSLIDE1UP_VX(NAME, ESZ) \ | ||
103 | +void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
104 | + CPURISCVState *env, uint32_t desc) \ | ||
105 | +{ \ | ||
106 | + vslide1up_##ESZ(vd, v0, s1, vs2, env, desc); \ | ||
107 | } | ||
108 | |||
109 | /* vslide1up.vx vd, vs2, rs1, vm # vd[0]=x[rs1], vd[i+1] = vs2[i] */ | ||
110 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_b, uint8_t, H1) | ||
111 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_h, uint16_t, H2) | ||
112 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, uint32_t, H4) | ||
113 | -GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, uint64_t, H8) | ||
114 | - | ||
115 | -#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, ETYPE, H) \ | ||
116 | -void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
117 | - CPURISCVState *env, uint32_t desc) \ | ||
118 | -{ \ | ||
119 | - uint32_t vm = vext_vm(desc); \ | ||
120 | - uint32_t vl = env->vl; \ | ||
121 | - uint32_t i; \ | ||
122 | - \ | ||
123 | - for (i = 0; i < vl; i++) { \ | ||
124 | - if (!vm && !vext_elem_mask(v0, i)) { \ | ||
125 | - continue; \ | ||
126 | - } \ | ||
127 | - if (i == vl - 1) { \ | ||
128 | - *((ETYPE *)vd + H(i)) = s1; \ | ||
129 | - } else { \ | ||
130 | - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1)); \ | ||
131 | - } \ | ||
132 | - } \ | ||
133 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_b, 8) | ||
134 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_h, 16) | ||
135 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, 32) | ||
136 | +GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, 64) | ||
137 | + | ||
138 | +#define GEN_VEXT_VSLIDE1DOWN(ESZ, H) \ | ||
139 | +static void vslide1down_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
140 | + CPURISCVState *env, uint32_t desc) \ | ||
141 | +{ \ | ||
142 | + typedef uint##ESZ##_t ETYPE; \ | ||
143 | + uint32_t vm = vext_vm(desc); \ | ||
144 | + uint32_t vl = env->vl; \ | ||
145 | + uint32_t i; \ | ||
146 | + \ | ||
147 | + for (i = 0; i < vl; i++) { \ | ||
148 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
149 | + continue; \ | ||
150 | + } \ | ||
151 | + if (i == vl - 1) { \ | ||
152 | + *((ETYPE *)vd + H(i)) = s1; \ | ||
153 | + } else { \ | ||
154 | + *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1)); \ | ||
155 | + } \ | ||
156 | + } \ | ||
157 | +} | ||
158 | + | ||
159 | +GEN_VEXT_VSLIDE1DOWN(8, H1) | ||
160 | +GEN_VEXT_VSLIDE1DOWN(16, H2) | ||
161 | +GEN_VEXT_VSLIDE1DOWN(32, H4) | ||
162 | +GEN_VEXT_VSLIDE1DOWN(64, H8) | ||
163 | + | ||
164 | +#define GEN_VEXT_VSLIDE1DOWN_VX(NAME, ESZ) \ | ||
165 | +void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
166 | + CPURISCVState *env, uint32_t desc) \ | ||
167 | +{ \ | ||
168 | + vslide1down_##ESZ(vd, v0, s1, vs2, env, desc); \ | ||
169 | } | ||
170 | |||
171 | /* vslide1down.vx vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=x[rs1] */ | ||
172 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_b, uint8_t, H1) | ||
173 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_h, uint16_t, H2) | ||
174 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4) | ||
175 | -GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) | ||
176 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_b, 8) | ||
177 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_h, 16) | ||
178 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, 32) | ||
179 | +GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, 64) | ||
180 | + | ||
181 | +/* Vector Floating-Point Slide Instructions */ | ||
182 | +#define GEN_VEXT_VFSLIDE1UP_VF(NAME, ESZ) \ | ||
183 | +void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
184 | + CPURISCVState *env, uint32_t desc) \ | ||
185 | +{ \ | ||
186 | + vslide1up_##ESZ(vd, v0, s1, vs2, env, desc); \ | ||
187 | +} | ||
188 | + | ||
189 | +/* vfslide1up.vf vd, vs2, rs1, vm # vd[0]=f[rs1], vd[i+1] = vs2[i] */ | ||
190 | +GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_h, 16) | ||
191 | +GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_w, 32) | ||
192 | +GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_d, 64) | ||
193 | + | ||
194 | +#define GEN_VEXT_VFSLIDE1DOWN_VF(NAME, ESZ) \ | ||
195 | +void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
196 | + CPURISCVState *env, uint32_t desc) \ | ||
197 | +{ \ | ||
198 | + vslide1down_##ESZ(vd, v0, s1, vs2, env, desc); \ | ||
199 | +} | ||
200 | + | ||
201 | +/* vfslide1down.vf vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=f[rs1] */ | ||
202 | +GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_h, 16) | ||
203 | +GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_w, 32) | ||
204 | +GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_d, 64) | ||
205 | |||
206 | /* Vector Register Gather Instruction */ | ||
207 | #define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2) \ | ||
208 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
209 | index XXXXXXX..XXXXXXX 100644 | ||
210 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
211 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
212 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check) | ||
213 | GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check) | ||
214 | GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check) | ||
215 | |||
216 | +/* Vector Floating-Point Slide Instructions */ | ||
217 | +static bool fslideup_check(DisasContext *s, arg_rmrr *a) | ||
218 | +{ | ||
219 | + return slideup_check(s, a) && | ||
220 | + require_rvf(s); | ||
221 | +} | ||
222 | + | ||
223 | +static bool fslidedown_check(DisasContext *s, arg_rmrr *a) | ||
224 | +{ | ||
225 | + return slidedown_check(s, a) && | ||
226 | + require_rvf(s); | ||
227 | +} | ||
228 | + | ||
229 | +GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check) | ||
230 | +GEN_OPFVF_TRANS(vfslide1down_vf, fslidedown_check) | ||
231 | + | ||
232 | /* Vector Register Gather Instruction */ | ||
233 | static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a) | ||
234 | { | ||
235 | -- | ||
236 | 2.31.1 | ||
237 | |||
238 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-53-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 24 ++++++------ | ||
9 | target/riscv/insn32.decode | 12 +++--- | ||
10 | target/riscv/vector_helper.c | 52 ++++++++++++------------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 12 +++--- | ||
12 | 4 files changed, 50 insertions(+), 50 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vssra_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
19 | DEF_HELPER_6(vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
20 | DEF_HELPER_6(vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
21 | |||
22 | -DEF_HELPER_6(vnclip_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | -DEF_HELPER_6(vnclip_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | -DEF_HELPER_6(vnclip_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | -DEF_HELPER_6(vnclipu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
26 | -DEF_HELPER_6(vnclipu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vnclipu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | -DEF_HELPER_6(vnclipu_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
29 | -DEF_HELPER_6(vnclipu_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
30 | -DEF_HELPER_6(vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
31 | -DEF_HELPER_6(vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
32 | -DEF_HELPER_6(vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
33 | -DEF_HELPER_6(vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
34 | +DEF_HELPER_6(vnclip_wv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
35 | +DEF_HELPER_6(vnclip_wv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
36 | +DEF_HELPER_6(vnclip_wv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
37 | +DEF_HELPER_6(vnclipu_wv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
38 | +DEF_HELPER_6(vnclipu_wv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
39 | +DEF_HELPER_6(vnclipu_wv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
40 | +DEF_HELPER_6(vnclipu_wx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
41 | +DEF_HELPER_6(vnclipu_wx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
42 | +DEF_HELPER_6(vnclipu_wx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
43 | +DEF_HELPER_6(vnclip_wx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
44 | +DEF_HELPER_6(vnclip_wx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
45 | +DEF_HELPER_6(vnclip_wx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
46 | |||
47 | DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
48 | DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
49 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/target/riscv/insn32.decode | ||
52 | +++ b/target/riscv/insn32.decode | ||
53 | @@ -XXX,XX +XXX,XX @@ vssrl_vi 101010 . ..... ..... 011 ..... 1010111 @r_vm | ||
54 | vssra_vv 101011 . ..... ..... 000 ..... 1010111 @r_vm | ||
55 | vssra_vx 101011 . ..... ..... 100 ..... 1010111 @r_vm | ||
56 | vssra_vi 101011 . ..... ..... 011 ..... 1010111 @r_vm | ||
57 | -vnclipu_vv 101110 . ..... ..... 000 ..... 1010111 @r_vm | ||
58 | -vnclipu_vx 101110 . ..... ..... 100 ..... 1010111 @r_vm | ||
59 | -vnclipu_vi 101110 . ..... ..... 011 ..... 1010111 @r_vm | ||
60 | -vnclip_vv 101111 . ..... ..... 000 ..... 1010111 @r_vm | ||
61 | -vnclip_vx 101111 . ..... ..... 100 ..... 1010111 @r_vm | ||
62 | -vnclip_vi 101111 . ..... ..... 011 ..... 1010111 @r_vm | ||
63 | +vnclipu_wv 101110 . ..... ..... 000 ..... 1010111 @r_vm | ||
64 | +vnclipu_wx 101110 . ..... ..... 100 ..... 1010111 @r_vm | ||
65 | +vnclipu_wi 101110 . ..... ..... 011 ..... 1010111 @r_vm | ||
66 | +vnclip_wv 101111 . ..... ..... 000 ..... 1010111 @r_vm | ||
67 | +vnclip_wx 101111 . ..... ..... 100 ..... 1010111 @r_vm | ||
68 | +vnclip_wi 101111 . ..... ..... 011 ..... 1010111 @r_vm | ||
69 | vfadd_vv 000000 . ..... ..... 001 ..... 1010111 @r_vm | ||
70 | vfadd_vf 000000 . ..... ..... 101 ..... 1010111 @r_vm | ||
71 | vfsub_vv 000010 . ..... ..... 001 ..... 1010111 @r_vm | ||
72 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/target/riscv/vector_helper.c | ||
75 | +++ b/target/riscv/vector_helper.c | ||
76 | @@ -XXX,XX +XXX,XX @@ vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b) | ||
77 | } | ||
78 | } | ||
79 | |||
80 | -RVVCALL(OPIVV2_RM, vnclip_vv_b, NOP_SSS_B, H1, H2, H1, vnclip8) | ||
81 | -RVVCALL(OPIVV2_RM, vnclip_vv_h, NOP_SSS_H, H2, H4, H2, vnclip16) | ||
82 | -RVVCALL(OPIVV2_RM, vnclip_vv_w, NOP_SSS_W, H4, H8, H4, vnclip32) | ||
83 | -GEN_VEXT_VV_RM(vnclip_vv_b, 1, 1) | ||
84 | -GEN_VEXT_VV_RM(vnclip_vv_h, 2, 2) | ||
85 | -GEN_VEXT_VV_RM(vnclip_vv_w, 4, 4) | ||
86 | - | ||
87 | -RVVCALL(OPIVX2_RM, vnclip_vx_b, NOP_SSS_B, H1, H2, vnclip8) | ||
88 | -RVVCALL(OPIVX2_RM, vnclip_vx_h, NOP_SSS_H, H2, H4, vnclip16) | ||
89 | -RVVCALL(OPIVX2_RM, vnclip_vx_w, NOP_SSS_W, H4, H8, vnclip32) | ||
90 | -GEN_VEXT_VX_RM(vnclip_vx_b, 1, 1) | ||
91 | -GEN_VEXT_VX_RM(vnclip_vx_h, 2, 2) | ||
92 | -GEN_VEXT_VX_RM(vnclip_vx_w, 4, 4) | ||
93 | +RVVCALL(OPIVV2_RM, vnclip_wv_b, NOP_SSS_B, H1, H2, H1, vnclip8) | ||
94 | +RVVCALL(OPIVV2_RM, vnclip_wv_h, NOP_SSS_H, H2, H4, H2, vnclip16) | ||
95 | +RVVCALL(OPIVV2_RM, vnclip_wv_w, NOP_SSS_W, H4, H8, H4, vnclip32) | ||
96 | +GEN_VEXT_VV_RM(vnclip_wv_b, 1, 1) | ||
97 | +GEN_VEXT_VV_RM(vnclip_wv_h, 2, 2) | ||
98 | +GEN_VEXT_VV_RM(vnclip_wv_w, 4, 4) | ||
99 | + | ||
100 | +RVVCALL(OPIVX2_RM, vnclip_wx_b, NOP_SSS_B, H1, H2, vnclip8) | ||
101 | +RVVCALL(OPIVX2_RM, vnclip_wx_h, NOP_SSS_H, H2, H4, vnclip16) | ||
102 | +RVVCALL(OPIVX2_RM, vnclip_wx_w, NOP_SSS_W, H4, H8, vnclip32) | ||
103 | +GEN_VEXT_VX_RM(vnclip_wx_b, 1, 1) | ||
104 | +GEN_VEXT_VX_RM(vnclip_wx_h, 2, 2) | ||
105 | +GEN_VEXT_VX_RM(vnclip_wx_w, 4, 4) | ||
106 | |||
107 | static inline uint8_t | ||
108 | vnclipu8(CPURISCVState *env, int vxrm, uint16_t a, uint8_t b) | ||
109 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t | ||
110 | vnclipu32(CPURISCVState *env, int vxrm, uint64_t a, uint32_t b) | ||
111 | { | ||
112 | uint8_t round, shift = b & 0x3f; | ||
113 | - int64_t res; | ||
114 | + uint64_t res; | ||
115 | |||
116 | round = get_round(vxrm, a, shift); | ||
117 | res = (a >> shift) + round; | ||
118 | @@ -XXX,XX +XXX,XX @@ vnclipu32(CPURISCVState *env, int vxrm, uint64_t a, uint32_t b) | ||
119 | } | ||
120 | } | ||
121 | |||
122 | -RVVCALL(OPIVV2_RM, vnclipu_vv_b, NOP_UUU_B, H1, H2, H1, vnclipu8) | ||
123 | -RVVCALL(OPIVV2_RM, vnclipu_vv_h, NOP_UUU_H, H2, H4, H2, vnclipu16) | ||
124 | -RVVCALL(OPIVV2_RM, vnclipu_vv_w, NOP_UUU_W, H4, H8, H4, vnclipu32) | ||
125 | -GEN_VEXT_VV_RM(vnclipu_vv_b, 1, 1) | ||
126 | -GEN_VEXT_VV_RM(vnclipu_vv_h, 2, 2) | ||
127 | -GEN_VEXT_VV_RM(vnclipu_vv_w, 4, 4) | ||
128 | +RVVCALL(OPIVV2_RM, vnclipu_wv_b, NOP_UUU_B, H1, H2, H1, vnclipu8) | ||
129 | +RVVCALL(OPIVV2_RM, vnclipu_wv_h, NOP_UUU_H, H2, H4, H2, vnclipu16) | ||
130 | +RVVCALL(OPIVV2_RM, vnclipu_wv_w, NOP_UUU_W, H4, H8, H4, vnclipu32) | ||
131 | +GEN_VEXT_VV_RM(vnclipu_wv_b, 1, 1) | ||
132 | +GEN_VEXT_VV_RM(vnclipu_wv_h, 2, 2) | ||
133 | +GEN_VEXT_VV_RM(vnclipu_wv_w, 4, 4) | ||
134 | |||
135 | -RVVCALL(OPIVX2_RM, vnclipu_vx_b, NOP_UUU_B, H1, H2, vnclipu8) | ||
136 | -RVVCALL(OPIVX2_RM, vnclipu_vx_h, NOP_UUU_H, H2, H4, vnclipu16) | ||
137 | -RVVCALL(OPIVX2_RM, vnclipu_vx_w, NOP_UUU_W, H4, H8, vnclipu32) | ||
138 | -GEN_VEXT_VX_RM(vnclipu_vx_b, 1, 1) | ||
139 | -GEN_VEXT_VX_RM(vnclipu_vx_h, 2, 2) | ||
140 | -GEN_VEXT_VX_RM(vnclipu_vx_w, 4, 4) | ||
141 | +RVVCALL(OPIVX2_RM, vnclipu_wx_b, NOP_UUU_B, H1, H2, vnclipu8) | ||
142 | +RVVCALL(OPIVX2_RM, vnclipu_wx_h, NOP_UUU_H, H2, H4, vnclipu16) | ||
143 | +RVVCALL(OPIVX2_RM, vnclipu_wx_w, NOP_UUU_W, H4, H8, vnclipu32) | ||
144 | +GEN_VEXT_VX_RM(vnclipu_wx_b, 1, 1) | ||
145 | +GEN_VEXT_VX_RM(vnclipu_wx_h, 2, 2) | ||
146 | +GEN_VEXT_VX_RM(vnclipu_wx_w, 4, 4) | ||
147 | |||
148 | /* | ||
149 | *** Vector Float Point Arithmetic Instructions | ||
150 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
151 | index XXXXXXX..XXXXXXX 100644 | ||
152 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
153 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
154 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check) | ||
155 | GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check) | ||
156 | |||
157 | /* Vector Narrowing Fixed-Point Clip Instructions */ | ||
158 | -GEN_OPIWV_NARROW_TRANS(vnclipu_vv) | ||
159 | -GEN_OPIWV_NARROW_TRANS(vnclip_vv) | ||
160 | -GEN_OPIWX_NARROW_TRANS(vnclipu_vx) | ||
161 | -GEN_OPIWX_NARROW_TRANS(vnclip_vx) | ||
162 | -GEN_OPIWI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx) | ||
163 | -GEN_OPIWI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) | ||
164 | +GEN_OPIWV_NARROW_TRANS(vnclipu_wv) | ||
165 | +GEN_OPIWV_NARROW_TRANS(vnclip_wv) | ||
166 | +GEN_OPIWX_NARROW_TRANS(vnclipu_wx) | ||
167 | +GEN_OPIWX_NARROW_TRANS(vnclip_wx) | ||
168 | +GEN_OPIWI_NARROW_TRANS(vnclipu_wi, IMM_ZX, vnclipu_wx) | ||
169 | +GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx) | ||
170 | |||
171 | /* | ||
172 | *** Vector Float Point Arithmetic Instructions | ||
173 | -- | ||
174 | 2.31.1 | ||
175 | |||
176 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-54-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/vector_helper.c | 12 ++++++------ | ||
9 | target/riscv/insn_trans/trans_rvv.c.inc | 12 +++++++++--- | ||
10 | 2 files changed, 15 insertions(+), 9 deletions(-) | ||
11 | |||
12 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/vector_helper.c | ||
15 | +++ b/target/riscv/vector_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, float32_add) | ||
17 | GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add) | ||
18 | |||
19 | /* Maximum value */ | ||
20 | -GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum) | ||
21 | -GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum) | ||
22 | -GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum) | ||
23 | +GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maximum_number) | ||
24 | +GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maximum_number) | ||
25 | +GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maximum_number) | ||
26 | |||
27 | /* Minimum value */ | ||
28 | -GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum) | ||
29 | -GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum) | ||
30 | -GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum) | ||
31 | +GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minimum_number) | ||
32 | +GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minimum_number) | ||
33 | +GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minimum_number) | ||
34 | |||
35 | /* Vector Widening Floating-Point Reduction Instructions */ | ||
36 | /* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */ | ||
37 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
40 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
41 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check) | ||
42 | GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check) | ||
43 | |||
44 | /* Vector Single-Width Floating-Point Reduction Instructions */ | ||
45 | -GEN_OPFVV_TRANS(vfredsum_vs, reduction_check) | ||
46 | -GEN_OPFVV_TRANS(vfredmax_vs, reduction_check) | ||
47 | -GEN_OPFVV_TRANS(vfredmin_vs, reduction_check) | ||
48 | +static bool freduction_check(DisasContext *s, arg_rmrr *a) | ||
49 | +{ | ||
50 | + return reduction_check(s, a) && | ||
51 | + require_rvf(s); | ||
52 | +} | ||
53 | + | ||
54 | +GEN_OPFVV_TRANS(vfredsum_vs, freduction_check) | ||
55 | +GEN_OPFVV_TRANS(vfredmax_vs, freduction_check) | ||
56 | +GEN_OPFVV_TRANS(vfredmin_vs, freduction_check) | ||
57 | |||
58 | /* Vector Widening Floating-Point Reduction Instructions */ | ||
59 | GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check) | ||
60 | -- | ||
61 | 2.31.1 | ||
62 | |||
63 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-55-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/insn_trans/trans_rvv.c.inc | 9 ++++++++- | ||
9 | 1 file changed, 8 insertions(+), 1 deletion(-) | ||
10 | |||
11 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
15 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmax_vs, freduction_check) | ||
16 | GEN_OPFVV_TRANS(vfredmin_vs, freduction_check) | ||
17 | |||
18 | /* Vector Widening Floating-Point Reduction Instructions */ | ||
19 | -GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check) | ||
20 | +static bool freduction_widen_check(DisasContext *s, arg_rmrr *a) | ||
21 | +{ | ||
22 | + return reduction_widen_check(s, a) && | ||
23 | + require_scale_rvf(s) && | ||
24 | + (s->sew != MO_8); | ||
25 | +} | ||
26 | + | ||
27 | +GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, freduction_widen_check) | ||
28 | |||
29 | /* | ||
30 | *** Vector Mask Operations | ||
31 | -- | ||
32 | 2.31.1 | ||
33 | |||
34 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | log(SEW) truncate vssra.vi immediate value. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Message-Id: <20211210075704.23951-56-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
11 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
17 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vssrl_vv, opivv_check) | ||
18 | GEN_OPIVV_TRANS(vssra_vv, opivv_check) | ||
19 | GEN_OPIVX_TRANS(vssrl_vx, opivx_check) | ||
20 | GEN_OPIVX_TRANS(vssra_vx, opivx_check) | ||
21 | -GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check) | ||
22 | -GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check) | ||
23 | +GEN_OPIVI_TRANS(vssrl_vi, IMM_TRUNC_SEW, vssrl_vx, opivx_check) | ||
24 | +GEN_OPIVI_TRANS(vssra_vi, IMM_TRUNC_SEW, vssra_vx, opivx_check) | ||
25 | |||
26 | /* Vector Narrowing Fixed-Point Clip Instructions */ | ||
27 | GEN_OPIWV_NARROW_TRANS(vnclipu_wv) | ||
28 | -- | ||
29 | 2.31.1 | ||
30 | |||
31 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-57-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 22 --- | ||
9 | target/riscv/insn32.decode | 7 - | ||
10 | target/riscv/vector_helper.c | 205 ------------------------ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 9 -- | ||
12 | 4 files changed, 243 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
19 | DEF_HELPER_6(vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
20 | DEF_HELPER_6(vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32) | ||
21 | |||
22 | -DEF_HELPER_6(vwsmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | -DEF_HELPER_6(vwsmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | -DEF_HELPER_6(vwsmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | -DEF_HELPER_6(vwsmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
26 | -DEF_HELPER_6(vwsmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vwsmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | -DEF_HELPER_6(vwsmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
29 | -DEF_HELPER_6(vwsmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | -DEF_HELPER_6(vwsmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
31 | -DEF_HELPER_6(vwsmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
32 | -DEF_HELPER_6(vwsmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
33 | -DEF_HELPER_6(vwsmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
34 | -DEF_HELPER_6(vwsmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
35 | -DEF_HELPER_6(vwsmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
36 | -DEF_HELPER_6(vwsmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
37 | -DEF_HELPER_6(vwsmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
38 | -DEF_HELPER_6(vwsmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
39 | -DEF_HELPER_6(vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
40 | -DEF_HELPER_6(vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32) | ||
41 | -DEF_HELPER_6(vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32) | ||
42 | -DEF_HELPER_6(vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32) | ||
43 | - | ||
44 | DEF_HELPER_6(vssrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
45 | DEF_HELPER_6(vssrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
46 | DEF_HELPER_6(vssrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
47 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/target/riscv/insn32.decode | ||
50 | +++ b/target/riscv/insn32.decode | ||
51 | @@ -XXX,XX +XXX,XX @@ vasubu_vv 001010 . ..... ..... 010 ..... 1010111 @r_vm | ||
52 | vasubu_vx 001010 . ..... ..... 110 ..... 1010111 @r_vm | ||
53 | vsmul_vv 100111 . ..... ..... 000 ..... 1010111 @r_vm | ||
54 | vsmul_vx 100111 . ..... ..... 100 ..... 1010111 @r_vm | ||
55 | -vwsmaccu_vv 111100 . ..... ..... 000 ..... 1010111 @r_vm | ||
56 | -vwsmaccu_vx 111100 . ..... ..... 100 ..... 1010111 @r_vm | ||
57 | -vwsmacc_vv 111101 . ..... ..... 000 ..... 1010111 @r_vm | ||
58 | -vwsmacc_vx 111101 . ..... ..... 100 ..... 1010111 @r_vm | ||
59 | -vwsmaccsu_vv 111110 . ..... ..... 000 ..... 1010111 @r_vm | ||
60 | -vwsmaccsu_vx 111110 . ..... ..... 100 ..... 1010111 @r_vm | ||
61 | -vwsmaccus_vx 111111 . ..... ..... 100 ..... 1010111 @r_vm | ||
62 | vssrl_vv 101010 . ..... ..... 000 ..... 1010111 @r_vm | ||
63 | vssrl_vx 101010 . ..... ..... 100 ..... 1010111 @r_vm | ||
64 | vssrl_vi 101010 . ..... ..... 011 ..... 1010111 @r_vm | ||
65 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/target/riscv/vector_helper.c | ||
68 | +++ b/target/riscv/vector_helper.c | ||
69 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VX_RM(vsmul_vx_h, 2, 2) | ||
70 | GEN_VEXT_VX_RM(vsmul_vx_w, 4, 4) | ||
71 | GEN_VEXT_VX_RM(vsmul_vx_d, 8, 8) | ||
72 | |||
73 | -/* Vector Widening Saturating Scaled Multiply-Add */ | ||
74 | -static inline uint16_t | ||
75 | -vwsmaccu8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b, | ||
76 | - uint16_t c) | ||
77 | -{ | ||
78 | - uint8_t round; | ||
79 | - uint16_t res = (uint16_t)a * b; | ||
80 | - | ||
81 | - round = get_round(vxrm, res, 4); | ||
82 | - res = (res >> 4) + round; | ||
83 | - return saddu16(env, vxrm, c, res); | ||
84 | -} | ||
85 | - | ||
86 | -static inline uint32_t | ||
87 | -vwsmaccu16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b, | ||
88 | - uint32_t c) | ||
89 | -{ | ||
90 | - uint8_t round; | ||
91 | - uint32_t res = (uint32_t)a * b; | ||
92 | - | ||
93 | - round = get_round(vxrm, res, 8); | ||
94 | - res = (res >> 8) + round; | ||
95 | - return saddu32(env, vxrm, c, res); | ||
96 | -} | ||
97 | - | ||
98 | -static inline uint64_t | ||
99 | -vwsmaccu32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b, | ||
100 | - uint64_t c) | ||
101 | -{ | ||
102 | - uint8_t round; | ||
103 | - uint64_t res = (uint64_t)a * b; | ||
104 | - | ||
105 | - round = get_round(vxrm, res, 16); | ||
106 | - res = (res >> 16) + round; | ||
107 | - return saddu64(env, vxrm, c, res); | ||
108 | -} | ||
109 | - | ||
110 | -#define OPIVV3_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ | ||
111 | -static inline void \ | ||
112 | -do_##NAME(void *vd, void *vs1, void *vs2, int i, \ | ||
113 | - CPURISCVState *env, int vxrm) \ | ||
114 | -{ \ | ||
115 | - TX1 s1 = *((T1 *)vs1 + HS1(i)); \ | ||
116 | - TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
117 | - TD d = *((TD *)vd + HD(i)); \ | ||
118 | - *((TD *)vd + HD(i)) = OP(env, vxrm, s2, s1, d); \ | ||
119 | -} | ||
120 | - | ||
121 | -RVVCALL(OPIVV3_RM, vwsmaccu_vv_b, WOP_UUU_B, H2, H1, H1, vwsmaccu8) | ||
122 | -RVVCALL(OPIVV3_RM, vwsmaccu_vv_h, WOP_UUU_H, H4, H2, H2, vwsmaccu16) | ||
123 | -RVVCALL(OPIVV3_RM, vwsmaccu_vv_w, WOP_UUU_W, H8, H4, H4, vwsmaccu32) | ||
124 | -GEN_VEXT_VV_RM(vwsmaccu_vv_b, 1, 2) | ||
125 | -GEN_VEXT_VV_RM(vwsmaccu_vv_h, 2, 4) | ||
126 | -GEN_VEXT_VV_RM(vwsmaccu_vv_w, 4, 8) | ||
127 | - | ||
128 | -#define OPIVX3_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ | ||
129 | -static inline void \ | ||
130 | -do_##NAME(void *vd, target_long s1, void *vs2, int i, \ | ||
131 | - CPURISCVState *env, int vxrm) \ | ||
132 | -{ \ | ||
133 | - TX2 s2 = *((T2 *)vs2 + HS2(i)); \ | ||
134 | - TD d = *((TD *)vd + HD(i)); \ | ||
135 | - *((TD *)vd + HD(i)) = OP(env, vxrm, s2, (TX1)(T1)s1, d); \ | ||
136 | -} | ||
137 | - | ||
138 | -RVVCALL(OPIVX3_RM, vwsmaccu_vx_b, WOP_UUU_B, H2, H1, vwsmaccu8) | ||
139 | -RVVCALL(OPIVX3_RM, vwsmaccu_vx_h, WOP_UUU_H, H4, H2, vwsmaccu16) | ||
140 | -RVVCALL(OPIVX3_RM, vwsmaccu_vx_w, WOP_UUU_W, H8, H4, vwsmaccu32) | ||
141 | -GEN_VEXT_VX_RM(vwsmaccu_vx_b, 1, 2) | ||
142 | -GEN_VEXT_VX_RM(vwsmaccu_vx_h, 2, 4) | ||
143 | -GEN_VEXT_VX_RM(vwsmaccu_vx_w, 4, 8) | ||
144 | - | ||
145 | -static inline int16_t | ||
146 | -vwsmacc8(CPURISCVState *env, int vxrm, int8_t a, int8_t b, int16_t c) | ||
147 | -{ | ||
148 | - uint8_t round; | ||
149 | - int16_t res = (int16_t)a * b; | ||
150 | - | ||
151 | - round = get_round(vxrm, res, 4); | ||
152 | - res = (res >> 4) + round; | ||
153 | - return sadd16(env, vxrm, c, res); | ||
154 | -} | ||
155 | - | ||
156 | -static inline int32_t | ||
157 | -vwsmacc16(CPURISCVState *env, int vxrm, int16_t a, int16_t b, int32_t c) | ||
158 | -{ | ||
159 | - uint8_t round; | ||
160 | - int32_t res = (int32_t)a * b; | ||
161 | - | ||
162 | - round = get_round(vxrm, res, 8); | ||
163 | - res = (res >> 8) + round; | ||
164 | - return sadd32(env, vxrm, c, res); | ||
165 | - | ||
166 | -} | ||
167 | - | ||
168 | -static inline int64_t | ||
169 | -vwsmacc32(CPURISCVState *env, int vxrm, int32_t a, int32_t b, int64_t c) | ||
170 | -{ | ||
171 | - uint8_t round; | ||
172 | - int64_t res = (int64_t)a * b; | ||
173 | - | ||
174 | - round = get_round(vxrm, res, 16); | ||
175 | - res = (res >> 16) + round; | ||
176 | - return sadd64(env, vxrm, c, res); | ||
177 | -} | ||
178 | - | ||
179 | -RVVCALL(OPIVV3_RM, vwsmacc_vv_b, WOP_SSS_B, H2, H1, H1, vwsmacc8) | ||
180 | -RVVCALL(OPIVV3_RM, vwsmacc_vv_h, WOP_SSS_H, H4, H2, H2, vwsmacc16) | ||
181 | -RVVCALL(OPIVV3_RM, vwsmacc_vv_w, WOP_SSS_W, H8, H4, H4, vwsmacc32) | ||
182 | -GEN_VEXT_VV_RM(vwsmacc_vv_b, 1, 2) | ||
183 | -GEN_VEXT_VV_RM(vwsmacc_vv_h, 2, 4) | ||
184 | -GEN_VEXT_VV_RM(vwsmacc_vv_w, 4, 8) | ||
185 | -RVVCALL(OPIVX3_RM, vwsmacc_vx_b, WOP_SSS_B, H2, H1, vwsmacc8) | ||
186 | -RVVCALL(OPIVX3_RM, vwsmacc_vx_h, WOP_SSS_H, H4, H2, vwsmacc16) | ||
187 | -RVVCALL(OPIVX3_RM, vwsmacc_vx_w, WOP_SSS_W, H8, H4, vwsmacc32) | ||
188 | -GEN_VEXT_VX_RM(vwsmacc_vx_b, 1, 2) | ||
189 | -GEN_VEXT_VX_RM(vwsmacc_vx_h, 2, 4) | ||
190 | -GEN_VEXT_VX_RM(vwsmacc_vx_w, 4, 8) | ||
191 | - | ||
192 | -static inline int16_t | ||
193 | -vwsmaccsu8(CPURISCVState *env, int vxrm, uint8_t a, int8_t b, int16_t c) | ||
194 | -{ | ||
195 | - uint8_t round; | ||
196 | - int16_t res = a * (int16_t)b; | ||
197 | - | ||
198 | - round = get_round(vxrm, res, 4); | ||
199 | - res = (res >> 4) + round; | ||
200 | - return ssub16(env, vxrm, c, res); | ||
201 | -} | ||
202 | - | ||
203 | -static inline int32_t | ||
204 | -vwsmaccsu16(CPURISCVState *env, int vxrm, uint16_t a, int16_t b, uint32_t c) | ||
205 | -{ | ||
206 | - uint8_t round; | ||
207 | - int32_t res = a * (int32_t)b; | ||
208 | - | ||
209 | - round = get_round(vxrm, res, 8); | ||
210 | - res = (res >> 8) + round; | ||
211 | - return ssub32(env, vxrm, c, res); | ||
212 | -} | ||
213 | - | ||
214 | -static inline int64_t | ||
215 | -vwsmaccsu32(CPURISCVState *env, int vxrm, uint32_t a, int32_t b, int64_t c) | ||
216 | -{ | ||
217 | - uint8_t round; | ||
218 | - int64_t res = a * (int64_t)b; | ||
219 | - | ||
220 | - round = get_round(vxrm, res, 16); | ||
221 | - res = (res >> 16) + round; | ||
222 | - return ssub64(env, vxrm, c, res); | ||
223 | -} | ||
224 | - | ||
225 | -RVVCALL(OPIVV3_RM, vwsmaccsu_vv_b, WOP_SSU_B, H2, H1, H1, vwsmaccsu8) | ||
226 | -RVVCALL(OPIVV3_RM, vwsmaccsu_vv_h, WOP_SSU_H, H4, H2, H2, vwsmaccsu16) | ||
227 | -RVVCALL(OPIVV3_RM, vwsmaccsu_vv_w, WOP_SSU_W, H8, H4, H4, vwsmaccsu32) | ||
228 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_b, 1, 2) | ||
229 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_h, 2, 4) | ||
230 | -GEN_VEXT_VV_RM(vwsmaccsu_vv_w, 4, 8) | ||
231 | -RVVCALL(OPIVX3_RM, vwsmaccsu_vx_b, WOP_SSU_B, H2, H1, vwsmaccsu8) | ||
232 | -RVVCALL(OPIVX3_RM, vwsmaccsu_vx_h, WOP_SSU_H, H4, H2, vwsmaccsu16) | ||
233 | -RVVCALL(OPIVX3_RM, vwsmaccsu_vx_w, WOP_SSU_W, H8, H4, vwsmaccsu32) | ||
234 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_b, 1, 2) | ||
235 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_h, 2, 4) | ||
236 | -GEN_VEXT_VX_RM(vwsmaccsu_vx_w, 4, 8) | ||
237 | - | ||
238 | -static inline int16_t | ||
239 | -vwsmaccus8(CPURISCVState *env, int vxrm, int8_t a, uint8_t b, int16_t c) | ||
240 | -{ | ||
241 | - uint8_t round; | ||
242 | - int16_t res = (int16_t)a * b; | ||
243 | - | ||
244 | - round = get_round(vxrm, res, 4); | ||
245 | - res = (res >> 4) + round; | ||
246 | - return ssub16(env, vxrm, c, res); | ||
247 | -} | ||
248 | - | ||
249 | -static inline int32_t | ||
250 | -vwsmaccus16(CPURISCVState *env, int vxrm, int16_t a, uint16_t b, int32_t c) | ||
251 | -{ | ||
252 | - uint8_t round; | ||
253 | - int32_t res = (int32_t)a * b; | ||
254 | - | ||
255 | - round = get_round(vxrm, res, 8); | ||
256 | - res = (res >> 8) + round; | ||
257 | - return ssub32(env, vxrm, c, res); | ||
258 | -} | ||
259 | - | ||
260 | -static inline int64_t | ||
261 | -vwsmaccus32(CPURISCVState *env, int vxrm, int32_t a, uint32_t b, int64_t c) | ||
262 | -{ | ||
263 | - uint8_t round; | ||
264 | - int64_t res = (int64_t)a * b; | ||
265 | - | ||
266 | - round = get_round(vxrm, res, 16); | ||
267 | - res = (res >> 16) + round; | ||
268 | - return ssub64(env, vxrm, c, res); | ||
269 | -} | ||
270 | - | ||
271 | -RVVCALL(OPIVX3_RM, vwsmaccus_vx_b, WOP_SUS_B, H2, H1, vwsmaccus8) | ||
272 | -RVVCALL(OPIVX3_RM, vwsmaccus_vx_h, WOP_SUS_H, H4, H2, vwsmaccus16) | ||
273 | -RVVCALL(OPIVX3_RM, vwsmaccus_vx_w, WOP_SUS_W, H8, H4, vwsmaccus32) | ||
274 | -GEN_VEXT_VX_RM(vwsmaccus_vx_b, 1, 2) | ||
275 | -GEN_VEXT_VX_RM(vwsmaccus_vx_h, 2, 4) | ||
276 | -GEN_VEXT_VX_RM(vwsmaccus_vx_w, 4, 8) | ||
277 | - | ||
278 | /* Vector Single-Width Scaling Shift Instructions */ | ||
279 | static inline uint8_t | ||
280 | vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b) | ||
281 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
282 | index XXXXXXX..XXXXXXX 100644 | ||
283 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
284 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
285 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vasubu_vx, opivx_check) | ||
286 | GEN_OPIVV_TRANS(vsmul_vv, opivv_check) | ||
287 | GEN_OPIVX_TRANS(vsmul_vx, opivx_check) | ||
288 | |||
289 | -/* Vector Widening Saturating Scaled Multiply-Add */ | ||
290 | -GEN_OPIVV_WIDEN_TRANS(vwsmaccu_vv, opivv_widen_check) | ||
291 | -GEN_OPIVV_WIDEN_TRANS(vwsmacc_vv, opivv_widen_check) | ||
292 | -GEN_OPIVV_WIDEN_TRANS(vwsmaccsu_vv, opivv_widen_check) | ||
293 | -GEN_OPIVX_WIDEN_TRANS(vwsmaccu_vx) | ||
294 | -GEN_OPIVX_WIDEN_TRANS(vwsmacc_vx) | ||
295 | -GEN_OPIVX_WIDEN_TRANS(vwsmaccsu_vx) | ||
296 | -GEN_OPIVX_WIDEN_TRANS(vwsmaccus_vx) | ||
297 | - | ||
298 | /* Vector Single-Width Scaling Shift Instructions */ | ||
299 | GEN_OPIVV_TRANS(vssrl_vv, opivv_check) | ||
300 | GEN_OPIVV_TRANS(vssra_vv, opivv_check) | ||
301 | -- | ||
302 | 2.31.1 | ||
303 | |||
304 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-58-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 6 ------ | ||
9 | target/riscv/insn32.decode | 2 -- | ||
10 | target/riscv/vector_helper.c | 7 ------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 2 -- | ||
12 | 4 files changed, 17 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, i32) | ||
19 | DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32) | ||
20 | DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32) | ||
21 | DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32) | ||
22 | -DEF_HELPER_6(vmford_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | -DEF_HELPER_6(vmford_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | -DEF_HELPER_6(vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | -DEF_HELPER_6(vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32) | ||
26 | -DEF_HELPER_6(vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32) | ||
28 | |||
29 | DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32) | ||
30 | DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32) | ||
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn32.decode | ||
34 | +++ b/target/riscv/insn32.decode | ||
35 | @@ -XXX,XX +XXX,XX @@ vmfle_vv 011001 . ..... ..... 001 ..... 1010111 @r_vm | ||
36 | vmfle_vf 011001 . ..... ..... 101 ..... 1010111 @r_vm | ||
37 | vmfgt_vf 011101 . ..... ..... 101 ..... 1010111 @r_vm | ||
38 | vmfge_vf 011111 . ..... ..... 101 ..... 1010111 @r_vm | ||
39 | -vmford_vv 011010 . ..... ..... 001 ..... 1010111 @r_vm | ||
40 | -vmford_vf 011010 . ..... ..... 101 ..... 1010111 @r_vm | ||
41 | vfclass_v 010011 . ..... 10000 001 ..... 1010111 @r2_vm | ||
42 | vfmerge_vfm 010111 0 ..... ..... 101 ..... 1010111 @r_vm_0 | ||
43 | vfmv_v_f 010111 1 00000 ..... 101 ..... 1010111 @r2 | ||
44 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/target/riscv/vector_helper.c | ||
47 | +++ b/target/riscv/vector_helper.c | ||
48 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16) | ||
49 | GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32) | ||
50 | GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64) | ||
51 | |||
52 | -GEN_VEXT_CMP_VV_ENV(vmford_vv_h, uint16_t, H2, !float16_unordered_quiet) | ||
53 | -GEN_VEXT_CMP_VV_ENV(vmford_vv_w, uint32_t, H4, !float32_unordered_quiet) | ||
54 | -GEN_VEXT_CMP_VV_ENV(vmford_vv_d, uint64_t, H8, !float64_unordered_quiet) | ||
55 | -GEN_VEXT_CMP_VF(vmford_vf_h, uint16_t, H2, !float16_unordered_quiet) | ||
56 | -GEN_VEXT_CMP_VF(vmford_vf_w, uint32_t, H4, !float32_unordered_quiet) | ||
57 | -GEN_VEXT_CMP_VF(vmford_vf_d, uint64_t, H8, !float64_unordered_quiet) | ||
58 | - | ||
59 | /* Vector Floating-Point Classify Instruction */ | ||
60 | #define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \ | ||
61 | static void do_##NAME(void *vd, void *vs2, int i) \ | ||
62 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
63 | index XXXXXXX..XXXXXXX 100644 | ||
64 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
65 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
66 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check) | ||
67 | GEN_OPFVV_TRANS(vmfne_vv, opfvv_cmp_check) | ||
68 | GEN_OPFVV_TRANS(vmflt_vv, opfvv_cmp_check) | ||
69 | GEN_OPFVV_TRANS(vmfle_vv, opfvv_cmp_check) | ||
70 | -GEN_OPFVV_TRANS(vmford_vv, opfvv_cmp_check) | ||
71 | |||
72 | static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a) | ||
73 | { | ||
74 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vmflt_vf, opfvf_cmp_check) | ||
75 | GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check) | ||
76 | GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check) | ||
77 | GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check) | ||
78 | -GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check) | ||
79 | |||
80 | /* Vector Floating-Point Classify Instruction */ | ||
81 | GEN_OPFV_TRANS(vfclass_v, opfv_check) | ||
82 | -- | ||
83 | 2.31.1 | ||
84 | |||
85 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-59-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/insn32.decode | 1 - | ||
9 | target/riscv/insn_trans/trans_rvv.c.inc | 23 ----------------------- | ||
10 | 2 files changed, 24 deletions(-) | ||
11 | |||
12 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/insn32.decode | ||
15 | +++ b/target/riscv/insn32.decode | ||
16 | @@ -XXX,XX +XXX,XX @@ viota_m 010100 . ..... 10000 010 ..... 1010111 @r2_vm | ||
17 | vid_v 010100 . 00000 10001 010 ..... 1010111 @r1_vm | ||
18 | vmv_x_s 010000 1 ..... 00000 010 ..... 1010111 @r2rd | ||
19 | vmv_s_x 010000 1 00000 ..... 110 ..... 1010111 @r2 | ||
20 | -vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r | ||
21 | vfmv_f_s 010000 1 ..... 00000 001 ..... 1010111 @r2rd | ||
22 | vfmv_s_f 010000 1 00000 ..... 101 ..... 1010111 @r2 | ||
23 | vslideup_vx 001110 . ..... ..... 100 ..... 1010111 @r_vm | ||
24 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
27 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
28 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
29 | *** Vector Permutation Instructions | ||
30 | */ | ||
31 | |||
32 | -/* Integer Extract Instruction */ | ||
33 | - | ||
34 | static void load_element(TCGv_i64 dest, TCGv_ptr base, | ||
35 | int ofs, int sew, bool sign) | ||
36 | { | ||
37 | @@ -XXX,XX +XXX,XX @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest, | ||
38 | load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign); | ||
39 | } | ||
40 | |||
41 | -static bool trans_vext_x_v(DisasContext *s, arg_r *a) | ||
42 | -{ | ||
43 | - TCGv_i64 tmp = tcg_temp_new_i64(); | ||
44 | - TCGv dest = dest_gpr(s, a->rd); | ||
45 | - | ||
46 | - if (a->rs1 == 0) { | ||
47 | - /* Special case vmv.x.s rd, vs2. */ | ||
48 | - vec_element_loadi(s, tmp, a->rs2, 0, false); | ||
49 | - } else { | ||
50 | - /* This instruction ignores LMUL and vector register groups */ | ||
51 | - int vlmax = s->vlen >> (3 + s->sew); | ||
52 | - vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax); | ||
53 | - } | ||
54 | - | ||
55 | - tcg_gen_trunc_i64_tl(dest, tmp); | ||
56 | - gen_set_gpr(s, a->rd, dest); | ||
57 | - | ||
58 | - tcg_temp_free_i64(tmp); | ||
59 | - return true; | ||
60 | -} | ||
61 | - | ||
62 | /* Integer Scalar Move Instruction */ | ||
63 | |||
64 | static void store_element(TCGv_i64 val, TCGv_ptr base, | ||
65 | -- | ||
66 | 2.31.1 | ||
67 | |||
68 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-60-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/vector_helper.c | 24 ++++++++++++------------ | ||
9 | 1 file changed, 12 insertions(+), 12 deletions(-) | ||
10 | |||
11 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/riscv/vector_helper.c | ||
14 | +++ b/target/riscv/vector_helper.c | ||
15 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4) | ||
16 | GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8) | ||
17 | |||
18 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
19 | -RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum) | ||
20 | -RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum) | ||
21 | -RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum) | ||
22 | +RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number) | ||
23 | +RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number) | ||
24 | +RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minimum_number) | ||
25 | GEN_VEXT_VV_ENV(vfmin_vv_h, 2, 2) | ||
26 | GEN_VEXT_VV_ENV(vfmin_vv_w, 4, 4) | ||
27 | GEN_VEXT_VV_ENV(vfmin_vv_d, 8, 8) | ||
28 | -RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum) | ||
29 | -RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum) | ||
30 | -RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum) | ||
31 | +RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minimum_number) | ||
32 | +RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minimum_number) | ||
33 | +RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minimum_number) | ||
34 | GEN_VEXT_VF(vfmin_vf_h, 2, 2) | ||
35 | GEN_VEXT_VF(vfmin_vf_w, 4, 4) | ||
36 | GEN_VEXT_VF(vfmin_vf_d, 8, 8) | ||
37 | |||
38 | -RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum) | ||
39 | -RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum) | ||
40 | -RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum) | ||
41 | +RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maximum_number) | ||
42 | +RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maximum_number) | ||
43 | +RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maximum_number) | ||
44 | GEN_VEXT_VV_ENV(vfmax_vv_h, 2, 2) | ||
45 | GEN_VEXT_VV_ENV(vfmax_vv_w, 4, 4) | ||
46 | GEN_VEXT_VV_ENV(vfmax_vv_d, 8, 8) | ||
47 | -RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum) | ||
48 | -RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum) | ||
49 | -RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum) | ||
50 | +RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maximum_number) | ||
51 | +RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maximum_number) | ||
52 | +RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maximum_number) | ||
53 | GEN_VEXT_VF(vfmax_vf_h, 2, 2) | ||
54 | GEN_VEXT_VF(vfmax_vf_w, 4, 4) | ||
55 | GEN_VEXT_VF(vfmax_vf_d, 8, 8) | ||
56 | -- | ||
57 | 2.31.1 | ||
58 | |||
59 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
5 | Message-Id: <20211210075704.23951-61-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/internals.h | 9 +++++++++ | ||
9 | target/riscv/fpu_helper.c | 12 ++++++------ | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 18 +++++++++--------- | ||
11 | 3 files changed, 24 insertions(+), 15 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/internals.h | ||
16 | +++ b/target/riscv/internals.h | ||
17 | @@ -XXX,XX +XXX,XX @@ target_ulong fclass_d(uint64_t frs1); | ||
18 | extern const VMStateDescription vmstate_riscv_cpu; | ||
19 | #endif | ||
20 | |||
21 | +enum { | ||
22 | + RISCV_FRM_RNE = 0, /* Round to Nearest, ties to Even */ | ||
23 | + RISCV_FRM_RTZ = 1, /* Round towards Zero */ | ||
24 | + RISCV_FRM_RDN = 2, /* Round Down */ | ||
25 | + RISCV_FRM_RUP = 3, /* Round Up */ | ||
26 | + RISCV_FRM_RMM = 4, /* Round to Nearest, ties to Max Magnitude */ | ||
27 | + RISCV_FRM_DYN = 7, /* Dynamic rounding mode */ | ||
28 | +}; | ||
29 | + | ||
30 | static inline uint64_t nanbox_s(float32 f) | ||
31 | { | ||
32 | return f | MAKE_64BIT_MASK(32, 32); | ||
33 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/target/riscv/fpu_helper.c | ||
36 | +++ b/target/riscv/fpu_helper.c | ||
37 | @@ -XXX,XX +XXX,XX @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) | ||
38 | { | ||
39 | int softrm; | ||
40 | |||
41 | - if (rm == 7) { | ||
42 | + if (rm == RISCV_FRM_DYN) { | ||
43 | rm = env->frm; | ||
44 | } | ||
45 | switch (rm) { | ||
46 | - case 0: | ||
47 | + case RISCV_FRM_RNE: | ||
48 | softrm = float_round_nearest_even; | ||
49 | break; | ||
50 | - case 1: | ||
51 | + case RISCV_FRM_RTZ: | ||
52 | softrm = float_round_to_zero; | ||
53 | break; | ||
54 | - case 2: | ||
55 | + case RISCV_FRM_RDN: | ||
56 | softrm = float_round_down; | ||
57 | break; | ||
58 | - case 3: | ||
59 | + case RISCV_FRM_RUP: | ||
60 | softrm = float_round_up; | ||
61 | break; | ||
62 | - case 4: | ||
63 | + case RISCV_FRM_RMM: | ||
64 | softrm = float_round_ties_away; | ||
65 | break; | ||
66 | default: | ||
67 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
70 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
71 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
72 | gen_helper_##NAME##_d, \ | ||
73 | }; \ | ||
74 | TCGLabel *over = gen_new_label(); \ | ||
75 | - gen_set_rm(s, 7); \ | ||
76 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
77 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
78 | \ | ||
79 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
80 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
81 | gen_helper_##NAME##_w, \ | ||
82 | gen_helper_##NAME##_d, \ | ||
83 | }; \ | ||
84 | - gen_set_rm(s, 7); \ | ||
85 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
86 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
87 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
88 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
89 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
90 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
91 | }; \ | ||
92 | TCGLabel *over = gen_new_label(); \ | ||
93 | - gen_set_rm(s, 7); \ | ||
94 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
95 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
96 | \ | ||
97 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
98 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
99 | static gen_helper_opfvf *const fns[2] = { \ | ||
100 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
101 | }; \ | ||
102 | - gen_set_rm(s, 7); \ | ||
103 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
104 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
105 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
106 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
107 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
108 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
109 | }; \ | ||
110 | TCGLabel *over = gen_new_label(); \ | ||
111 | - gen_set_rm(s, 7); \ | ||
112 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
113 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
114 | \ | ||
115 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
116 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
117 | static gen_helper_opfvf *const fns[2] = { \ | ||
118 | gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ | ||
119 | }; \ | ||
120 | - gen_set_rm(s, 7); \ | ||
121 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
122 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
123 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
124 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
125 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
126 | gen_helper_##NAME##_d, \ | ||
127 | }; \ | ||
128 | TCGLabel *over = gen_new_label(); \ | ||
129 | - gen_set_rm(s, 7); \ | ||
130 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
131 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
132 | \ | ||
133 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
134 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
135 | gen_helper_##NAME##_w, \ | ||
136 | }; \ | ||
137 | TCGLabel *over = gen_new_label(); \ | ||
138 | - gen_set_rm(s, 7); \ | ||
139 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
140 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
141 | \ | ||
142 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
143 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
144 | gen_helper_##NAME##_w, \ | ||
145 | }; \ | ||
146 | TCGLabel *over = gen_new_label(); \ | ||
147 | - gen_set_rm(s, 7); \ | ||
148 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
149 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
150 | \ | ||
151 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
152 | -- | ||
153 | 2.31.1 | ||
154 | |||
155 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Add the following instructions: | ||
4 | |||
5 | * vfcvt.rtz.xu.f.v | ||
6 | * vfcvt.rtz.x.f.v | ||
7 | |||
8 | Also adjust GEN_OPFV_TRANS() to accept multiple floating-point rounding | ||
9 | modes. | ||
10 | |||
11 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-Id: <20211210075704.23951-62-frank.chang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/insn32.decode | 11 ++-- | ||
17 | target/riscv/insn_trans/trans_rvv.c.inc | 84 +++++++++++++++---------- | ||
18 | 2 files changed, 59 insertions(+), 36 deletions(-) | ||
19 | |||
20 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/insn32.decode | ||
23 | +++ b/target/riscv/insn32.decode | ||
24 | @@ -XXX,XX +XXX,XX @@ vmfge_vf 011111 . ..... ..... 101 ..... 1010111 @r_vm | ||
25 | vfclass_v 010011 . ..... 10000 001 ..... 1010111 @r2_vm | ||
26 | vfmerge_vfm 010111 0 ..... ..... 101 ..... 1010111 @r_vm_0 | ||
27 | vfmv_v_f 010111 1 00000 ..... 101 ..... 1010111 @r2 | ||
28 | -vfcvt_xu_f_v 100010 . ..... 00000 001 ..... 1010111 @r2_vm | ||
29 | -vfcvt_x_f_v 100010 . ..... 00001 001 ..... 1010111 @r2_vm | ||
30 | -vfcvt_f_xu_v 100010 . ..... 00010 001 ..... 1010111 @r2_vm | ||
31 | -vfcvt_f_x_v 100010 . ..... 00011 001 ..... 1010111 @r2_vm | ||
32 | + | ||
33 | +vfcvt_xu_f_v 010010 . ..... 00000 001 ..... 1010111 @r2_vm | ||
34 | +vfcvt_x_f_v 010010 . ..... 00001 001 ..... 1010111 @r2_vm | ||
35 | +vfcvt_f_xu_v 010010 . ..... 00010 001 ..... 1010111 @r2_vm | ||
36 | +vfcvt_f_x_v 010010 . ..... 00011 001 ..... 1010111 @r2_vm | ||
37 | +vfcvt_rtz_xu_f_v 010010 . ..... 00110 001 ..... 1010111 @r2_vm | ||
38 | +vfcvt_rtz_x_f_v 010010 . ..... 00111 001 ..... 1010111 @r2_vm | ||
39 | vfwcvt_xu_f_v 100010 . ..... 01000 001 ..... 1010111 @r2_vm | ||
40 | vfwcvt_x_f_v 100010 . ..... 01001 001 ..... 1010111 @r2_vm | ||
41 | vfwcvt_f_xu_v 100010 . ..... 01010 001 ..... 1010111 @r2_vm | ||
42 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
45 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
46 | @@ -XXX,XX +XXX,XX @@ | ||
47 | /* | ||
48 | - * RISC-V translation routines for the RVV Standard Extension. | ||
49 | * | ||
50 | * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved. | ||
51 | * | ||
52 | @@ -XXX,XX +XXX,XX @@ static bool opfv_check(DisasContext *s, arg_rmr *a) | ||
53 | vext_check_ss(s, a->rd, a->rs2, a->vm); | ||
54 | } | ||
55 | |||
56 | -#define GEN_OPFV_TRANS(NAME, CHECK) \ | ||
57 | -static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
58 | -{ \ | ||
59 | - if (CHECK(s, a)) { \ | ||
60 | - uint32_t data = 0; \ | ||
61 | - static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
62 | - gen_helper_##NAME##_h, \ | ||
63 | - gen_helper_##NAME##_w, \ | ||
64 | - gen_helper_##NAME##_d, \ | ||
65 | - }; \ | ||
66 | - TCGLabel *over = gen_new_label(); \ | ||
67 | - gen_set_rm(s, RISCV_FRM_DYN); \ | ||
68 | - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
69 | - \ | ||
70 | - data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
71 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
72 | - tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
73 | - vreg_ofs(s, a->rs2), cpu_env, \ | ||
74 | - s->vlen / 8, s->vlen / 8, data, \ | ||
75 | - fns[s->sew - 1]); \ | ||
76 | - mark_vs_dirty(s); \ | ||
77 | - gen_set_label(over); \ | ||
78 | - return true; \ | ||
79 | - } \ | ||
80 | - return false; \ | ||
81 | +static bool do_opfv(DisasContext *s, arg_rmr *a, | ||
82 | + gen_helper_gvec_3_ptr *fn, | ||
83 | + bool (*checkfn)(DisasContext *, arg_rmr *), | ||
84 | + int rm) | ||
85 | +{ | ||
86 | + if (checkfn(s, a)) { | ||
87 | + uint32_t data = 0; | ||
88 | + TCGLabel *over = gen_new_label(); | ||
89 | + gen_set_rm(s, rm); | ||
90 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
91 | + | ||
92 | + data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
93 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
94 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
95 | + vreg_ofs(s, a->rs2), cpu_env, | ||
96 | + s->vlen / 8, s->vlen / 8, data, fn); | ||
97 | + mark_vs_dirty(s); | ||
98 | + gen_set_label(over); | ||
99 | + return true; | ||
100 | + } | ||
101 | + return false; | ||
102 | +} | ||
103 | + | ||
104 | +#define GEN_OPFV_TRANS(NAME, CHECK, FRM) \ | ||
105 | +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
106 | +{ \ | ||
107 | + static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
108 | + gen_helper_##NAME##_h, \ | ||
109 | + gen_helper_##NAME##_w, \ | ||
110 | + gen_helper_##NAME##_d \ | ||
111 | + }; \ | ||
112 | + return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM); \ | ||
113 | } | ||
114 | |||
115 | -GEN_OPFV_TRANS(vfsqrt_v, opfv_check) | ||
116 | +GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN) | ||
117 | |||
118 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
119 | GEN_OPFVV_TRANS(vfmin_vv, opfvv_check) | ||
120 | @@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check) | ||
121 | GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check) | ||
122 | |||
123 | /* Vector Floating-Point Classify Instruction */ | ||
124 | -GEN_OPFV_TRANS(vfclass_v, opfv_check) | ||
125 | +GEN_OPFV_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN) | ||
126 | |||
127 | /* Vector Floating-Point Merge Instruction */ | ||
128 | GEN_OPFVF_TRANS(vfmerge_vfm, opfvf_check) | ||
129 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
130 | } | ||
131 | |||
132 | /* Single-Width Floating-Point/Integer Type-Convert Instructions */ | ||
133 | -GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check) | ||
134 | -GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check) | ||
135 | -GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check) | ||
136 | -GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check) | ||
137 | +#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM) \ | ||
138 | +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
139 | +{ \ | ||
140 | + static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
141 | + gen_helper_##HELPER##_h, \ | ||
142 | + gen_helper_##HELPER##_w, \ | ||
143 | + gen_helper_##HELPER##_d \ | ||
144 | + }; \ | ||
145 | + return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM); \ | ||
146 | +} | ||
147 | + | ||
148 | +GEN_OPFV_CVT_TRANS(vfcvt_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_DYN) | ||
149 | +GEN_OPFV_CVT_TRANS(vfcvt_x_f_v, vfcvt_x_f_v, RISCV_FRM_DYN) | ||
150 | +GEN_OPFV_CVT_TRANS(vfcvt_f_xu_v, vfcvt_f_xu_v, RISCV_FRM_DYN) | ||
151 | +GEN_OPFV_CVT_TRANS(vfcvt_f_x_v, vfcvt_f_x_v, RISCV_FRM_DYN) | ||
152 | +/* Reuse the helper functions from vfcvt.xu.f.v and vfcvt.x.f.v */ | ||
153 | +GEN_OPFV_CVT_TRANS(vfcvt_rtz_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_RTZ) | ||
154 | +GEN_OPFV_CVT_TRANS(vfcvt_rtz_x_f_v, vfcvt_x_f_v, RISCV_FRM_RTZ) | ||
155 | |||
156 | /* Widening Floating-Point/Integer Type-Convert Instructions */ | ||
157 | |||
158 | -- | ||
159 | 2.31.1 | ||
160 | |||
161 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Add the following instructions: | ||
4 | |||
5 | * vfwcvt.rtz.xu.f.v | ||
6 | * vfwcvt.rtz.x.f.v | ||
7 | |||
8 | Also adjust GEN_OPFV_WIDEN_TRANS() to accept multiple floating-point | ||
9 | rounding modes. | ||
10 | |||
11 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
12 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-Id: <20211210075704.23951-63-frank.chang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/helper.h | 2 + | ||
17 | target/riscv/insn32.decode | 13 +++--- | ||
18 | target/riscv/vector_helper.c | 7 +++- | ||
19 | target/riscv/insn_trans/trans_rvv.c.inc | 55 +++++++++++++++++++++---- | ||
20 | 4 files changed, 63 insertions(+), 14 deletions(-) | ||
21 | |||
22 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/target/riscv/helper.h | ||
25 | +++ b/target/riscv/helper.h | ||
26 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
27 | DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
28 | DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
29 | DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
30 | +DEF_HELPER_5(vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32) | ||
31 | DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32) | ||
32 | DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32) | ||
33 | +DEF_HELPER_5(vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32) | ||
34 | DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32) | ||
35 | DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32) | ||
36 | DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
37 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/target/riscv/insn32.decode | ||
40 | +++ b/target/riscv/insn32.decode | ||
41 | @@ -XXX,XX +XXX,XX @@ vfcvt_f_xu_v 010010 . ..... 00010 001 ..... 1010111 @r2_vm | ||
42 | vfcvt_f_x_v 010010 . ..... 00011 001 ..... 1010111 @r2_vm | ||
43 | vfcvt_rtz_xu_f_v 010010 . ..... 00110 001 ..... 1010111 @r2_vm | ||
44 | vfcvt_rtz_x_f_v 010010 . ..... 00111 001 ..... 1010111 @r2_vm | ||
45 | -vfwcvt_xu_f_v 100010 . ..... 01000 001 ..... 1010111 @r2_vm | ||
46 | -vfwcvt_x_f_v 100010 . ..... 01001 001 ..... 1010111 @r2_vm | ||
47 | -vfwcvt_f_xu_v 100010 . ..... 01010 001 ..... 1010111 @r2_vm | ||
48 | -vfwcvt_f_x_v 100010 . ..... 01011 001 ..... 1010111 @r2_vm | ||
49 | -vfwcvt_f_f_v 100010 . ..... 01100 001 ..... 1010111 @r2_vm | ||
50 | + | ||
51 | +vfwcvt_xu_f_v 010010 . ..... 01000 001 ..... 1010111 @r2_vm | ||
52 | +vfwcvt_x_f_v 010010 . ..... 01001 001 ..... 1010111 @r2_vm | ||
53 | +vfwcvt_f_xu_v 010010 . ..... 01010 001 ..... 1010111 @r2_vm | ||
54 | +vfwcvt_f_x_v 010010 . ..... 01011 001 ..... 1010111 @r2_vm | ||
55 | +vfwcvt_f_f_v 010010 . ..... 01100 001 ..... 1010111 @r2_vm | ||
56 | +vfwcvt_rtz_xu_f_v 010010 . ..... 01110 001 ..... 1010111 @r2_vm | ||
57 | +vfwcvt_rtz_x_f_v 010010 . ..... 01111 001 ..... 1010111 @r2_vm | ||
58 | vfncvt_xu_f_v 100010 . ..... 10000 001 ..... 1010111 @r2_vm | ||
59 | vfncvt_x_f_v 100010 . ..... 10001 001 ..... 1010111 @r2_vm | ||
60 | vfncvt_f_xu_v 100010 . ..... 10010 001 ..... 1010111 @r2_vm | ||
61 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/target/riscv/vector_helper.c | ||
64 | +++ b/target/riscv/vector_helper.c | ||
65 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8) | ||
66 | |||
67 | /* Widening Floating-Point/Integer Type-Convert Instructions */ | ||
68 | /* (TD, T2, TX2) */ | ||
69 | +#define WOP_UU_B uint16_t, uint8_t, uint8_t | ||
70 | #define WOP_UU_H uint32_t, uint16_t, uint16_t | ||
71 | #define WOP_UU_W uint64_t, uint32_t, uint32_t | ||
72 | /* vfwcvt.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer.*/ | ||
73 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfwcvt_x_f_v_h, 2, 4) | ||
74 | GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 4, 8) | ||
75 | |||
76 | /* vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float */ | ||
77 | +RVVCALL(OPFVV1, vfwcvt_f_xu_v_b, WOP_UU_B, H2, H1, uint8_to_float16) | ||
78 | RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32) | ||
79 | RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64) | ||
80 | +GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b, 1, 2) | ||
81 | GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 2, 4) | ||
82 | GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 4, 8) | ||
83 | |||
84 | /* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */ | ||
85 | +RVVCALL(OPFVV1, vfwcvt_f_x_v_b, WOP_UU_B, H2, H1, int8_to_float16) | ||
86 | RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32) | ||
87 | RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64) | ||
88 | +GEN_VEXT_V_ENV(vfwcvt_f_x_v_b, 1, 2) | ||
89 | GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 2, 4) | ||
90 | GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 4, 8) | ||
91 | |||
92 | /* | ||
93 | - * vfwcvt.f.f.v vd, vs2, vm # | ||
94 | + * vfwcvt.f.f.v vd, vs2, vm | ||
95 | * Convert single-width float to double-width float. | ||
96 | */ | ||
97 | static uint32_t vfwcvtffv16(uint16_t a, float_status *s) | ||
98 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
101 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
102 | @@ -XXX,XX +XXX,XX @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a) | ||
103 | vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
104 | } | ||
105 | |||
106 | -#define GEN_OPFV_WIDEN_TRANS(NAME) \ | ||
107 | +#define GEN_OPFV_WIDEN_TRANS(NAME, HELPER, FRM) \ | ||
108 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
109 | { \ | ||
110 | if (opfv_widen_check(s, a)) { \ | ||
111 | uint32_t data = 0; \ | ||
112 | static gen_helper_gvec_3_ptr * const fns[2] = { \ | ||
113 | + gen_helper_##HELPER##_h, \ | ||
114 | + gen_helper_##HELPER##_w, \ | ||
115 | + }; \ | ||
116 | + TCGLabel *over = gen_new_label(); \ | ||
117 | + gen_set_rm(s, FRM); \ | ||
118 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
119 | + \ | ||
120 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
121 | + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
122 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
123 | + vreg_ofs(s, a->rs2), cpu_env, \ | ||
124 | + s->vlen / 8, s->vlen / 8, data, \ | ||
125 | + fns[s->sew - 1]); \ | ||
126 | + mark_vs_dirty(s); \ | ||
127 | + gen_set_label(over); \ | ||
128 | + return true; \ | ||
129 | + } \ | ||
130 | + return false; \ | ||
131 | +} | ||
132 | + | ||
133 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_DYN) | ||
134 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, vfwcvt_x_f_v, RISCV_FRM_DYN) | ||
135 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, vfwcvt_f_f_v, RISCV_FRM_DYN) | ||
136 | +/* Reuse the helper functions from vfwcvt.xu.f.v and vfwcvt.x.f.v */ | ||
137 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_RTZ) | ||
138 | +GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, vfwcvt_x_f_v, RISCV_FRM_RTZ) | ||
139 | + | ||
140 | +static bool opfxv_widen_check(DisasContext *s, arg_rmr *a) | ||
141 | +{ | ||
142 | + return require_rvv(s) && | ||
143 | + require_scale_rvf(s) && | ||
144 | + vext_check_isa_ill(s) && | ||
145 | + /* OPFV widening instructions ignore vs1 check */ | ||
146 | + vext_check_ds(s, a->rd, a->rs2, a->vm); | ||
147 | +} | ||
148 | + | ||
149 | +#define GEN_OPFXV_WIDEN_TRANS(NAME) \ | ||
150 | +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
151 | +{ \ | ||
152 | + if (opfxv_widen_check(s, a)) { \ | ||
153 | + uint32_t data = 0; \ | ||
154 | + static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
155 | + gen_helper_##NAME##_b, \ | ||
156 | gen_helper_##NAME##_h, \ | ||
157 | gen_helper_##NAME##_w, \ | ||
158 | }; \ | ||
159 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
160 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
161 | \ | ||
162 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
163 | - data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
164 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
165 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
166 | s->vlen / 8, s->vlen / 8, data, \ | ||
167 | - fns[s->sew - 1]); \ | ||
168 | + fns[s->sew]); \ | ||
169 | mark_vs_dirty(s); \ | ||
170 | gen_set_label(over); \ | ||
171 | return true; \ | ||
172 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
173 | return false; \ | ||
174 | } | ||
175 | |||
176 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v) | ||
177 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v) | ||
178 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v) | ||
179 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v) | ||
180 | -GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v) | ||
181 | +GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_xu_v) | ||
182 | +GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_x_v) | ||
183 | |||
184 | /* Narrowing Floating-Point/Integer Type-Convert Instructions */ | ||
185 | |||
186 | -- | ||
187 | 2.31.1 | ||
188 | |||
189 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | helper_set_rounding_mode() is responsible for SIGILL, and "round to odd" | ||
4 | should be an interface private to translation, so add a new independent | ||
5 | helper_set_rod_rounding_mode(). | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-64-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/helper.h | 1 + | ||
13 | target/riscv/internals.h | 1 + | ||
14 | target/riscv/fpu_helper.c | 5 +++++ | ||
15 | target/riscv/translate.c | 7 +++++++ | ||
16 | 4 files changed, 14 insertions(+) | ||
17 | |||
18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/helper.h | ||
21 | +++ b/target/riscv/helper.h | ||
22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(raise_exception, noreturn, env, i32) | ||
23 | |||
24 | /* Floating Point - rounding mode */ | ||
25 | DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32) | ||
26 | +DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env) | ||
27 | |||
28 | /* Floating Point - fused */ | ||
29 | DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) | ||
30 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/target/riscv/internals.h | ||
33 | +++ b/target/riscv/internals.h | ||
34 | @@ -XXX,XX +XXX,XX @@ enum { | ||
35 | RISCV_FRM_RUP = 3, /* Round Up */ | ||
36 | RISCV_FRM_RMM = 4, /* Round to Nearest, ties to Max Magnitude */ | ||
37 | RISCV_FRM_DYN = 7, /* Dynamic rounding mode */ | ||
38 | + RISCV_FRM_ROD = 8, /* Round to Odd */ | ||
39 | }; | ||
40 | |||
41 | static inline uint64_t nanbox_s(float32 f) | ||
42 | diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/target/riscv/fpu_helper.c | ||
45 | +++ b/target/riscv/fpu_helper.c | ||
46 | @@ -XXX,XX +XXX,XX @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) | ||
47 | set_float_rounding_mode(softrm, &env->fp_status); | ||
48 | } | ||
49 | |||
50 | +void helper_set_rod_rounding_mode(CPURISCVState *env) | ||
51 | +{ | ||
52 | + set_float_rounding_mode(float_round_to_odd, &env->fp_status); | ||
53 | +} | ||
54 | + | ||
55 | static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2, | ||
56 | uint64_t rs3, int flags) | ||
57 | { | ||
58 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/translate.c | ||
61 | +++ b/target/riscv/translate.c | ||
62 | @@ -XXX,XX +XXX,XX @@ | ||
63 | #include "exec/log.h" | ||
64 | |||
65 | #include "instmap.h" | ||
66 | +#include "internals.h" | ||
67 | |||
68 | /* global register indices */ | ||
69 | static TCGv cpu_gpr[32], cpu_pc, cpu_vl; | ||
70 | @@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm) | ||
71 | return; | ||
72 | } | ||
73 | ctx->frm = rm; | ||
74 | + | ||
75 | + if (rm == RISCV_FRM_ROD) { | ||
76 | + gen_helper_set_rod_rounding_mode(cpu_env); | ||
77 | + return; | ||
78 | + } | ||
79 | + | ||
80 | gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm)); | ||
81 | } | ||
82 | |||
83 | -- | ||
84 | 2.31.1 | ||
85 | |||
86 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-65-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 22 ++++----- | ||
9 | target/riscv/insn32.decode | 15 ++++--- | ||
10 | target/riscv/vector_helper.c | 45 ++++++++++--------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 59 +++++++++++++++++++++---- | ||
12 | 4 files changed, 97 insertions(+), 44 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32) | ||
19 | DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
20 | DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
21 | |||
22 | -DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
23 | -DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
24 | -DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
25 | -DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
26 | -DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32) | ||
27 | -DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32) | ||
28 | -DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32) | ||
29 | -DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32) | ||
30 | -DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32) | ||
31 | -DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32) | ||
32 | +DEF_HELPER_5(vfncvt_xu_f_w_b, void, ptr, ptr, ptr, env, i32) | ||
33 | +DEF_HELPER_5(vfncvt_xu_f_w_h, void, ptr, ptr, ptr, env, i32) | ||
34 | +DEF_HELPER_5(vfncvt_xu_f_w_w, void, ptr, ptr, ptr, env, i32) | ||
35 | +DEF_HELPER_5(vfncvt_x_f_w_b, void, ptr, ptr, ptr, env, i32) | ||
36 | +DEF_HELPER_5(vfncvt_x_f_w_h, void, ptr, ptr, ptr, env, i32) | ||
37 | +DEF_HELPER_5(vfncvt_x_f_w_w, void, ptr, ptr, ptr, env, i32) | ||
38 | +DEF_HELPER_5(vfncvt_f_xu_w_h, void, ptr, ptr, ptr, env, i32) | ||
39 | +DEF_HELPER_5(vfncvt_f_xu_w_w, void, ptr, ptr, ptr, env, i32) | ||
40 | +DEF_HELPER_5(vfncvt_f_x_w_h, void, ptr, ptr, ptr, env, i32) | ||
41 | +DEF_HELPER_5(vfncvt_f_x_w_w, void, ptr, ptr, ptr, env, i32) | ||
42 | +DEF_HELPER_5(vfncvt_f_f_w_h, void, ptr, ptr, ptr, env, i32) | ||
43 | +DEF_HELPER_5(vfncvt_f_f_w_w, void, ptr, ptr, ptr, env, i32) | ||
44 | |||
45 | DEF_HELPER_6(vredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32) | ||
46 | DEF_HELPER_6(vredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
47 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/target/riscv/insn32.decode | ||
50 | +++ b/target/riscv/insn32.decode | ||
51 | @@ -XXX,XX +XXX,XX @@ vfwcvt_f_x_v 010010 . ..... 01011 001 ..... 1010111 @r2_vm | ||
52 | vfwcvt_f_f_v 010010 . ..... 01100 001 ..... 1010111 @r2_vm | ||
53 | vfwcvt_rtz_xu_f_v 010010 . ..... 01110 001 ..... 1010111 @r2_vm | ||
54 | vfwcvt_rtz_x_f_v 010010 . ..... 01111 001 ..... 1010111 @r2_vm | ||
55 | -vfncvt_xu_f_v 100010 . ..... 10000 001 ..... 1010111 @r2_vm | ||
56 | -vfncvt_x_f_v 100010 . ..... 10001 001 ..... 1010111 @r2_vm | ||
57 | -vfncvt_f_xu_v 100010 . ..... 10010 001 ..... 1010111 @r2_vm | ||
58 | -vfncvt_f_x_v 100010 . ..... 10011 001 ..... 1010111 @r2_vm | ||
59 | -vfncvt_f_f_v 100010 . ..... 10100 001 ..... 1010111 @r2_vm | ||
60 | + | ||
61 | +vfncvt_xu_f_w 010010 . ..... 10000 001 ..... 1010111 @r2_vm | ||
62 | +vfncvt_x_f_w 010010 . ..... 10001 001 ..... 1010111 @r2_vm | ||
63 | +vfncvt_f_xu_w 010010 . ..... 10010 001 ..... 1010111 @r2_vm | ||
64 | +vfncvt_f_x_w 010010 . ..... 10011 001 ..... 1010111 @r2_vm | ||
65 | +vfncvt_f_f_w 010010 . ..... 10100 001 ..... 1010111 @r2_vm | ||
66 | +vfncvt_rod_f_f_w 010010 . ..... 10101 001 ..... 1010111 @r2_vm | ||
67 | +vfncvt_rtz_xu_f_w 010010 . ..... 10110 001 ..... 1010111 @r2_vm | ||
68 | +vfncvt_rtz_x_f_w 010010 . ..... 10111 001 ..... 1010111 @r2_vm | ||
69 | + | ||
70 | vredsum_vs 000000 . ..... ..... 010 ..... 1010111 @r_vm | ||
71 | vredand_vs 000001 . ..... ..... 010 ..... 1010111 @r_vm | ||
72 | vredor_vs 000010 . ..... ..... 010 ..... 1010111 @r_vm | ||
73 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
74 | index XXXXXXX..XXXXXXX 100644 | ||
75 | --- a/target/riscv/vector_helper.c | ||
76 | +++ b/target/riscv/vector_helper.c | ||
77 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8) | ||
78 | |||
79 | /* Narrowing Floating-Point/Integer Type-Convert Instructions */ | ||
80 | /* (TD, T2, TX2) */ | ||
81 | +#define NOP_UU_B uint8_t, uint16_t, uint32_t | ||
82 | #define NOP_UU_H uint16_t, uint32_t, uint32_t | ||
83 | #define NOP_UU_W uint32_t, uint64_t, uint64_t | ||
84 | /* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */ | ||
85 | -RVVCALL(OPFVV1, vfncvt_xu_f_v_h, NOP_UU_H, H2, H4, float32_to_uint16) | ||
86 | -RVVCALL(OPFVV1, vfncvt_xu_f_v_w, NOP_UU_W, H4, H8, float64_to_uint32) | ||
87 | -GEN_VEXT_V_ENV(vfncvt_xu_f_v_h, 2, 2) | ||
88 | -GEN_VEXT_V_ENV(vfncvt_xu_f_v_w, 4, 4) | ||
89 | +RVVCALL(OPFVV1, vfncvt_xu_f_w_b, NOP_UU_B, H1, H2, float16_to_uint8) | ||
90 | +RVVCALL(OPFVV1, vfncvt_xu_f_w_h, NOP_UU_H, H2, H4, float32_to_uint16) | ||
91 | +RVVCALL(OPFVV1, vfncvt_xu_f_w_w, NOP_UU_W, H4, H8, float64_to_uint32) | ||
92 | +GEN_VEXT_V_ENV(vfncvt_xu_f_w_b, 1, 1) | ||
93 | +GEN_VEXT_V_ENV(vfncvt_xu_f_w_h, 2, 2) | ||
94 | +GEN_VEXT_V_ENV(vfncvt_xu_f_w_w, 4, 4) | ||
95 | |||
96 | /* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */ | ||
97 | -RVVCALL(OPFVV1, vfncvt_x_f_v_h, NOP_UU_H, H2, H4, float32_to_int16) | ||
98 | -RVVCALL(OPFVV1, vfncvt_x_f_v_w, NOP_UU_W, H4, H8, float64_to_int32) | ||
99 | -GEN_VEXT_V_ENV(vfncvt_x_f_v_h, 2, 2) | ||
100 | -GEN_VEXT_V_ENV(vfncvt_x_f_v_w, 4, 4) | ||
101 | +RVVCALL(OPFVV1, vfncvt_x_f_w_b, NOP_UU_B, H1, H2, float16_to_int8) | ||
102 | +RVVCALL(OPFVV1, vfncvt_x_f_w_h, NOP_UU_H, H2, H4, float32_to_int16) | ||
103 | +RVVCALL(OPFVV1, vfncvt_x_f_w_w, NOP_UU_W, H4, H8, float64_to_int32) | ||
104 | +GEN_VEXT_V_ENV(vfncvt_x_f_w_b, 1, 1) | ||
105 | +GEN_VEXT_V_ENV(vfncvt_x_f_w_h, 2, 2) | ||
106 | +GEN_VEXT_V_ENV(vfncvt_x_f_w_w, 4, 4) | ||
107 | |||
108 | /* vfncvt.f.xu.v vd, vs2, vm # Convert double-width unsigned integer to float */ | ||
109 | -RVVCALL(OPFVV1, vfncvt_f_xu_v_h, NOP_UU_H, H2, H4, uint32_to_float16) | ||
110 | -RVVCALL(OPFVV1, vfncvt_f_xu_v_w, NOP_UU_W, H4, H8, uint64_to_float32) | ||
111 | -GEN_VEXT_V_ENV(vfncvt_f_xu_v_h, 2, 2) | ||
112 | -GEN_VEXT_V_ENV(vfncvt_f_xu_v_w, 4, 4) | ||
113 | +RVVCALL(OPFVV1, vfncvt_f_xu_w_h, NOP_UU_H, H2, H4, uint32_to_float16) | ||
114 | +RVVCALL(OPFVV1, vfncvt_f_xu_w_w, NOP_UU_W, H4, H8, uint64_to_float32) | ||
115 | +GEN_VEXT_V_ENV(vfncvt_f_xu_w_h, 2, 2) | ||
116 | +GEN_VEXT_V_ENV(vfncvt_f_xu_w_w, 4, 4) | ||
117 | |||
118 | /* vfncvt.f.x.v vd, vs2, vm # Convert double-width integer to float. */ | ||
119 | -RVVCALL(OPFVV1, vfncvt_f_x_v_h, NOP_UU_H, H2, H4, int32_to_float16) | ||
120 | -RVVCALL(OPFVV1, vfncvt_f_x_v_w, NOP_UU_W, H4, H8, int64_to_float32) | ||
121 | -GEN_VEXT_V_ENV(vfncvt_f_x_v_h, 2, 2) | ||
122 | -GEN_VEXT_V_ENV(vfncvt_f_x_v_w, 4, 4) | ||
123 | +RVVCALL(OPFVV1, vfncvt_f_x_w_h, NOP_UU_H, H2, H4, int32_to_float16) | ||
124 | +RVVCALL(OPFVV1, vfncvt_f_x_w_w, NOP_UU_W, H4, H8, int64_to_float32) | ||
125 | +GEN_VEXT_V_ENV(vfncvt_f_x_w_h, 2, 2) | ||
126 | +GEN_VEXT_V_ENV(vfncvt_f_x_w_w, 4, 4) | ||
127 | |||
128 | /* vfncvt.f.f.v vd, vs2, vm # Convert double float to single-width float. */ | ||
129 | static uint16_t vfncvtffv16(uint32_t a, float_status *s) | ||
130 | @@ -XXX,XX +XXX,XX @@ static uint16_t vfncvtffv16(uint32_t a, float_status *s) | ||
131 | return float32_to_float16(a, true, s); | ||
132 | } | ||
133 | |||
134 | -RVVCALL(OPFVV1, vfncvt_f_f_v_h, NOP_UU_H, H2, H4, vfncvtffv16) | ||
135 | -RVVCALL(OPFVV1, vfncvt_f_f_v_w, NOP_UU_W, H4, H8, float64_to_float32) | ||
136 | -GEN_VEXT_V_ENV(vfncvt_f_f_v_h, 2, 2) | ||
137 | -GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4) | ||
138 | +RVVCALL(OPFVV1, vfncvt_f_f_w_h, NOP_UU_H, H2, H4, vfncvtffv16) | ||
139 | +RVVCALL(OPFVV1, vfncvt_f_f_w_w, NOP_UU_W, H4, H8, float64_to_float32) | ||
140 | +GEN_VEXT_V_ENV(vfncvt_f_f_w_h, 2, 2) | ||
141 | +GEN_VEXT_V_ENV(vfncvt_f_f_w_w, 4, 4) | ||
142 | |||
143 | /* | ||
144 | *** Vector Reduction Operations | ||
145 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
146 | index XXXXXXX..XXXXXXX 100644 | ||
147 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
148 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
149 | @@ -XXX,XX +XXX,XX @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
150 | vext_check_sd(s, a->rd, a->rs2, a->vm); | ||
151 | } | ||
152 | |||
153 | -#define GEN_OPFV_NARROW_TRANS(NAME) \ | ||
154 | +#define GEN_OPFV_NARROW_TRANS(NAME, HELPER, FRM) \ | ||
155 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
156 | { \ | ||
157 | if (opfv_narrow_check(s, a)) { \ | ||
158 | uint32_t data = 0; \ | ||
159 | static gen_helper_gvec_3_ptr * const fns[2] = { \ | ||
160 | - gen_helper_##NAME##_h, \ | ||
161 | - gen_helper_##NAME##_w, \ | ||
162 | + gen_helper_##HELPER##_h, \ | ||
163 | + gen_helper_##HELPER##_w, \ | ||
164 | }; \ | ||
165 | TCGLabel *over = gen_new_label(); \ | ||
166 | - gen_set_rm(s, RISCV_FRM_DYN); \ | ||
167 | + gen_set_rm(s, FRM); \ | ||
168 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
169 | \ | ||
170 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
171 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
172 | return false; \ | ||
173 | } | ||
174 | |||
175 | -GEN_OPFV_NARROW_TRANS(vfncvt_xu_f_v) | ||
176 | -GEN_OPFV_NARROW_TRANS(vfncvt_x_f_v) | ||
177 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_v) | ||
178 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_x_v) | ||
179 | -GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v) | ||
180 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, vfncvt_f_xu_w, RISCV_FRM_DYN) | ||
181 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, vfncvt_f_x_w, RISCV_FRM_DYN) | ||
182 | +GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, vfncvt_f_f_w, RISCV_FRM_DYN) | ||
183 | +/* Reuse the helper function from vfncvt.f.f.w */ | ||
184 | +GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, vfncvt_f_f_w, RISCV_FRM_ROD) | ||
185 | + | ||
186 | +static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
187 | +{ | ||
188 | + return require_rvv(s) && | ||
189 | + require_scale_rvf(s) && | ||
190 | + vext_check_isa_ill(s) && | ||
191 | + /* OPFV narrowing instructions ignore vs1 check */ | ||
192 | + vext_check_sd(s, a->rd, a->rs2, a->vm); | ||
193 | +} | ||
194 | + | ||
195 | +#define GEN_OPXFV_NARROW_TRANS(NAME, HELPER, FRM) \ | ||
196 | +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
197 | +{ \ | ||
198 | + if (opxfv_narrow_check(s, a)) { \ | ||
199 | + uint32_t data = 0; \ | ||
200 | + static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
201 | + gen_helper_##HELPER##_b, \ | ||
202 | + gen_helper_##HELPER##_h, \ | ||
203 | + gen_helper_##HELPER##_w, \ | ||
204 | + }; \ | ||
205 | + TCGLabel *over = gen_new_label(); \ | ||
206 | + gen_set_rm(s, FRM); \ | ||
207 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ | ||
208 | + \ | ||
209 | + data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
210 | + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
211 | + vreg_ofs(s, a->rs2), cpu_env, \ | ||
212 | + s->vlen / 8, s->vlen / 8, data, \ | ||
213 | + fns[s->sew]); \ | ||
214 | + mark_vs_dirty(s); \ | ||
215 | + gen_set_label(over); \ | ||
216 | + return true; \ | ||
217 | + } \ | ||
218 | + return false; \ | ||
219 | +} | ||
220 | + | ||
221 | +GEN_OPXFV_NARROW_TRANS(vfncvt_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_DYN) | ||
222 | +GEN_OPXFV_NARROW_TRANS(vfncvt_x_f_w, vfncvt_x_f_w, RISCV_FRM_DYN) | ||
223 | +/* Reuse the helper functions from vfncvt.xu.f.w and vfncvt.x.f.w */ | ||
224 | +GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_RTZ) | ||
225 | +GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_x_f_w, vfncvt_x_f_w, RISCV_FRM_RTZ) | ||
226 | |||
227 | /* | ||
228 | *** Vector Reduction Operations | ||
229 | -- | ||
230 | 2.31.1 | ||
231 | |||
232 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-66-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/cpu.h | 2 +- | ||
9 | target/riscv/vector_helper.c | 2 +- | ||
10 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
11 | 3 files changed, 4 insertions(+), 4 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/cpu.h | ||
16 | +++ b/target/riscv/cpu.h | ||
17 | @@ -XXX,XX +XXX,XX @@ typedef struct CPURISCVState CPURISCVState; | ||
18 | #include "pmp.h" | ||
19 | #endif | ||
20 | |||
21 | -#define RV_VLEN_MAX 256 | ||
22 | +#define RV_VLEN_MAX 1024 | ||
23 | |||
24 | FIELD(VTYPE, VLMUL, 0, 3) | ||
25 | FIELD(VTYPE, VSEW, 3, 3) | ||
26 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/riscv/vector_helper.c | ||
29 | +++ b/target/riscv/vector_helper.c | ||
30 | @@ -XXX,XX +XXX,XX @@ static inline int32_t vext_lmul(uint32_t desc) | ||
31 | static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz) | ||
32 | { | ||
33 | /* | ||
34 | - * As simd_desc support at most 256 bytes, the max vlen is 256 bits. | ||
35 | + * As simd_desc support at most 2048 bytes, the max vlen is 1024 bits. | ||
36 | * so vlen in bytes (vlenb) is encoded as maxsz. | ||
37 | */ | ||
38 | uint32_t vlenb = simd_maxsz(desc); | ||
39 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
42 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
43 | @@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data, | ||
44 | base = get_gpr(s, rs1, EXT_NONE); | ||
45 | |||
46 | /* | ||
47 | - * As simd_desc supports at most 256 bytes, and in this implementation, | ||
48 | - * the max vector group length is 2048 bytes. So split it into two parts. | ||
49 | + * As simd_desc supports at most 2048 bytes, and in this implementation, | ||
50 | + * the max vector group length is 4096 bytes. So split it into two parts. | ||
51 | * | ||
52 | * The first part is vlen in bytes, encoded in maxsz of simd_desc. | ||
53 | * The second part is lmul, encoded in data of simd_desc. | ||
54 | -- | ||
55 | 2.31.1 | ||
56 | |||
57 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> | 1 | From: Frank Chang <frank.chang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Once a "One Time Programmable" is programmed, it shouldn't be reset. | 3 | * Update and check vstart value for vector instructions. |
4 | * Add whole register move instruction helper functions as we have to | ||
5 | call helper function for case where vstart is not zero. | ||
6 | * Remove probe_pages() calls in vector load/store instructions | ||
7 | (except fault-only-first loads) to raise the memory access exception | ||
8 | at the exact processed vector element. | ||
4 | 9 | ||
5 | Do not re-initialize the OTP content in the DeviceReset handler, | 10 | Signed-off-by: Frank Chang <frank.chang@sifive.com> |
6 | initialize it once in the DeviceRealize one. | ||
7 | |||
8 | Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP") | ||
9 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
11 | Message-Id: <20211119104757.331579-1-f4bug@amsat.org> | 12 | Message-Id: <20211210075704.23951-67-frank.chang@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 | hw/misc/sifive_u_otp.c | 13 +++++-------- | 15 | target/riscv/helper.h | 5 + |
15 | 1 file changed, 5 insertions(+), 8 deletions(-) | 16 | target/riscv/csr.c | 6 +- |
17 | target/riscv/translate.c | 6 +- | ||
18 | target/riscv/vector_helper.c | 210 +++++++++++++++--------- | ||
19 | target/riscv/insn_trans/trans_rvv.c.inc | 75 ++++++--- | ||
20 | 5 files changed, 199 insertions(+), 103 deletions(-) | ||
16 | 21 | ||
17 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | 22 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h |
18 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/misc/sifive_u_otp.c | 24 | --- a/target/riscv/helper.h |
20 | +++ b/hw/misc/sifive_u_otp.c | 25 | +++ b/target/riscv/helper.h |
21 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 26 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) |
22 | 27 | DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) | |
23 | if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { | 28 | DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) |
24 | error_setg(errp, "failed to read the initial flash content"); | 29 | |
25 | + return; | 30 | +DEF_HELPER_4(vmv1r_v, void, ptr, ptr, env, i32) |
31 | +DEF_HELPER_4(vmv2r_v, void, ptr, ptr, env, i32) | ||
32 | +DEF_HELPER_4(vmv4r_v, void, ptr, ptr, env, i32) | ||
33 | +DEF_HELPER_4(vmv8r_v, void, ptr, ptr, env, i32) | ||
34 | + | ||
35 | DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32) | ||
36 | DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32) | ||
37 | DEF_HELPER_5(vzext_vf2_d, void, ptr, ptr, ptr, env, i32) | ||
38 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/target/riscv/csr.c | ||
41 | +++ b/target/riscv/csr.c | ||
42 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_vstart(CPURISCVState *env, int csrno, | ||
43 | #if !defined(CONFIG_USER_ONLY) | ||
44 | env->mstatus |= MSTATUS_VS; | ||
45 | #endif | ||
46 | - env->vstart = val; | ||
47 | + /* | ||
48 | + * The vstart CSR is defined to have only enough writable bits | ||
49 | + * to hold the largest element index, i.e. lg2(VLEN) bits. | ||
50 | + */ | ||
51 | + env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen)); | ||
52 | return RISCV_EXCP_NONE; | ||
53 | } | ||
54 | |||
55 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/target/riscv/translate.c | ||
58 | +++ b/target/riscv/translate.c | ||
59 | @@ -XXX,XX +XXX,XX @@ | ||
60 | #include "internals.h" | ||
61 | |||
62 | /* global register indices */ | ||
63 | -static TCGv cpu_gpr[32], cpu_pc, cpu_vl; | ||
64 | +static TCGv cpu_gpr[32], cpu_pc, cpu_vl, cpu_vstart; | ||
65 | static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */ | ||
66 | static TCGv load_res; | ||
67 | static TCGv load_val; | ||
68 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
69 | int8_t lmul; | ||
70 | uint8_t sew; | ||
71 | uint16_t vlen; | ||
72 | + target_ulong vstart; | ||
73 | bool vl_eq_vlmax; | ||
74 | uint8_t ntemp; | ||
75 | CPUState *cs; | ||
76 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
77 | ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL); | ||
78 | ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); | ||
79 | ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3); | ||
80 | + ctx->vstart = env->vstart; | ||
81 | ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); | ||
82 | ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL); | ||
83 | ctx->cs = cs; | ||
84 | @@ -XXX,XX +XXX,XX @@ void riscv_translate_init(void) | ||
85 | |||
86 | cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, pc), "pc"); | ||
87 | cpu_vl = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, vl), "vl"); | ||
88 | + cpu_vstart = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, vstart), | ||
89 | + "vstart"); | ||
90 | load_res = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_res), | ||
91 | "load_res"); | ||
92 | load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val), | ||
93 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/target/riscv/vector_helper.c | ||
96 | +++ b/target/riscv/vector_helper.c | ||
97 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
98 | uint32_t nf = vext_nf(desc); | ||
99 | uint32_t max_elems = vext_max_elems(desc, esz); | ||
100 | |||
101 | - /* probe every access*/ | ||
102 | - for (i = 0; i < env->vl; i++) { | ||
103 | + for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
104 | if (!vm && !vext_elem_mask(v0, i)) { | ||
105 | continue; | ||
106 | } | ||
107 | - probe_pages(env, base + stride * i, nf << esz, ra, access_type); | ||
108 | - } | ||
109 | - /* do real access */ | ||
110 | - for (i = 0; i < env->vl; i++) { | ||
111 | + | ||
112 | k = 0; | ||
113 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
114 | - continue; | ||
115 | - } | ||
116 | while (k < nf) { | ||
117 | target_ulong addr = base + stride * i + (k << esz); | ||
118 | ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
119 | k++; | ||
120 | } | ||
121 | } | ||
122 | + env->vstart = 0; | ||
123 | } | ||
124 | |||
125 | #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN) \ | ||
126 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
127 | uint32_t nf = vext_nf(desc); | ||
128 | uint32_t max_elems = vext_max_elems(desc, esz); | ||
129 | |||
130 | - /* probe every access */ | ||
131 | - probe_pages(env, base, env->vl * (nf << esz), ra, access_type); | ||
132 | /* load bytes from guest memory */ | ||
133 | - for (i = 0; i < env->vl; i++) { | ||
134 | + for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
135 | k = 0; | ||
136 | while (k < nf) { | ||
137 | target_ulong addr = base + ((i * nf + k) << esz); | ||
138 | @@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
139 | k++; | ||
140 | } | ||
141 | } | ||
142 | + env->vstart = 0; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
147 | uint32_t vm = vext_vm(desc); | ||
148 | uint32_t max_elems = vext_max_elems(desc, esz); | ||
149 | |||
150 | - /* probe every access*/ | ||
151 | - for (i = 0; i < env->vl; i++) { | ||
152 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
153 | - continue; | ||
154 | - } | ||
155 | - probe_pages(env, get_index_addr(base, i, vs2), nf << esz, ra, | ||
156 | - access_type); | ||
157 | - } | ||
158 | /* load bytes from guest memory */ | ||
159 | - for (i = 0; i < env->vl; i++) { | ||
160 | - k = 0; | ||
161 | + for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
162 | if (!vm && !vext_elem_mask(v0, i)) { | ||
163 | continue; | ||
164 | } | ||
165 | + | ||
166 | + k = 0; | ||
167 | while (k < nf) { | ||
168 | abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz); | ||
169 | ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
170 | k++; | ||
171 | } | ||
172 | } | ||
173 | + env->vstart = 0; | ||
174 | } | ||
175 | |||
176 | #define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN) \ | ||
177 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
178 | target_ulong addr, offset, remain; | ||
179 | |||
180 | /* probe every access*/ | ||
181 | - for (i = 0; i < env->vl; i++) { | ||
182 | + for (i = env->vstart; i < env->vl; i++) { | ||
183 | if (!vm && !vext_elem_mask(v0, i)) { | ||
184 | continue; | ||
185 | } | ||
186 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
187 | if (vl != 0) { | ||
188 | env->vl = vl; | ||
189 | } | ||
190 | - for (i = 0; i < env->vl; i++) { | ||
191 | + for (i = env->vstart; i < env->vl; i++) { | ||
192 | k = 0; | ||
193 | if (!vm && !vext_elem_mask(v0, i)) { | ||
194 | continue; | ||
195 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
196 | k++; | ||
197 | } | ||
198 | } | ||
199 | + env->vstart = 0; | ||
200 | } | ||
201 | |||
202 | #define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN) \ | ||
203 | @@ -XXX,XX +XXX,XX @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
204 | vext_ldst_elem_fn *ldst_elem, uint32_t esz, uintptr_t ra, | ||
205 | MMUAccessType access_type) | ||
206 | { | ||
207 | - uint32_t i, k; | ||
208 | + uint32_t i, k, off, pos; | ||
209 | uint32_t nf = vext_nf(desc); | ||
210 | uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3; | ||
211 | uint32_t max_elems = vlenb >> esz; | ||
212 | |||
213 | - /* probe every access */ | ||
214 | - probe_pages(env, base, vlenb * nf, ra, access_type); | ||
215 | + k = env->vstart / max_elems; | ||
216 | + off = env->vstart % max_elems; | ||
217 | |||
218 | - /* load bytes from guest memory */ | ||
219 | - for (k = 0; k < nf; k++) { | ||
220 | - for (i = 0; i < max_elems; i++) { | ||
221 | + if (off) { | ||
222 | + /* load/store rest of elements of current segment pointed by vstart */ | ||
223 | + for (pos = off; pos < max_elems; pos++, env->vstart++) { | ||
224 | + target_ulong addr = base + ((pos + k * max_elems) << esz); | ||
225 | + ldst_elem(env, addr, pos + k * max_elems, vd, ra); | ||
226 | + } | ||
227 | + k++; | ||
228 | + } | ||
229 | + | ||
230 | + /* load/store elements for rest of segments */ | ||
231 | + for (; k < nf; k++) { | ||
232 | + for (i = 0; i < max_elems; i++, env->vstart++) { | ||
233 | target_ulong addr = base + ((i + k * max_elems) << esz); | ||
234 | ldst_elem(env, addr, i + k * max_elems, vd, ra); | ||
235 | } | ||
236 | } | ||
237 | + | ||
238 | + env->vstart = 0; | ||
239 | } | ||
240 | |||
241 | #define GEN_VEXT_LD_WHOLE(NAME, ETYPE, LOAD_FN) \ | ||
242 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
243 | uint32_t vl = env->vl; | ||
244 | uint32_t i; | ||
245 | |||
246 | - for (i = 0; i < vl; i++) { | ||
247 | + for (i = env->vstart; i < vl; i++) { | ||
248 | if (!vm && !vext_elem_mask(v0, i)) { | ||
249 | continue; | ||
250 | } | ||
251 | fn(vd, vs1, vs2, i); | ||
252 | } | ||
253 | + env->vstart = 0; | ||
254 | } | ||
255 | |||
256 | /* generate the helpers for OPIVV */ | ||
257 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
258 | uint32_t vl = env->vl; | ||
259 | uint32_t i; | ||
260 | |||
261 | - for (i = 0; i < vl; i++) { | ||
262 | + for (i = env->vstart; i < vl; i++) { | ||
263 | if (!vm && !vext_elem_mask(v0, i)) { | ||
264 | continue; | ||
265 | } | ||
266 | fn(vd, s1, vs2, i); | ||
267 | } | ||
268 | + env->vstart = 0; | ||
269 | } | ||
270 | |||
271 | /* generate the helpers for OPIVX */ | ||
272 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
273 | uint32_t vl = env->vl; \ | ||
274 | uint32_t i; \ | ||
275 | \ | ||
276 | - for (i = 0; i < vl; i++) { \ | ||
277 | + for (i = env->vstart; i < vl; i++) { \ | ||
278 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
279 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
280 | ETYPE carry = vext_elem_mask(v0, i); \ | ||
281 | \ | ||
282 | *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \ | ||
283 | } \ | ||
284 | + env->vstart = 0; \ | ||
285 | } | ||
286 | |||
287 | GEN_VEXT_VADC_VVM(vadc_vvm_b, uint8_t, H1, DO_VADC) | ||
288 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
289 | uint32_t vl = env->vl; \ | ||
290 | uint32_t i; \ | ||
291 | \ | ||
292 | - for (i = 0; i < vl; i++) { \ | ||
293 | + for (i = env->vstart; i < vl; i++) { \ | ||
294 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
295 | ETYPE carry = vext_elem_mask(v0, i); \ | ||
296 | \ | ||
297 | *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\ | ||
298 | } \ | ||
299 | + env->vstart = 0; \ | ||
300 | } | ||
301 | |||
302 | GEN_VEXT_VADC_VXM(vadc_vxm_b, uint8_t, H1, DO_VADC) | ||
303 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
304 | uint32_t vm = vext_vm(desc); \ | ||
305 | uint32_t i; \ | ||
306 | \ | ||
307 | - for (i = 0; i < vl; i++) { \ | ||
308 | + for (i = env->vstart; i < vl; i++) { \ | ||
309 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
310 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
311 | ETYPE carry = !vm && vext_elem_mask(v0, i); \ | ||
312 | vext_set_elem_mask(vd, i, DO_OP(s2, s1, carry)); \ | ||
313 | } \ | ||
314 | + env->vstart = 0; \ | ||
315 | } | ||
316 | |||
317 | GEN_VEXT_VMADC_VVM(vmadc_vvm_b, uint8_t, H1, DO_MADC) | ||
318 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
319 | uint32_t vm = vext_vm(desc); \ | ||
320 | uint32_t i; \ | ||
321 | \ | ||
322 | - for (i = 0; i < vl; i++) { \ | ||
323 | + for (i = env->vstart; i < vl; i++) { \ | ||
324 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
325 | ETYPE carry = !vm && vext_elem_mask(v0, i); \ | ||
326 | vext_set_elem_mask(vd, i, \ | ||
327 | DO_OP(s2, (ETYPE)(target_long)s1, carry)); \ | ||
328 | } \ | ||
329 | + env->vstart = 0; \ | ||
330 | } | ||
331 | |||
332 | GEN_VEXT_VMADC_VXM(vmadc_vxm_b, uint8_t, H1, DO_MADC) | ||
333 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
334 | uint32_t vl = env->vl; \ | ||
335 | uint32_t i; \ | ||
336 | \ | ||
337 | - for (i = 0; i < vl; i++) { \ | ||
338 | + for (i = env->vstart; i < vl; i++) { \ | ||
339 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
340 | continue; \ | ||
341 | } \ | ||
342 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
343 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
344 | *((TS1 *)vd + HS1(i)) = OP(s2, s1 & MASK); \ | ||
345 | } \ | ||
346 | + env->vstart = 0; \ | ||
347 | } | ||
348 | |||
349 | GEN_VEXT_SHIFT_VV(vsll_vv_b, uint8_t, uint8_t, H1, H1, DO_SLL, 0x7) | ||
350 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
351 | uint32_t vl = env->vl; \ | ||
352 | uint32_t i; \ | ||
353 | \ | ||
354 | - for (i = 0; i < vl; i++) { \ | ||
355 | + for (i = env->vstart; i < vl; i++) { \ | ||
356 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
357 | continue; \ | ||
358 | } \ | ||
359 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
360 | *((TD *)vd + HD(i)) = OP(s2, s1 & MASK); \ | ||
361 | } \ | ||
362 | + env->vstart = 0; \ | ||
363 | } | ||
364 | |||
365 | GEN_VEXT_SHIFT_VX(vsll_vx_b, uint8_t, int8_t, H1, H1, DO_SLL, 0x7) | ||
366 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
367 | uint32_t vl = env->vl; \ | ||
368 | uint32_t i; \ | ||
369 | \ | ||
370 | - for (i = 0; i < vl; i++) { \ | ||
371 | + for (i = env->vstart; i < vl; i++) { \ | ||
372 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
373 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
374 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
375 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
376 | } \ | ||
377 | vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \ | ||
378 | } \ | ||
379 | + env->vstart = 0; \ | ||
380 | } | ||
381 | |||
382 | GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t, H1, DO_MSEQ) | ||
383 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
384 | uint32_t vl = env->vl; \ | ||
385 | uint32_t i; \ | ||
386 | \ | ||
387 | - for (i = 0; i < vl; i++) { \ | ||
388 | + for (i = env->vstart; i < vl; i++) { \ | ||
389 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
390 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
391 | continue; \ | ||
392 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
393 | vext_set_elem_mask(vd, i, \ | ||
394 | DO_OP(s2, (ETYPE)(target_long)s1)); \ | ||
395 | } \ | ||
396 | + env->vstart = 0; \ | ||
397 | } | ||
398 | |||
399 | GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t, H1, DO_MSEQ) | ||
400 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env, \ | ||
401 | uint32_t vl = env->vl; \ | ||
402 | uint32_t i; \ | ||
403 | \ | ||
404 | - for (i = 0; i < vl; i++) { \ | ||
405 | + for (i = env->vstart; i < vl; i++) { \ | ||
406 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
407 | *((ETYPE *)vd + H(i)) = s1; \ | ||
408 | } \ | ||
409 | + env->vstart = 0; \ | ||
410 | } | ||
411 | |||
412 | GEN_VEXT_VMV_VV(vmv_v_v_b, int8_t, H1) | ||
413 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env, \ | ||
414 | uint32_t vl = env->vl; \ | ||
415 | uint32_t i; \ | ||
416 | \ | ||
417 | - for (i = 0; i < vl; i++) { \ | ||
418 | + for (i = env->vstart; i < vl; i++) { \ | ||
419 | *((ETYPE *)vd + H(i)) = (ETYPE)s1; \ | ||
420 | } \ | ||
421 | + env->vstart = 0; \ | ||
422 | } | ||
423 | |||
424 | GEN_VEXT_VMV_VX(vmv_v_x_b, int8_t, H1) | ||
425 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
426 | uint32_t vl = env->vl; \ | ||
427 | uint32_t i; \ | ||
428 | \ | ||
429 | - for (i = 0; i < vl; i++) { \ | ||
430 | + for (i = env->vstart; i < vl; i++) { \ | ||
431 | ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1); \ | ||
432 | *((ETYPE *)vd + H(i)) = *(vt + H(i)); \ | ||
433 | } \ | ||
434 | + env->vstart = 0; \ | ||
435 | } | ||
436 | |||
437 | GEN_VEXT_VMERGE_VV(vmerge_vvm_b, int8_t, H1) | ||
438 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
439 | uint32_t vl = env->vl; \ | ||
440 | uint32_t i; \ | ||
441 | \ | ||
442 | - for (i = 0; i < vl; i++) { \ | ||
443 | + for (i = env->vstart; i < vl; i++) { \ | ||
444 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
445 | ETYPE d = (!vext_elem_mask(v0, i) ? s2 : \ | ||
446 | (ETYPE)(target_long)s1); \ | ||
447 | *((ETYPE *)vd + H(i)) = d; \ | ||
448 | } \ | ||
449 | + env->vstart = 0; \ | ||
450 | } | ||
451 | |||
452 | GEN_VEXT_VMERGE_VX(vmerge_vxm_b, int8_t, H1) | ||
453 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2, | ||
454 | uint32_t vl, uint32_t vm, int vxrm, | ||
455 | opivv2_rm_fn *fn) | ||
456 | { | ||
457 | - for (uint32_t i = 0; i < vl; i++) { | ||
458 | + for (uint32_t i = env->vstart; i < vl; i++) { | ||
459 | if (!vm && !vext_elem_mask(v0, i)) { | ||
460 | continue; | ||
461 | } | ||
462 | fn(vd, vs1, vs2, i, env, vxrm); | ||
463 | } | ||
464 | + env->vstart = 0; | ||
465 | } | ||
466 | |||
467 | static inline void | ||
468 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, | ||
469 | uint32_t vl, uint32_t vm, int vxrm, | ||
470 | opivx2_rm_fn *fn) | ||
471 | { | ||
472 | - for (uint32_t i = 0; i < vl; i++) { | ||
473 | + for (uint32_t i = env->vstart; i < vl; i++) { | ||
474 | if (!vm && !vext_elem_mask(v0, i)) { | ||
475 | continue; | ||
476 | } | ||
477 | fn(vd, s1, vs2, i, env, vxrm); | ||
478 | } | ||
479 | + env->vstart = 0; | ||
480 | } | ||
481 | |||
482 | static inline void | ||
483 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
484 | uint32_t vl = env->vl; \ | ||
485 | uint32_t i; \ | ||
486 | \ | ||
487 | - for (i = 0; i < vl; i++) { \ | ||
488 | + for (i = env->vstart; i < vl; i++) { \ | ||
489 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
490 | continue; \ | ||
491 | } \ | ||
492 | do_##NAME(vd, vs1, vs2, i, env); \ | ||
493 | } \ | ||
494 | + env->vstart = 0; \ | ||
495 | } | ||
496 | |||
497 | RVVCALL(OPFVV2, vfadd_vv_h, OP_UUU_H, H2, H2, H2, float16_add) | ||
498 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
499 | uint32_t vl = env->vl; \ | ||
500 | uint32_t i; \ | ||
501 | \ | ||
502 | - for (i = 0; i < vl; i++) { \ | ||
503 | + for (i = env->vstart; i < vl; i++) { \ | ||
504 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
505 | continue; \ | ||
506 | } \ | ||
507 | do_##NAME(vd, s1, vs2, i, env); \ | ||
508 | } \ | ||
509 | + env->vstart = 0; \ | ||
510 | } | ||
511 | |||
512 | RVVCALL(OPFVF2, vfadd_vf_h, OP_UUU_H, H2, H2, float16_add) | ||
513 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
514 | if (vl == 0) { \ | ||
515 | return; \ | ||
516 | } \ | ||
517 | - for (i = 0; i < vl; i++) { \ | ||
518 | + for (i = env->vstart; i < vl; i++) { \ | ||
519 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
520 | continue; \ | ||
521 | } \ | ||
522 | do_##NAME(vd, vs2, i, env); \ | ||
523 | } \ | ||
524 | + env->vstart = 0; \ | ||
525 | } | ||
526 | |||
527 | RVVCALL(OPFVV1, vfsqrt_v_h, OP_UU_H, H2, H2, float16_sqrt) | ||
528 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
529 | uint32_t vl = env->vl; \ | ||
530 | uint32_t i; \ | ||
531 | \ | ||
532 | - for (i = 0; i < vl; i++) { \ | ||
533 | + for (i = env->vstart; i < vl; i++) { \ | ||
534 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
535 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
536 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
537 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
538 | vext_set_elem_mask(vd, i, \ | ||
539 | DO_OP(s2, s1, &env->fp_status)); \ | ||
540 | } \ | ||
541 | + env->vstart = 0; \ | ||
542 | } | ||
543 | |||
544 | GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet) | ||
545 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
546 | uint32_t vl = env->vl; \ | ||
547 | uint32_t i; \ | ||
548 | \ | ||
549 | - for (i = 0; i < vl; i++) { \ | ||
550 | + for (i = env->vstart; i < vl; i++) { \ | ||
551 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
552 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
553 | continue; \ | ||
554 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
555 | vext_set_elem_mask(vd, i, \ | ||
556 | DO_OP(s2, (ETYPE)s1, &env->fp_status)); \ | ||
557 | } \ | ||
558 | + env->vstart = 0; \ | ||
559 | } | ||
560 | |||
561 | GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet) | ||
562 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
563 | uint32_t vl = env->vl; \ | ||
564 | uint32_t i; \ | ||
565 | \ | ||
566 | - for (i = 0; i < vl; i++) { \ | ||
567 | + for (i = env->vstart; i < vl; i++) { \ | ||
568 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
569 | continue; \ | ||
570 | } \ | ||
571 | do_##NAME(vd, vs2, i); \ | ||
572 | } \ | ||
573 | + env->vstart = 0; \ | ||
574 | } | ||
575 | |||
576 | target_ulong fclass_h(uint64_t frs1) | ||
577 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
578 | uint32_t vl = env->vl; \ | ||
579 | uint32_t i; \ | ||
580 | \ | ||
581 | - for (i = 0; i < vl; i++) { \ | ||
582 | + for (i = env->vstart; i < vl; i++) { \ | ||
583 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
584 | *((ETYPE *)vd + H(i)) \ | ||
585 | = (!vm && !vext_elem_mask(v0, i) ? s2 : s1); \ | ||
586 | } \ | ||
587 | + env->vstart = 0; \ | ||
588 | } | ||
589 | |||
590 | GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2) | ||
591 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
592 | uint32_t i; \ | ||
593 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
594 | \ | ||
595 | - for (i = 0; i < vl; i++) { \ | ||
596 | + for (i = env->vstart; i < vl; i++) { \ | ||
597 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
598 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
599 | continue; \ | ||
600 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
601 | s1 = OP(s1, (TD)s2); \ | ||
602 | } \ | ||
603 | *((TD *)vd + HD(0)) = s1; \ | ||
604 | + env->vstart = 0; \ | ||
605 | } | ||
606 | |||
607 | /* vd[0] = sum(vs1[0], vs2[*]) */ | ||
608 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
609 | uint32_t i; \ | ||
610 | TD s1 = *((TD *)vs1 + HD(0)); \ | ||
611 | \ | ||
612 | - for (i = 0; i < vl; i++) { \ | ||
613 | + for (i = env->vstart; i < vl; i++) { \ | ||
614 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
615 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
616 | continue; \ | ||
617 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
618 | s1 = OP(s1, (TD)s2, &env->fp_status); \ | ||
619 | } \ | ||
620 | *((TD *)vd + HD(0)) = s1; \ | ||
621 | + env->vstart = 0; \ | ||
622 | } | ||
623 | |||
624 | /* Unordered sum */ | ||
625 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
626 | uint32_t i; | ||
627 | uint32_t s1 = *((uint32_t *)vs1 + H4(0)); | ||
628 | |||
629 | - for (i = 0; i < vl; i++) { | ||
630 | + for (i = env->vstart; i < vl; i++) { | ||
631 | uint16_t s2 = *((uint16_t *)vs2 + H2(i)); | ||
632 | if (!vm && !vext_elem_mask(v0, i)) { | ||
633 | continue; | ||
634 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1, | ||
635 | &env->fp_status); | ||
636 | } | ||
637 | *((uint32_t *)vd + H4(0)) = s1; | ||
638 | + env->vstart = 0; | ||
639 | } | ||
640 | |||
641 | void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
642 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
643 | uint32_t i; | ||
644 | uint64_t s1 = *((uint64_t *)vs1); | ||
645 | |||
646 | - for (i = 0; i < vl; i++) { | ||
647 | + for (i = env->vstart; i < vl; i++) { | ||
648 | uint32_t s2 = *((uint32_t *)vs2 + H4(i)); | ||
649 | if (!vm && !vext_elem_mask(v0, i)) { | ||
650 | continue; | ||
651 | @@ -XXX,XX +XXX,XX @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1, | ||
652 | &env->fp_status); | ||
653 | } | ||
654 | *((uint64_t *)vd) = s1; | ||
655 | + env->vstart = 0; | ||
656 | } | ||
657 | |||
658 | /* | ||
659 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
660 | uint32_t i; \ | ||
661 | int a, b; \ | ||
662 | \ | ||
663 | - for (i = 0; i < vl; i++) { \ | ||
664 | + for (i = env->vstart; i < vl; i++) { \ | ||
665 | a = vext_elem_mask(vs1, i); \ | ||
666 | b = vext_elem_mask(vs2, i); \ | ||
667 | vext_set_elem_mask(vd, i, OP(b, a)); \ | ||
668 | } \ | ||
669 | + env->vstart = 0; \ | ||
670 | } | ||
671 | |||
672 | #define DO_NAND(N, M) (!(N & M)) | ||
673 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env, | ||
674 | uint32_t vl = env->vl; | ||
675 | int i; | ||
676 | |||
677 | - for (i = 0; i < vl; i++) { | ||
678 | + for (i = env->vstart; i < vl; i++) { | ||
679 | if (vm || vext_elem_mask(v0, i)) { | ||
680 | if (vext_elem_mask(vs2, i)) { | ||
681 | cnt++; | ||
26 | } | 682 | } |
27 | } | 683 | } |
28 | } | 684 | } |
685 | + env->vstart = 0; | ||
686 | return cnt; | ||
687 | } | ||
688 | |||
689 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vfirst_m)(void *v0, void *vs2, CPURISCVState *env, | ||
690 | uint32_t vl = env->vl; | ||
691 | int i; | ||
692 | |||
693 | - for (i = 0; i < vl; i++) { | ||
694 | + for (i = env->vstart; i < vl; i++) { | ||
695 | if (vm || vext_elem_mask(v0, i)) { | ||
696 | if (vext_elem_mask(vs2, i)) { | ||
697 | return i; | ||
698 | } | ||
699 | } | ||
700 | } | ||
701 | + env->vstart = 0; | ||
702 | return -1LL; | ||
703 | } | ||
704 | |||
705 | @@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
706 | int i; | ||
707 | bool first_mask_bit = false; | ||
708 | |||
709 | - for (i = 0; i < vl; i++) { | ||
710 | + for (i = env->vstart; i < vl; i++) { | ||
711 | if (!vm && !vext_elem_mask(v0, i)) { | ||
712 | continue; | ||
713 | } | ||
714 | @@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | + env->vstart = 0; | ||
719 | } | ||
720 | |||
721 | void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
722 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
723 | uint32_t sum = 0; \ | ||
724 | int i; \ | ||
725 | \ | ||
726 | - for (i = 0; i < vl; i++) { \ | ||
727 | + for (i = env->vstart; i < vl; i++) { \ | ||
728 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
729 | continue; \ | ||
730 | } \ | ||
731 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
732 | sum++; \ | ||
733 | } \ | ||
734 | } \ | ||
735 | + env->vstart = 0; \ | ||
736 | } | ||
737 | |||
738 | GEN_VEXT_VIOTA_M(viota_m_b, uint8_t, H1) | ||
739 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
740 | uint32_t vl = env->vl; \ | ||
741 | int i; \ | ||
742 | \ | ||
743 | - for (i = 0; i < vl; i++) { \ | ||
744 | + for (i = env->vstart; i < vl; i++) { \ | ||
745 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
746 | continue; \ | ||
747 | } \ | ||
748 | *((ETYPE *)vd + H(i)) = i; \ | ||
749 | } \ | ||
750 | + env->vstart = 0; \ | ||
751 | } | ||
752 | |||
753 | GEN_VEXT_VID_V(vid_v_b, uint8_t, H1) | ||
754 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
755 | { \ | ||
756 | uint32_t vm = vext_vm(desc); \ | ||
757 | uint32_t vl = env->vl; \ | ||
758 | - target_ulong offset = s1, i; \ | ||
759 | + target_ulong offset = s1, i_min, i; \ | ||
760 | \ | ||
761 | - for (i = offset; i < vl; i++) { \ | ||
762 | + i_min = MAX(env->vstart, offset); \ | ||
763 | + for (i = i_min; i < vl; i++) { \ | ||
764 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
765 | continue; \ | ||
766 | } \ | ||
767 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
768 | uint32_t vl = env->vl; \ | ||
769 | target_ulong i_max, i; \ | ||
770 | \ | ||
771 | - i_max = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \ | ||
772 | - for (i = 0; i < i_max; ++i) { \ | ||
773 | + i_max = MAX(MIN(s1 < vlmax ? vlmax - s1 : 0, vl), env->vstart); \ | ||
774 | + for (i = env->vstart; i < i_max; ++i) { \ | ||
775 | if (vm || vext_elem_mask(v0, i)) { \ | ||
776 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \ | ||
777 | } \ | ||
778 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
779 | *((ETYPE *)vd + H(i)) = 0; \ | ||
780 | } \ | ||
781 | } \ | ||
782 | + \ | ||
783 | + env->vstart = 0; \ | ||
784 | } | ||
785 | |||
786 | /* vslidedown.vx vd, vs2, rs1, vm # vd[i] = vs2[i+rs1] */ | ||
787 | @@ -XXX,XX +XXX,XX @@ static void vslide1up_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
788 | uint32_t vl = env->vl; \ | ||
789 | uint32_t i; \ | ||
790 | \ | ||
791 | - for (i = 0; i < vl; i++) { \ | ||
792 | + for (i = env->vstart; i < vl; i++) { \ | ||
793 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
794 | continue; \ | ||
795 | } \ | ||
796 | @@ -XXX,XX +XXX,XX @@ static void vslide1up_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
797 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1)); \ | ||
798 | } \ | ||
799 | } \ | ||
800 | + env->vstart = 0; \ | ||
801 | } | ||
802 | |||
803 | GEN_VEXT_VSLIE1UP(8, H1) | ||
804 | @@ -XXX,XX +XXX,XX @@ static void vslide1down_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
805 | uint32_t vl = env->vl; \ | ||
806 | uint32_t i; \ | ||
807 | \ | ||
808 | - for (i = 0; i < vl; i++) { \ | ||
809 | + for (i = env->vstart; i < vl; i++) { \ | ||
810 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
811 | continue; \ | ||
812 | } \ | ||
813 | @@ -XXX,XX +XXX,XX @@ static void vslide1down_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
814 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1)); \ | ||
815 | } \ | ||
816 | } \ | ||
817 | + env->vstart = 0; \ | ||
818 | } | ||
819 | |||
820 | GEN_VEXT_VSLIDE1DOWN(8, H1) | ||
821 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_d, 64) | ||
822 | void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
823 | CPURISCVState *env, uint32_t desc) \ | ||
824 | { \ | ||
825 | - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS1))); \ | ||
826 | + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS2))); \ | ||
827 | uint32_t vm = vext_vm(desc); \ | ||
828 | uint32_t vl = env->vl; \ | ||
829 | uint64_t index; \ | ||
830 | uint32_t i; \ | ||
831 | \ | ||
832 | - for (i = 0; i < vl; i++) { \ | ||
833 | + for (i = env->vstart; i < vl; i++) { \ | ||
834 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
835 | continue; \ | ||
836 | } \ | ||
837 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
838 | *((TS2 *)vd + HS2(i)) = *((TS2 *)vs2 + HS2(index)); \ | ||
839 | } \ | ||
840 | } \ | ||
841 | + env->vstart = 0; \ | ||
842 | } | ||
843 | |||
844 | /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */ | ||
845 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
846 | uint64_t index = s1; \ | ||
847 | uint32_t i; \ | ||
848 | \ | ||
849 | - for (i = 0; i < vl; i++) { \ | ||
850 | + for (i = env->vstart; i < vl; i++) { \ | ||
851 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
852 | continue; \ | ||
853 | } \ | ||
854 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
855 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ | ||
856 | } \ | ||
857 | } \ | ||
858 | + env->vstart = 0; \ | ||
859 | } | ||
860 | |||
861 | /* vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[rs1] */ | ||
862 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
863 | uint32_t vl = env->vl; \ | ||
864 | uint32_t num = 0, i; \ | ||
865 | \ | ||
866 | - for (i = 0; i < vl; i++) { \ | ||
867 | + for (i = env->vstart; i < vl; i++) { \ | ||
868 | if (!vext_elem_mask(vs1, i)) { \ | ||
869 | continue; \ | ||
870 | } \ | ||
871 | *((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i)); \ | ||
872 | num++; \ | ||
873 | } \ | ||
874 | + env->vstart = 0; \ | ||
875 | } | ||
876 | |||
877 | /* Compress into vd elements of vs2 where vs1 is enabled */ | ||
878 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_h, uint16_t, H2) | ||
879 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4) | ||
880 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8) | ||
881 | |||
882 | +/* Vector Whole Register Move */ | ||
883 | +#define GEN_VEXT_VMV_WHOLE(NAME, LEN) \ | ||
884 | +void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \ | ||
885 | + uint32_t desc) \ | ||
886 | +{ \ | ||
887 | + /* EEW = 8 */ \ | ||
888 | + uint32_t maxsz = simd_maxsz(desc); \ | ||
889 | + uint32_t i = env->vstart; \ | ||
890 | + \ | ||
891 | + memcpy((uint8_t *)vd + H1(i), \ | ||
892 | + (uint8_t *)vs2 + H1(i), \ | ||
893 | + maxsz - env->vstart); \ | ||
894 | + \ | ||
895 | + env->vstart = 0; \ | ||
896 | +} | ||
897 | + | ||
898 | +GEN_VEXT_VMV_WHOLE(vmv1r_v, 1) | ||
899 | +GEN_VEXT_VMV_WHOLE(vmv2r_v, 2) | ||
900 | +GEN_VEXT_VMV_WHOLE(vmv4r_v, 4) | ||
901 | +GEN_VEXT_VMV_WHOLE(vmv8r_v, 8) | ||
902 | + | ||
903 | /* Vector Integer Extension */ | ||
904 | #define GEN_VEXT_INT_EXT(NAME, ETYPE, DTYPE, HD, HS1) \ | ||
905 | void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
906 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
907 | uint32_t vm = vext_vm(desc); \ | ||
908 | uint32_t i; \ | ||
909 | \ | ||
910 | - for (i = 0; i < vl; i++) { \ | ||
911 | + for (i = env->vstart; i < vl; i++) { \ | ||
912 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
913 | continue; \ | ||
914 | } \ | ||
915 | *((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i)); \ | ||
916 | } \ | ||
917 | + env->vstart = 0; \ | ||
918 | } | ||
919 | |||
920 | GEN_VEXT_INT_EXT(vzext_vf2_h, uint16_t, uint8_t, H2, H1) | ||
921 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
922 | index XXXXXXX..XXXXXXX 100644 | ||
923 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
924 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
925 | @@ -XXX,XX +XXX,XX @@ static bool vext_check_sds(DisasContext *s, int vd, int vs1, int vs2, int vm) | ||
926 | */ | ||
927 | static bool vext_check_reduction(DisasContext *s, int vs2) | ||
928 | { | ||
929 | - return require_align(vs2, s->lmul); | ||
930 | + return require_align(vs2, s->lmul) && (s->vstart == 0); | ||
931 | } | ||
932 | |||
933 | /* | ||
934 | @@ -XXX,XX +XXX,XX @@ GEN_MM_TRANS(vmxnor_mm) | ||
935 | static bool trans_vcpop_m(DisasContext *s, arg_rmr *a) | ||
936 | { | ||
937 | if (require_rvv(s) && | ||
938 | - vext_check_isa_ill(s)) { | ||
939 | + vext_check_isa_ill(s) && | ||
940 | + s->vstart == 0) { | ||
941 | TCGv_ptr src2, mask; | ||
942 | TCGv dst; | ||
943 | TCGv_i32 desc; | ||
944 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a) | ||
945 | static bool trans_vfirst_m(DisasContext *s, arg_rmr *a) | ||
946 | { | ||
947 | if (require_rvv(s) && | ||
948 | - vext_check_isa_ill(s)) { | ||
949 | + vext_check_isa_ill(s) && | ||
950 | + s->vstart == 0) { | ||
951 | TCGv_ptr src2, mask; | ||
952 | TCGv dst; | ||
953 | TCGv_i32 desc; | ||
954 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
955 | if (require_rvv(s) && \ | ||
956 | vext_check_isa_ill(s) && \ | ||
957 | require_vm(a->vm, a->rd) && \ | ||
958 | - (a->rd != a->rs2)) { \ | ||
959 | + (a->rd != a->rs2) && \ | ||
960 | + (s->vstart == 0)) { \ | ||
961 | uint32_t data = 0; \ | ||
962 | gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \ | ||
963 | TCGLabel *over = gen_new_label(); \ | ||
964 | @@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
965 | vext_check_isa_ill(s) && | ||
966 | !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) && | ||
967 | require_vm(a->vm, a->rd) && | ||
968 | - require_align(a->rd, s->lmul)) { | ||
969 | + require_align(a->rd, s->lmul) && | ||
970 | + (s->vstart == 0)) { | ||
971 | uint32_t data = 0; | ||
972 | TCGLabel *over = gen_new_label(); | ||
973 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
974 | @@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) | ||
975 | TCGLabel *over = gen_new_label(); | ||
976 | |||
977 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
978 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
979 | |||
980 | t1 = tcg_temp_new_i64(); | ||
981 | |||
982 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
983 | TCGv_i64 t1; | ||
984 | TCGLabel *over = gen_new_label(); | ||
985 | |||
986 | - /* if vl == 0, skip vector register write back */ | ||
987 | + /* if vl == 0 or vstart >= vl, skip vector register write back */ | ||
988 | tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); | ||
989 | + tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); | ||
990 | |||
991 | /* NaN-box f[rs1] */ | ||
992 | t1 = tcg_temp_new_i64(); | ||
993 | @@ -XXX,XX +XXX,XX @@ static bool vcompress_vm_check(DisasContext *s, arg_r *a) | ||
994 | require_align(a->rd, s->lmul) && | ||
995 | require_align(a->rs2, s->lmul) && | ||
996 | (a->rd != a->rs2) && | ||
997 | - !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs1, 1); | ||
998 | + !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs1, 1) && | ||
999 | + (s->vstart == 0); | ||
1000 | } | ||
1001 | |||
1002 | static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
1003 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | ||
1004 | * Whole Vector Register Move Instructions ignore vtype and vl setting. | ||
1005 | * Thus, we don't need to check vill bit. (Section 16.6) | ||
1006 | */ | ||
1007 | -#define GEN_VMV_WHOLE_TRANS(NAME, LEN) \ | ||
1008 | -static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
1009 | -{ \ | ||
1010 | - if (require_rvv(s) && \ | ||
1011 | - QEMU_IS_ALIGNED(a->rd, LEN) && \ | ||
1012 | - QEMU_IS_ALIGNED(a->rs2, LEN)) { \ | ||
1013 | - /* EEW = 8 */ \ | ||
1014 | - tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd), \ | ||
1015 | - vreg_ofs(s, a->rs2), \ | ||
1016 | - s->vlen / 8 * LEN, s->vlen / 8 * LEN); \ | ||
1017 | - mark_vs_dirty(s); \ | ||
1018 | - return true; \ | ||
1019 | - } \ | ||
1020 | - return false; \ | ||
29 | -} | 1021 | -} |
30 | - | 1022 | - |
31 | -static void sifive_u_otp_reset(DeviceState *dev) | 1023 | -GEN_VMV_WHOLE_TRANS(vmv1r_v, 1) |
32 | -{ | 1024 | -GEN_VMV_WHOLE_TRANS(vmv2r_v, 2) |
33 | - SiFiveUOTPState *s = SIFIVE_U_OTP(dev); | 1025 | -GEN_VMV_WHOLE_TRANS(vmv4r_v, 4) |
34 | 1026 | -GEN_VMV_WHOLE_TRANS(vmv8r_v, 8) | |
35 | /* Initialize all fuses' initial value to 0xFFs */ | 1027 | +#define GEN_VMV_WHOLE_TRANS(NAME, LEN, SEQ) \ |
36 | memset(s->fuse, 0xff, sizeof(s->fuse)); | 1028 | +static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ |
37 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev) | 1029 | +{ \ |
38 | serial_data = s->serial; | 1030 | + if (require_rvv(s) && \ |
39 | if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, | 1031 | + QEMU_IS_ALIGNED(a->rd, LEN) && \ |
40 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | 1032 | + QEMU_IS_ALIGNED(a->rs2, LEN)) { \ |
41 | - error_report("write error index<%d>", index); | 1033 | + uint32_t maxsz = (s->vlen >> 3) * LEN; \ |
42 | + error_setg(errp, "failed to write index<%d>", index); | 1034 | + if (s->vstart == 0) { \ |
43 | + return; | 1035 | + /* EEW = 8 */ \ |
44 | } | 1036 | + tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd), \ |
45 | 1037 | + vreg_ofs(s, a->rs2), maxsz, maxsz); \ | |
46 | serial_data = ~(s->serial); | 1038 | + mark_vs_dirty(s); \ |
47 | if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, | 1039 | + } else { \ |
48 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | 1040 | + TCGLabel *over = gen_new_label(); \ |
49 | - error_report("write error index<%d>", index + 1); | 1041 | + tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \ |
50 | + error_setg(errp, "failed to write index<%d>", index + 1); | 1042 | + \ |
51 | + return; | 1043 | + static gen_helper_gvec_2_ptr * const fns[4] = { \ |
52 | } | 1044 | + gen_helper_vmv1r_v, gen_helper_vmv2r_v, \ |
53 | } | 1045 | + gen_helper_vmv4r_v, gen_helper_vmv8r_v, \ |
54 | 1046 | + }; \ | |
55 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data) | 1047 | + tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \ |
56 | 1048 | + cpu_env, maxsz, maxsz, 0, fns[SEQ]); \ | |
57 | device_class_set_props(dc, sifive_u_otp_properties); | 1049 | + mark_vs_dirty(s); \ |
58 | dc->realize = sifive_u_otp_realize; | 1050 | + gen_set_label(over); \ |
59 | - dc->reset = sifive_u_otp_reset; | 1051 | + } \ |
60 | } | 1052 | + return true; \ |
61 | 1053 | + } \ | |
62 | static const TypeInfo sifive_u_otp_info = { | 1054 | + return false; \ |
1055 | +} | ||
1056 | + | ||
1057 | +GEN_VMV_WHOLE_TRANS(vmv1r_v, 1, 0) | ||
1058 | +GEN_VMV_WHOLE_TRANS(vmv2r_v, 2, 1) | ||
1059 | +GEN_VMV_WHOLE_TRANS(vmv4r_v, 4, 2) | ||
1060 | +GEN_VMV_WHOLE_TRANS(vmv8r_v, 8, 3) | ||
1061 | |||
1062 | static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div) | ||
1063 | { | ||
63 | -- | 1064 | -- |
64 | 2.31.1 | 1065 | 2.31.1 |
65 | 1066 | ||
66 | 1067 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | If the frm field contains an invalid rounding mode (101-111), | ||
4 | attempting to execute any vector floating-point instruction, even | ||
5 | those that do not depend on the rounding mode, will raise an illegal | ||
6 | instruction exception. | ||
7 | |||
8 | Call gen_set_rm() with DYN rounding mode to check and trigger illegal | ||
9 | instruction exception if frm field contains invalid value at run-time | ||
10 | for vector floating-point instructions. | ||
11 | |||
12 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Message-Id: <20211210075704.23951-68-frank.chang@sifive.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | target/riscv/insn_trans/trans_rvv.c.inc | 22 ++++++++++++++++++++++ | ||
18 | 1 file changed, 22 insertions(+) | ||
19 | |||
20 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
23 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
24 | @@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a, | ||
25 | int rm) | ||
26 | { | ||
27 | if (checkfn(s, a)) { | ||
28 | + if (rm != RISCV_FRM_DYN) { | ||
29 | + gen_set_rm(s, RISCV_FRM_DYN); | ||
30 | + } | ||
31 | + | ||
32 | uint32_t data = 0; | ||
33 | TCGLabel *over = gen_new_label(); | ||
34 | gen_set_rm(s, rm); | ||
35 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
36 | require_rvf(s) && | ||
37 | vext_check_isa_ill(s) && | ||
38 | require_align(a->rd, s->lmul)) { | ||
39 | + gen_set_rm(s, RISCV_FRM_DYN); | ||
40 | + | ||
41 | TCGv_i64 t1; | ||
42 | |||
43 | if (s->vl_eq_vlmax) { | ||
44 | @@ -XXX,XX +XXX,XX @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a) | ||
45 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
46 | { \ | ||
47 | if (opfv_widen_check(s, a)) { \ | ||
48 | + if (FRM != RISCV_FRM_DYN) { \ | ||
49 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
50 | + } \ | ||
51 | + \ | ||
52 | uint32_t data = 0; \ | ||
53 | static gen_helper_gvec_3_ptr * const fns[2] = { \ | ||
54 | gen_helper_##HELPER##_h, \ | ||
55 | @@ -XXX,XX +XXX,XX @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
56 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
57 | { \ | ||
58 | if (opfv_narrow_check(s, a)) { \ | ||
59 | + if (FRM != RISCV_FRM_DYN) { \ | ||
60 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
61 | + } \ | ||
62 | + \ | ||
63 | uint32_t data = 0; \ | ||
64 | static gen_helper_gvec_3_ptr * const fns[2] = { \ | ||
65 | gen_helper_##HELPER##_h, \ | ||
66 | @@ -XXX,XX +XXX,XX @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a) | ||
67 | static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
68 | { \ | ||
69 | if (opxfv_narrow_check(s, a)) { \ | ||
70 | + if (FRM != RISCV_FRM_DYN) { \ | ||
71 | + gen_set_rm(s, RISCV_FRM_DYN); \ | ||
72 | + } \ | ||
73 | + \ | ||
74 | uint32_t data = 0; \ | ||
75 | static gen_helper_gvec_3_ptr * const fns[3] = { \ | ||
76 | gen_helper_##HELPER##_b, \ | ||
77 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) | ||
78 | if (require_rvv(s) && | ||
79 | require_rvf(s) && | ||
80 | vext_check_isa_ill(s)) { | ||
81 | + gen_set_rm(s, RISCV_FRM_DYN); | ||
82 | + | ||
83 | unsigned int ofs = (8 << s->sew); | ||
84 | unsigned int len = 64 - ofs; | ||
85 | TCGv_i64 t_nan; | ||
86 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) | ||
87 | if (require_rvv(s) && | ||
88 | require_rvf(s) && | ||
89 | vext_check_isa_ill(s)) { | ||
90 | + gen_set_rm(s, RISCV_FRM_DYN); | ||
91 | + | ||
92 | /* The instructions ignore LMUL and vector register group. */ | ||
93 | TCGv_i64 t1; | ||
94 | TCGLabel *over = gen_new_label(); | ||
95 | -- | ||
96 | 2.31.1 | ||
97 | |||
98 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Hsiangkai Wang <kai.wang@sifive.com> | |
2 | |||
3 | Signed-off-by: Hsiangkai Wang <kai.wang@sifive.com> | ||
4 | Signed-off-by: Greentime Hu <greentime.hu@sifive.com> | ||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-69-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 1 + | ||
11 | target/riscv/cpu.c | 2 + | ||
12 | target/riscv/gdbstub.c | 184 +++++++++++++++++++++++++++++++++++++++++ | ||
13 | 3 files changed, 187 insertions(+) | ||
14 | |||
15 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/cpu.h | ||
18 | +++ b/target/riscv/cpu.h | ||
19 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPU { | ||
20 | CPURISCVState env; | ||
21 | |||
22 | char *dyn_csr_xml; | ||
23 | + char *dyn_vreg_xml; | ||
24 | |||
25 | /* Configuration Settings */ | ||
26 | struct { | ||
27 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/riscv/cpu.c | ||
30 | +++ b/target/riscv/cpu.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) | ||
32 | |||
33 | if (strcmp(xmlname, "riscv-csr.xml") == 0) { | ||
34 | return cpu->dyn_csr_xml; | ||
35 | + } else if (strcmp(xmlname, "riscv-vector.xml") == 0) { | ||
36 | + return cpu->dyn_vreg_xml; | ||
37 | } | ||
38 | |||
39 | return NULL; | ||
40 | diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/riscv/gdbstub.c | ||
43 | +++ b/target/riscv/gdbstub.c | ||
44 | @@ -XXX,XX +XXX,XX @@ | ||
45 | #include "exec/gdbstub.h" | ||
46 | #include "cpu.h" | ||
47 | |||
48 | +struct TypeSize { | ||
49 | + const char *gdb_type; | ||
50 | + const char *id; | ||
51 | + int size; | ||
52 | + const char suffix; | ||
53 | +}; | ||
54 | + | ||
55 | +static const struct TypeSize vec_lanes[] = { | ||
56 | + /* quads */ | ||
57 | + { "uint128", "quads", 128, 'q' }, | ||
58 | + /* 64 bit */ | ||
59 | + { "uint64", "longs", 64, 'l' }, | ||
60 | + /* 32 bit */ | ||
61 | + { "uint32", "words", 32, 'w' }, | ||
62 | + /* 16 bit */ | ||
63 | + { "uint16", "shorts", 16, 's' }, | ||
64 | + /* | ||
65 | + * TODO: currently there is no reliable way of telling | ||
66 | + * if the remote gdb actually understands ieee_half so | ||
67 | + * we don't expose it in the target description for now. | ||
68 | + * { "ieee_half", 16, 'h', 'f' }, | ||
69 | + */ | ||
70 | + /* bytes */ | ||
71 | + { "uint8", "bytes", 8, 'b' }, | ||
72 | +}; | ||
73 | + | ||
74 | int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) | ||
75 | { | ||
76 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
77 | @@ -XXX,XX +XXX,XX @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | +/* | ||
82 | + * Convert register index number passed by GDB to the correspond | ||
83 | + * vector CSR number. Vector CSRs are defined after vector registers | ||
84 | + * in dynamic generated riscv-vector.xml, thus the starting register index | ||
85 | + * of vector CSRs is 32. | ||
86 | + * Return 0 if register index number is out of range. | ||
87 | + */ | ||
88 | +static int riscv_gdb_vector_csrno(int num_regs) | ||
89 | +{ | ||
90 | + /* | ||
91 | + * The order of vector CSRs in the switch case | ||
92 | + * should match with the order defined in csr_ops[]. | ||
93 | + */ | ||
94 | + switch (num_regs) { | ||
95 | + case 32: | ||
96 | + return CSR_VSTART; | ||
97 | + case 33: | ||
98 | + return CSR_VXSAT; | ||
99 | + case 34: | ||
100 | + return CSR_VXRM; | ||
101 | + case 35: | ||
102 | + return CSR_VCSR; | ||
103 | + case 36: | ||
104 | + return CSR_VL; | ||
105 | + case 37: | ||
106 | + return CSR_VTYPE; | ||
107 | + case 38: | ||
108 | + return CSR_VLENB; | ||
109 | + default: | ||
110 | + /* Unknown register. */ | ||
111 | + return 0; | ||
112 | + } | ||
113 | +} | ||
114 | + | ||
115 | +static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n) | ||
116 | +{ | ||
117 | + uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3; | ||
118 | + if (n < 32) { | ||
119 | + int i; | ||
120 | + int cnt = 0; | ||
121 | + for (i = 0; i < vlenb; i += 8) { | ||
122 | + cnt += gdb_get_reg64(buf, | ||
123 | + env->vreg[(n * vlenb + i) / 8]); | ||
124 | + } | ||
125 | + return cnt; | ||
126 | + } | ||
127 | + | ||
128 | + int csrno = riscv_gdb_vector_csrno(n); | ||
129 | + | ||
130 | + if (!csrno) { | ||
131 | + return 0; | ||
132 | + } | ||
133 | + | ||
134 | + target_ulong val = 0; | ||
135 | + int result = riscv_csrrw_debug(env, csrno, &val, 0, 0); | ||
136 | + | ||
137 | + if (result == 0) { | ||
138 | + return gdb_get_regl(buf, val); | ||
139 | + } | ||
140 | + | ||
141 | + return 0; | ||
142 | +} | ||
143 | + | ||
144 | +static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n) | ||
145 | +{ | ||
146 | + uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3; | ||
147 | + if (n < 32) { | ||
148 | + int i; | ||
149 | + for (i = 0; i < vlenb; i += 8) { | ||
150 | + env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i); | ||
151 | + } | ||
152 | + return vlenb; | ||
153 | + } | ||
154 | + | ||
155 | + int csrno = riscv_gdb_vector_csrno(n); | ||
156 | + | ||
157 | + if (!csrno) { | ||
158 | + return 0; | ||
159 | + } | ||
160 | + | ||
161 | + target_ulong val = ldtul_p(mem_buf); | ||
162 | + int result = riscv_csrrw_debug(env, csrno, NULL, val, -1); | ||
163 | + | ||
164 | + if (result == 0) { | ||
165 | + return sizeof(target_ulong); | ||
166 | + } | ||
167 | + | ||
168 | + return 0; | ||
169 | +} | ||
170 | + | ||
171 | static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n) | ||
172 | { | ||
173 | if (n < CSR_TABLE_SIZE) { | ||
174 | @@ -XXX,XX +XXX,XX @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg) | ||
175 | return CSR_TABLE_SIZE; | ||
176 | } | ||
177 | |||
178 | +static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg) | ||
179 | +{ | ||
180 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
181 | + GString *s = g_string_new(NULL); | ||
182 | + g_autoptr(GString) ts = g_string_new(""); | ||
183 | + int reg_width = cpu->cfg.vlen; | ||
184 | + int num_regs = 0; | ||
185 | + int i; | ||
186 | + | ||
187 | + g_string_printf(s, "<?xml version=\"1.0\"?>"); | ||
188 | + g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); | ||
189 | + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">"); | ||
190 | + | ||
191 | + /* First define types and totals in a whole VL */ | ||
192 | + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { | ||
193 | + int count = reg_width / vec_lanes[i].size; | ||
194 | + g_string_printf(ts, "%s", vec_lanes[i].id); | ||
195 | + g_string_append_printf(s, | ||
196 | + "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", | ||
197 | + ts->str, vec_lanes[i].gdb_type, count); | ||
198 | + } | ||
199 | + | ||
200 | + /* Define unions */ | ||
201 | + g_string_append_printf(s, "<union id=\"riscv_vector\">"); | ||
202 | + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { | ||
203 | + g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>", | ||
204 | + vec_lanes[i].suffix, | ||
205 | + vec_lanes[i].id); | ||
206 | + } | ||
207 | + g_string_append(s, "</union>"); | ||
208 | + | ||
209 | + /* Define vector registers */ | ||
210 | + for (i = 0; i < 32; i++) { | ||
211 | + g_string_append_printf(s, | ||
212 | + "<reg name=\"v%d\" bitsize=\"%d\"" | ||
213 | + " regnum=\"%d\" group=\"vector\"" | ||
214 | + " type=\"riscv_vector\"/>", | ||
215 | + i, reg_width, base_reg++); | ||
216 | + num_regs++; | ||
217 | + } | ||
218 | + | ||
219 | + /* Define vector CSRs */ | ||
220 | + const char *vector_csrs[7] = { | ||
221 | + "vstart", "vxsat", "vxrm", "vcsr", | ||
222 | + "vl", "vtype", "vlenb" | ||
223 | + }; | ||
224 | + | ||
225 | + for (i = 0; i < 7; i++) { | ||
226 | + g_string_append_printf(s, | ||
227 | + "<reg name=\"%s\" bitsize=\"%d\"" | ||
228 | + " regnum=\"%d\" group=\"vector\"" | ||
229 | + " type=\"int\"/>", | ||
230 | + vector_csrs[i], TARGET_LONG_BITS, base_reg++); | ||
231 | + num_regs++; | ||
232 | + } | ||
233 | + | ||
234 | + g_string_append_printf(s, "</feature>"); | ||
235 | + | ||
236 | + cpu->dyn_vreg_xml = g_string_free(s, false); | ||
237 | + return num_regs; | ||
238 | +} | ||
239 | + | ||
240 | void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) | ||
241 | { | ||
242 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
243 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) | ||
244 | gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu, | ||
245 | 36, "riscv-32bit-fpu.xml", 0); | ||
246 | } | ||
247 | + if (env->misa_ext & RVV) { | ||
248 | + gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector, | ||
249 | + ricsv_gen_dynamic_vector_xml(cs, | ||
250 | + cs->gdb_num_regs), | ||
251 | + "riscv-vector.xml", 0); | ||
252 | + } | ||
253 | #if defined(TARGET_RISCV32) | ||
254 | gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, | ||
255 | 1, "riscv-32bit-virtual.xml", 0); | ||
256 | -- | ||
257 | 2.31.1 | ||
258 | |||
259 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Implement the floating-point reciprocal square-root estimate to 7 bits | ||
4 | instruction. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20211210075704.23951-70-frank.chang@sifive.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/helper.h | 4 + | ||
12 | target/riscv/insn32.decode | 1 + | ||
13 | target/riscv/vector_helper.c | 183 ++++++++++++++++++++++++ | ||
14 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + | ||
15 | 4 files changed, 189 insertions(+) | ||
16 | |||
17 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/helper.h | ||
20 | +++ b/target/riscv/helper.h | ||
21 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32) | ||
22 | DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32) | ||
23 | DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32) | ||
24 | |||
25 | +DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32) | ||
26 | +DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32) | ||
27 | +DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32) | ||
28 | + | ||
29 | DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
31 | DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
32 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/insn32.decode | ||
35 | +++ b/target/riscv/insn32.decode | ||
36 | @@ -XXX,XX +XXX,XX @@ vfwmsac_vf 111110 . ..... ..... 101 ..... 1010111 @r_vm | ||
37 | vfwnmsac_vv 111111 . ..... ..... 001 ..... 1010111 @r_vm | ||
38 | vfwnmsac_vf 111111 . ..... ..... 101 ..... 1010111 @r_vm | ||
39 | vfsqrt_v 010011 . ..... 00000 001 ..... 1010111 @r2_vm | ||
40 | +vfrsqrt7_v 010011 . ..... 00100 001 ..... 1010111 @r2_vm | ||
41 | vfmin_vv 000100 . ..... ..... 001 ..... 1010111 @r_vm | ||
42 | vfmin_vf 000100 . ..... ..... 101 ..... 1010111 @r_vm | ||
43 | vfmax_vv 000110 . ..... ..... 001 ..... 1010111 @r_vm | ||
44 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/target/riscv/vector_helper.c | ||
47 | +++ b/target/riscv/vector_helper.c | ||
48 | @@ -XXX,XX +XXX,XX @@ | ||
49 | |||
50 | #include "qemu/osdep.h" | ||
51 | #include "qemu/host-utils.h" | ||
52 | +#include "qemu/bitops.h" | ||
53 | #include "cpu.h" | ||
54 | #include "exec/memop.h" | ||
55 | #include "exec/exec-all.h" | ||
56 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfsqrt_v_h, 2, 2) | ||
57 | GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4) | ||
58 | GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8) | ||
59 | |||
60 | +/* | ||
61 | + * Vector Floating-Point Reciprocal Square-Root Estimate Instruction | ||
62 | + * | ||
63 | + * Adapted from riscv-v-spec recip.c: | ||
64 | + * https://github.com/riscv/riscv-v-spec/blob/master/recip.c | ||
65 | + */ | ||
66 | +static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size) | ||
67 | +{ | ||
68 | + uint64_t sign = extract64(f, frac_size + exp_size, 1); | ||
69 | + uint64_t exp = extract64(f, frac_size, exp_size); | ||
70 | + uint64_t frac = extract64(f, 0, frac_size); | ||
71 | + | ||
72 | + const uint8_t lookup_table[] = { | ||
73 | + 52, 51, 50, 48, 47, 46, 44, 43, | ||
74 | + 42, 41, 40, 39, 38, 36, 35, 34, | ||
75 | + 33, 32, 31, 30, 30, 29, 28, 27, | ||
76 | + 26, 25, 24, 23, 23, 22, 21, 20, | ||
77 | + 19, 19, 18, 17, 16, 16, 15, 14, | ||
78 | + 14, 13, 12, 12, 11, 10, 10, 9, | ||
79 | + 9, 8, 7, 7, 6, 6, 5, 4, | ||
80 | + 4, 3, 3, 2, 2, 1, 1, 0, | ||
81 | + 127, 125, 123, 121, 119, 118, 116, 114, | ||
82 | + 113, 111, 109, 108, 106, 105, 103, 102, | ||
83 | + 100, 99, 97, 96, 95, 93, 92, 91, | ||
84 | + 90, 88, 87, 86, 85, 84, 83, 82, | ||
85 | + 80, 79, 78, 77, 76, 75, 74, 73, | ||
86 | + 72, 71, 70, 70, 69, 68, 67, 66, | ||
87 | + 65, 64, 63, 63, 62, 61, 60, 59, | ||
88 | + 59, 58, 57, 56, 56, 55, 54, 53 | ||
89 | + }; | ||
90 | + const int precision = 7; | ||
91 | + | ||
92 | + if (exp == 0 && frac != 0) { /* subnormal */ | ||
93 | + /* Normalize the subnormal. */ | ||
94 | + while (extract64(frac, frac_size - 1, 1) == 0) { | ||
95 | + exp--; | ||
96 | + frac <<= 1; | ||
97 | + } | ||
98 | + | ||
99 | + frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size); | ||
100 | + } | ||
101 | + | ||
102 | + int idx = ((exp & 1) << (precision - 1)) | | ||
103 | + (frac >> (frac_size - precision + 1)); | ||
104 | + uint64_t out_frac = (uint64_t)(lookup_table[idx]) << | ||
105 | + (frac_size - precision); | ||
106 | + uint64_t out_exp = (3 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp) / 2; | ||
107 | + | ||
108 | + uint64_t val = 0; | ||
109 | + val = deposit64(val, 0, frac_size, out_frac); | ||
110 | + val = deposit64(val, frac_size, exp_size, out_exp); | ||
111 | + val = deposit64(val, frac_size + exp_size, 1, sign); | ||
112 | + return val; | ||
113 | +} | ||
114 | + | ||
115 | +static float16 frsqrt7_h(float16 f, float_status *s) | ||
116 | +{ | ||
117 | + int exp_size = 5, frac_size = 10; | ||
118 | + bool sign = float16_is_neg(f); | ||
119 | + | ||
120 | + /* | ||
121 | + * frsqrt7(sNaN) = canonical NaN | ||
122 | + * frsqrt7(-inf) = canonical NaN | ||
123 | + * frsqrt7(-normal) = canonical NaN | ||
124 | + * frsqrt7(-subnormal) = canonical NaN | ||
125 | + */ | ||
126 | + if (float16_is_signaling_nan(f, s) || | ||
127 | + (float16_is_infinity(f) && sign) || | ||
128 | + (float16_is_normal(f) && sign) || | ||
129 | + (float16_is_zero_or_denormal(f) && !float16_is_zero(f) && sign)) { | ||
130 | + s->float_exception_flags |= float_flag_invalid; | ||
131 | + return float16_default_nan(s); | ||
132 | + } | ||
133 | + | ||
134 | + /* frsqrt7(qNaN) = canonical NaN */ | ||
135 | + if (float16_is_quiet_nan(f, s)) { | ||
136 | + return float16_default_nan(s); | ||
137 | + } | ||
138 | + | ||
139 | + /* frsqrt7(+-0) = +-inf */ | ||
140 | + if (float16_is_zero(f)) { | ||
141 | + s->float_exception_flags |= float_flag_divbyzero; | ||
142 | + return float16_set_sign(float16_infinity, sign); | ||
143 | + } | ||
144 | + | ||
145 | + /* frsqrt7(+inf) = +0 */ | ||
146 | + if (float16_is_infinity(f) && !sign) { | ||
147 | + return float16_set_sign(float16_zero, sign); | ||
148 | + } | ||
149 | + | ||
150 | + /* +normal, +subnormal */ | ||
151 | + uint64_t val = frsqrt7(f, exp_size, frac_size); | ||
152 | + return make_float16(val); | ||
153 | +} | ||
154 | + | ||
155 | +static float32 frsqrt7_s(float32 f, float_status *s) | ||
156 | +{ | ||
157 | + int exp_size = 8, frac_size = 23; | ||
158 | + bool sign = float32_is_neg(f); | ||
159 | + | ||
160 | + /* | ||
161 | + * frsqrt7(sNaN) = canonical NaN | ||
162 | + * frsqrt7(-inf) = canonical NaN | ||
163 | + * frsqrt7(-normal) = canonical NaN | ||
164 | + * frsqrt7(-subnormal) = canonical NaN | ||
165 | + */ | ||
166 | + if (float32_is_signaling_nan(f, s) || | ||
167 | + (float32_is_infinity(f) && sign) || | ||
168 | + (float32_is_normal(f) && sign) || | ||
169 | + (float32_is_zero_or_denormal(f) && !float32_is_zero(f) && sign)) { | ||
170 | + s->float_exception_flags |= float_flag_invalid; | ||
171 | + return float32_default_nan(s); | ||
172 | + } | ||
173 | + | ||
174 | + /* frsqrt7(qNaN) = canonical NaN */ | ||
175 | + if (float32_is_quiet_nan(f, s)) { | ||
176 | + return float32_default_nan(s); | ||
177 | + } | ||
178 | + | ||
179 | + /* frsqrt7(+-0) = +-inf */ | ||
180 | + if (float32_is_zero(f)) { | ||
181 | + s->float_exception_flags |= float_flag_divbyzero; | ||
182 | + return float32_set_sign(float32_infinity, sign); | ||
183 | + } | ||
184 | + | ||
185 | + /* frsqrt7(+inf) = +0 */ | ||
186 | + if (float32_is_infinity(f) && !sign) { | ||
187 | + return float32_set_sign(float32_zero, sign); | ||
188 | + } | ||
189 | + | ||
190 | + /* +normal, +subnormal */ | ||
191 | + uint64_t val = frsqrt7(f, exp_size, frac_size); | ||
192 | + return make_float32(val); | ||
193 | +} | ||
194 | + | ||
195 | +static float64 frsqrt7_d(float64 f, float_status *s) | ||
196 | +{ | ||
197 | + int exp_size = 11, frac_size = 52; | ||
198 | + bool sign = float64_is_neg(f); | ||
199 | + | ||
200 | + /* | ||
201 | + * frsqrt7(sNaN) = canonical NaN | ||
202 | + * frsqrt7(-inf) = canonical NaN | ||
203 | + * frsqrt7(-normal) = canonical NaN | ||
204 | + * frsqrt7(-subnormal) = canonical NaN | ||
205 | + */ | ||
206 | + if (float64_is_signaling_nan(f, s) || | ||
207 | + (float64_is_infinity(f) && sign) || | ||
208 | + (float64_is_normal(f) && sign) || | ||
209 | + (float64_is_zero_or_denormal(f) && !float64_is_zero(f) && sign)) { | ||
210 | + s->float_exception_flags |= float_flag_invalid; | ||
211 | + return float64_default_nan(s); | ||
212 | + } | ||
213 | + | ||
214 | + /* frsqrt7(qNaN) = canonical NaN */ | ||
215 | + if (float64_is_quiet_nan(f, s)) { | ||
216 | + return float64_default_nan(s); | ||
217 | + } | ||
218 | + | ||
219 | + /* frsqrt7(+-0) = +-inf */ | ||
220 | + if (float64_is_zero(f)) { | ||
221 | + s->float_exception_flags |= float_flag_divbyzero; | ||
222 | + return float64_set_sign(float64_infinity, sign); | ||
223 | + } | ||
224 | + | ||
225 | + /* frsqrt7(+inf) = +0 */ | ||
226 | + if (float64_is_infinity(f) && !sign) { | ||
227 | + return float64_set_sign(float64_zero, sign); | ||
228 | + } | ||
229 | + | ||
230 | + /* +normal, +subnormal */ | ||
231 | + uint64_t val = frsqrt7(f, exp_size, frac_size); | ||
232 | + return make_float64(val); | ||
233 | +} | ||
234 | + | ||
235 | +RVVCALL(OPFVV1, vfrsqrt7_v_h, OP_UU_H, H2, H2, frsqrt7_h) | ||
236 | +RVVCALL(OPFVV1, vfrsqrt7_v_w, OP_UU_W, H4, H4, frsqrt7_s) | ||
237 | +RVVCALL(OPFVV1, vfrsqrt7_v_d, OP_UU_D, H8, H8, frsqrt7_d) | ||
238 | +GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2, 2) | ||
239 | +GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4, 4) | ||
240 | +GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8, 8) | ||
241 | + | ||
242 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
243 | RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number) | ||
244 | RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number) | ||
245 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
246 | index XXXXXXX..XXXXXXX 100644 | ||
247 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
248 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
249 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
250 | } | ||
251 | |||
252 | GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN) | ||
253 | +GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN) | ||
254 | |||
255 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
256 | GEN_OPFVV_TRANS(vfmin_vv, opfvv_check) | ||
257 | -- | ||
258 | 2.31.1 | ||
259 | |||
260 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Frank Chang <frank.chang@sifive.com> | |
2 | |||
3 | Implement the floating-point reciprocal estimate to 7 bits instruction. | ||
4 | |||
5 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <20211210075704.23951-71-frank.chang@sifive.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/helper.h | 4 + | ||
11 | target/riscv/insn32.decode | 1 + | ||
12 | target/riscv/vector_helper.c | 191 ++++++++++++++++++++++++ | ||
13 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + | ||
14 | 4 files changed, 197 insertions(+) | ||
15 | |||
16 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/helper.h | ||
19 | +++ b/target/riscv/helper.h | ||
20 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32) | ||
21 | DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32) | ||
22 | DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32) | ||
23 | |||
24 | +DEF_HELPER_5(vfrec7_v_h, void, ptr, ptr, ptr, env, i32) | ||
25 | +DEF_HELPER_5(vfrec7_v_w, void, ptr, ptr, ptr, env, i32) | ||
26 | +DEF_HELPER_5(vfrec7_v_d, void, ptr, ptr, ptr, env, i32) | ||
27 | + | ||
28 | DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32) | ||
29 | DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32) | ||
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/insn32.decode | ||
34 | +++ b/target/riscv/insn32.decode | ||
35 | @@ -XXX,XX +XXX,XX @@ vfwnmsac_vv 111111 . ..... ..... 001 ..... 1010111 @r_vm | ||
36 | vfwnmsac_vf 111111 . ..... ..... 101 ..... 1010111 @r_vm | ||
37 | vfsqrt_v 010011 . ..... 00000 001 ..... 1010111 @r2_vm | ||
38 | vfrsqrt7_v 010011 . ..... 00100 001 ..... 1010111 @r2_vm | ||
39 | +vfrec7_v 010011 . ..... 00101 001 ..... 1010111 @r2_vm | ||
40 | vfmin_vv 000100 . ..... ..... 001 ..... 1010111 @r_vm | ||
41 | vfmin_vf 000100 . ..... ..... 101 ..... 1010111 @r_vm | ||
42 | vfmax_vv 000110 . ..... ..... 001 ..... 1010111 @r_vm | ||
43 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/target/riscv/vector_helper.c | ||
46 | +++ b/target/riscv/vector_helper.c | ||
47 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2, 2) | ||
48 | GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4, 4) | ||
49 | GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8, 8) | ||
50 | |||
51 | +/* | ||
52 | + * Vector Floating-Point Reciprocal Estimate Instruction | ||
53 | + * | ||
54 | + * Adapted from riscv-v-spec recip.c: | ||
55 | + * https://github.com/riscv/riscv-v-spec/blob/master/recip.c | ||
56 | + */ | ||
57 | +static uint64_t frec7(uint64_t f, int exp_size, int frac_size, | ||
58 | + float_status *s) | ||
59 | +{ | ||
60 | + uint64_t sign = extract64(f, frac_size + exp_size, 1); | ||
61 | + uint64_t exp = extract64(f, frac_size, exp_size); | ||
62 | + uint64_t frac = extract64(f, 0, frac_size); | ||
63 | + | ||
64 | + const uint8_t lookup_table[] = { | ||
65 | + 127, 125, 123, 121, 119, 117, 116, 114, | ||
66 | + 112, 110, 109, 107, 105, 104, 102, 100, | ||
67 | + 99, 97, 96, 94, 93, 91, 90, 88, | ||
68 | + 87, 85, 84, 83, 81, 80, 79, 77, | ||
69 | + 76, 75, 74, 72, 71, 70, 69, 68, | ||
70 | + 66, 65, 64, 63, 62, 61, 60, 59, | ||
71 | + 58, 57, 56, 55, 54, 53, 52, 51, | ||
72 | + 50, 49, 48, 47, 46, 45, 44, 43, | ||
73 | + 42, 41, 40, 40, 39, 38, 37, 36, | ||
74 | + 35, 35, 34, 33, 32, 31, 31, 30, | ||
75 | + 29, 28, 28, 27, 26, 25, 25, 24, | ||
76 | + 23, 23, 22, 21, 21, 20, 19, 19, | ||
77 | + 18, 17, 17, 16, 15, 15, 14, 14, | ||
78 | + 13, 12, 12, 11, 11, 10, 9, 9, | ||
79 | + 8, 8, 7, 7, 6, 5, 5, 4, | ||
80 | + 4, 3, 3, 2, 2, 1, 1, 0 | ||
81 | + }; | ||
82 | + const int precision = 7; | ||
83 | + | ||
84 | + if (exp == 0 && frac != 0) { /* subnormal */ | ||
85 | + /* Normalize the subnormal. */ | ||
86 | + while (extract64(frac, frac_size - 1, 1) == 0) { | ||
87 | + exp--; | ||
88 | + frac <<= 1; | ||
89 | + } | ||
90 | + | ||
91 | + frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size); | ||
92 | + | ||
93 | + if (exp != 0 && exp != UINT64_MAX) { | ||
94 | + /* | ||
95 | + * Overflow to inf or max value of same sign, | ||
96 | + * depending on sign and rounding mode. | ||
97 | + */ | ||
98 | + s->float_exception_flags |= (float_flag_inexact | | ||
99 | + float_flag_overflow); | ||
100 | + | ||
101 | + if ((s->float_rounding_mode == float_round_to_zero) || | ||
102 | + ((s->float_rounding_mode == float_round_down) && !sign) || | ||
103 | + ((s->float_rounding_mode == float_round_up) && sign)) { | ||
104 | + /* Return greatest/negative finite value. */ | ||
105 | + return (sign << (exp_size + frac_size)) | | ||
106 | + (MAKE_64BIT_MASK(frac_size, exp_size) - 1); | ||
107 | + } else { | ||
108 | + /* Return +-inf. */ | ||
109 | + return (sign << (exp_size + frac_size)) | | ||
110 | + MAKE_64BIT_MASK(frac_size, exp_size); | ||
111 | + } | ||
112 | + } | ||
113 | + } | ||
114 | + | ||
115 | + int idx = frac >> (frac_size - precision); | ||
116 | + uint64_t out_frac = (uint64_t)(lookup_table[idx]) << | ||
117 | + (frac_size - precision); | ||
118 | + uint64_t out_exp = 2 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp; | ||
119 | + | ||
120 | + if (out_exp == 0 || out_exp == UINT64_MAX) { | ||
121 | + /* | ||
122 | + * The result is subnormal, but don't raise the underflow exception, | ||
123 | + * because there's no additional loss of precision. | ||
124 | + */ | ||
125 | + out_frac = (out_frac >> 1) | MAKE_64BIT_MASK(frac_size - 1, 1); | ||
126 | + if (out_exp == UINT64_MAX) { | ||
127 | + out_frac >>= 1; | ||
128 | + out_exp = 0; | ||
129 | + } | ||
130 | + } | ||
131 | + | ||
132 | + uint64_t val = 0; | ||
133 | + val = deposit64(val, 0, frac_size, out_frac); | ||
134 | + val = deposit64(val, frac_size, exp_size, out_exp); | ||
135 | + val = deposit64(val, frac_size + exp_size, 1, sign); | ||
136 | + return val; | ||
137 | +} | ||
138 | + | ||
139 | +static float16 frec7_h(float16 f, float_status *s) | ||
140 | +{ | ||
141 | + int exp_size = 5, frac_size = 10; | ||
142 | + bool sign = float16_is_neg(f); | ||
143 | + | ||
144 | + /* frec7(+-inf) = +-0 */ | ||
145 | + if (float16_is_infinity(f)) { | ||
146 | + return float16_set_sign(float16_zero, sign); | ||
147 | + } | ||
148 | + | ||
149 | + /* frec7(+-0) = +-inf */ | ||
150 | + if (float16_is_zero(f)) { | ||
151 | + s->float_exception_flags |= float_flag_divbyzero; | ||
152 | + return float16_set_sign(float16_infinity, sign); | ||
153 | + } | ||
154 | + | ||
155 | + /* frec7(sNaN) = canonical NaN */ | ||
156 | + if (float16_is_signaling_nan(f, s)) { | ||
157 | + s->float_exception_flags |= float_flag_invalid; | ||
158 | + return float16_default_nan(s); | ||
159 | + } | ||
160 | + | ||
161 | + /* frec7(qNaN) = canonical NaN */ | ||
162 | + if (float16_is_quiet_nan(f, s)) { | ||
163 | + return float16_default_nan(s); | ||
164 | + } | ||
165 | + | ||
166 | + /* +-normal, +-subnormal */ | ||
167 | + uint64_t val = frec7(f, exp_size, frac_size, s); | ||
168 | + return make_float16(val); | ||
169 | +} | ||
170 | + | ||
171 | +static float32 frec7_s(float32 f, float_status *s) | ||
172 | +{ | ||
173 | + int exp_size = 8, frac_size = 23; | ||
174 | + bool sign = float32_is_neg(f); | ||
175 | + | ||
176 | + /* frec7(+-inf) = +-0 */ | ||
177 | + if (float32_is_infinity(f)) { | ||
178 | + return float32_set_sign(float32_zero, sign); | ||
179 | + } | ||
180 | + | ||
181 | + /* frec7(+-0) = +-inf */ | ||
182 | + if (float32_is_zero(f)) { | ||
183 | + s->float_exception_flags |= float_flag_divbyzero; | ||
184 | + return float32_set_sign(float32_infinity, sign); | ||
185 | + } | ||
186 | + | ||
187 | + /* frec7(sNaN) = canonical NaN */ | ||
188 | + if (float32_is_signaling_nan(f, s)) { | ||
189 | + s->float_exception_flags |= float_flag_invalid; | ||
190 | + return float32_default_nan(s); | ||
191 | + } | ||
192 | + | ||
193 | + /* frec7(qNaN) = canonical NaN */ | ||
194 | + if (float32_is_quiet_nan(f, s)) { | ||
195 | + return float32_default_nan(s); | ||
196 | + } | ||
197 | + | ||
198 | + /* +-normal, +-subnormal */ | ||
199 | + uint64_t val = frec7(f, exp_size, frac_size, s); | ||
200 | + return make_float32(val); | ||
201 | +} | ||
202 | + | ||
203 | +static float64 frec7_d(float64 f, float_status *s) | ||
204 | +{ | ||
205 | + int exp_size = 11, frac_size = 52; | ||
206 | + bool sign = float64_is_neg(f); | ||
207 | + | ||
208 | + /* frec7(+-inf) = +-0 */ | ||
209 | + if (float64_is_infinity(f)) { | ||
210 | + return float64_set_sign(float64_zero, sign); | ||
211 | + } | ||
212 | + | ||
213 | + /* frec7(+-0) = +-inf */ | ||
214 | + if (float64_is_zero(f)) { | ||
215 | + s->float_exception_flags |= float_flag_divbyzero; | ||
216 | + return float64_set_sign(float64_infinity, sign); | ||
217 | + } | ||
218 | + | ||
219 | + /* frec7(sNaN) = canonical NaN */ | ||
220 | + if (float64_is_signaling_nan(f, s)) { | ||
221 | + s->float_exception_flags |= float_flag_invalid; | ||
222 | + return float64_default_nan(s); | ||
223 | + } | ||
224 | + | ||
225 | + /* frec7(qNaN) = canonical NaN */ | ||
226 | + if (float64_is_quiet_nan(f, s)) { | ||
227 | + return float64_default_nan(s); | ||
228 | + } | ||
229 | + | ||
230 | + /* +-normal, +-subnormal */ | ||
231 | + uint64_t val = frec7(f, exp_size, frac_size, s); | ||
232 | + return make_float64(val); | ||
233 | +} | ||
234 | + | ||
235 | +RVVCALL(OPFVV1, vfrec7_v_h, OP_UU_H, H2, H2, frec7_h) | ||
236 | +RVVCALL(OPFVV1, vfrec7_v_w, OP_UU_W, H4, H4, frec7_s) | ||
237 | +RVVCALL(OPFVV1, vfrec7_v_d, OP_UU_D, H8, H8, frec7_d) | ||
238 | +GEN_VEXT_V_ENV(vfrec7_v_h, 2, 2) | ||
239 | +GEN_VEXT_V_ENV(vfrec7_v_w, 4, 4) | ||
240 | +GEN_VEXT_V_ENV(vfrec7_v_d, 8, 8) | ||
241 | + | ||
242 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
243 | RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number) | ||
244 | RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number) | ||
245 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
246 | index XXXXXXX..XXXXXXX 100644 | ||
247 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
248 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
249 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
250 | |||
251 | GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN) | ||
252 | GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN) | ||
253 | +GEN_OPFV_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN) | ||
254 | |||
255 | /* Vector Floating-Point MIN/MAX Instructions */ | ||
256 | GEN_OPFVV_TRANS(vfmin_vv, opfvv_check) | ||
257 | -- | ||
258 | 2.31.1 | ||
259 | |||
260 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Rename r2_zimm to r2_zimm11 for the upcoming vsetivli instruction. | ||
4 | vsetivli has 10-bits of zimm but vsetvli has 11-bits of zimm. | ||
5 | |||
6 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20211210075704.23951-72-frank.chang@sifive.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/insn32.decode | 4 ++-- | ||
12 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/insn32.decode | ||
17 | +++ b/target/riscv/insn32.decode | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | @r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd | ||
20 | @r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd | ||
21 | @r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd | ||
22 | -@r2_zimm . zimm:11 ..... ... ..... ....... %rs1 %rd | ||
23 | +@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd | ||
24 | @r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
25 | |||
26 | @hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
27 | @@ -XXX,XX +XXX,XX @@ vsext_vf2 010010 . ..... 00111 010 ..... 1010111 @r2_vm | ||
28 | vsext_vf4 010010 . ..... 00101 010 ..... 1010111 @r2_vm | ||
29 | vsext_vf8 010010 . ..... 00011 010 ..... 1010111 @r2_vm | ||
30 | |||
31 | -vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm | ||
32 | +vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm11 | ||
33 | vsetvl 1000000 ..... ..... 111 ..... 1010111 @r | ||
34 | |||
35 | # *** RV32 Zba Standard Extension *** | ||
36 | -- | ||
37 | 2.31.1 | ||
38 | |||
39 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-73-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/insn32.decode | 2 ++ | ||
9 | target/riscv/insn_trans/trans_rvv.c.inc | 27 +++++++++++++++++++++++++ | ||
10 | 2 files changed, 29 insertions(+) | ||
11 | |||
12 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/insn32.decode | ||
15 | +++ b/target/riscv/insn32.decode | ||
16 | @@ -XXX,XX +XXX,XX @@ | ||
17 | @r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd | ||
18 | @r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd | ||
19 | @r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd | ||
20 | +@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd | ||
21 | @r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
22 | |||
23 | @hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
24 | @@ -XXX,XX +XXX,XX @@ vsext_vf4 010010 . ..... 00101 010 ..... 1010111 @r2_vm | ||
25 | vsext_vf8 010010 . ..... 00011 010 ..... 1010111 @r2_vm | ||
26 | |||
27 | vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm11 | ||
28 | +vsetivli 11 .......... ..... 111 ..... 1010111 @r2_zimm10 | ||
29 | vsetvl 1000000 ..... ..... 111 ..... 1010111 @r | ||
30 | |||
31 | # *** RV32 Zba Standard Extension *** | ||
32 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
35 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
36 | @@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2) | ||
37 | return true; | ||
38 | } | ||
39 | |||
40 | +static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2) | ||
41 | +{ | ||
42 | + TCGv dst; | ||
43 | + | ||
44 | + if (!require_rvv(s) || !has_ext(s, RVV)) { | ||
45 | + return false; | ||
46 | + } | ||
47 | + | ||
48 | + dst = dest_gpr(s, rd); | ||
49 | + | ||
50 | + gen_helper_vsetvl(dst, cpu_env, s1, s2); | ||
51 | + gen_set_gpr(s, rd, dst); | ||
52 | + mark_vs_dirty(s); | ||
53 | + tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn); | ||
54 | + tcg_gen_lookup_and_goto_ptr(); | ||
55 | + s->base.is_jmp = DISAS_NORETURN; | ||
56 | + | ||
57 | + return true; | ||
58 | +} | ||
59 | + | ||
60 | static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a) | ||
61 | { | ||
62 | TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO); | ||
63 | @@ -XXX,XX +XXX,XX @@ static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a) | ||
64 | return do_vsetvl(s, a->rd, a->rs1, s2); | ||
65 | } | ||
66 | |||
67 | +static bool trans_vsetivli(DisasContext *s, arg_vsetivli *a) | ||
68 | +{ | ||
69 | + TCGv s1 = tcg_const_tl(a->rs1); | ||
70 | + TCGv s2 = tcg_const_tl(a->zimm); | ||
71 | + return do_vsetivli(s, a->rd, s1, s2); | ||
72 | +} | ||
73 | + | ||
74 | /* vector register offset from env */ | ||
75 | static uint32_t vreg_ofs(DisasContext *s, int reg) | ||
76 | { | ||
77 | -- | ||
78 | 2.31.1 | ||
79 | |||
80 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Add supports of Vector unit-stride mask load/store instructions | ||
4 | (vlm.v, vsm.v), which has: | ||
5 | evl (effective vector length) = ceil(env->vl / 8). | ||
6 | |||
7 | The new instructions operate the same as unmasked byte loads and stores. | ||
8 | Add evl parameter to reuse vext_ldst_us(). | ||
9 | |||
10 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20211210075704.23951-74-frank.chang@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/vector_helper.c | 36 ++++++++++++++++++------------------ | ||
16 | 1 file changed, 18 insertions(+), 18 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/vector_helper.c | ||
21 | +++ b/target/riscv/vector_helper.c | ||
22 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d) | ||
23 | /* unmasked unit-stride load and store operation*/ | ||
24 | static void | ||
25 | vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, | ||
26 | - vext_ldst_elem_fn *ldst_elem, | ||
27 | - uint32_t esz, uintptr_t ra, MMUAccessType access_type) | ||
28 | + vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t evl, | ||
29 | + uintptr_t ra, MMUAccessType access_type) | ||
30 | { | ||
31 | uint32_t i, k; | ||
32 | uint32_t nf = vext_nf(desc); | ||
33 | uint32_t max_elems = vext_max_elems(desc, esz); | ||
34 | |||
35 | /* load bytes from guest memory */ | ||
36 | - for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
37 | + for (i = env->vstart; i < evl; i++, env->vstart++) { | ||
38 | k = 0; | ||
39 | while (k < nf) { | ||
40 | target_ulong addr = base + ((i * nf + k) << esz); | ||
41 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
42 | CPURISCVState *env, uint32_t desc) \ | ||
43 | { \ | ||
44 | vext_ldst_us(vd, base, env, desc, LOAD_FN, \ | ||
45 | - ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \ | ||
46 | + ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_LOAD); \ | ||
47 | } | ||
48 | |||
49 | GEN_VEXT_LD_US(vle8_v, int8_t, lde_b) | ||
50 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_LD_US(vle16_v, int16_t, lde_h) | ||
51 | GEN_VEXT_LD_US(vle32_v, int32_t, lde_w) | ||
52 | GEN_VEXT_LD_US(vle64_v, int64_t, lde_d) | ||
53 | |||
54 | -#define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN) \ | ||
55 | -void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
56 | - CPURISCVState *env, uint32_t desc) \ | ||
57 | -{ \ | ||
58 | - uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \ | ||
59 | - vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \ | ||
60 | - ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
61 | -} \ | ||
62 | - \ | ||
63 | -void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
64 | - CPURISCVState *env, uint32_t desc) \ | ||
65 | -{ \ | ||
66 | - vext_ldst_us(vd, base, env, desc, STORE_FN, \ | ||
67 | - ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
68 | +#define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN) \ | ||
69 | +void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \ | ||
70 | + CPURISCVState *env, uint32_t desc) \ | ||
71 | +{ \ | ||
72 | + uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \ | ||
73 | + vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \ | ||
74 | + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \ | ||
75 | +} \ | ||
76 | + \ | ||
77 | +void HELPER(NAME)(void *vd, void *v0, target_ulong base, \ | ||
78 | + CPURISCVState *env, uint32_t desc) \ | ||
79 | +{ \ | ||
80 | + vext_ldst_us(vd, base, env, desc, STORE_FN, \ | ||
81 | + ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_STORE); \ | ||
82 | } | ||
83 | |||
84 | GEN_VEXT_ST_US(vse8_v, int8_t, ste_b) | ||
85 | -- | ||
86 | 2.31.1 | ||
87 | |||
88 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-75-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 2 ++ | ||
9 | target/riscv/insn32.decode | 4 +++ | ||
10 | target/riscv/vector_helper.c | 21 +++++++++++++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 40 +++++++++++++++++++++++++ | ||
12 | 4 files changed, 67 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vse8_v_mask, void, ptr, ptr, tl, env, i32) | ||
19 | DEF_HELPER_5(vse16_v_mask, void, ptr, ptr, tl, env, i32) | ||
20 | DEF_HELPER_5(vse32_v_mask, void, ptr, ptr, tl, env, i32) | ||
21 | DEF_HELPER_5(vse64_v_mask, void, ptr, ptr, tl, env, i32) | ||
22 | +DEF_HELPER_5(vlm_v, void, ptr, ptr, tl, env, i32) | ||
23 | +DEF_HELPER_5(vsm_v, void, ptr, ptr, tl, env, i32) | ||
24 | DEF_HELPER_6(vlse8_v, void, ptr, ptr, tl, tl, env, i32) | ||
25 | DEF_HELPER_6(vlse16_v, void, ptr, ptr, tl, tl, env, i32) | ||
26 | DEF_HELPER_6(vlse32_v, void, ptr, ptr, tl, tl, env, i32) | ||
27 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/riscv/insn32.decode | ||
30 | +++ b/target/riscv/insn32.decode | ||
31 | @@ -XXX,XX +XXX,XX @@ vse16_v ... 000 . 00000 ..... 101 ..... 0100111 @r2_nfvm | ||
32 | vse32_v ... 000 . 00000 ..... 110 ..... 0100111 @r2_nfvm | ||
33 | vse64_v ... 000 . 00000 ..... 111 ..... 0100111 @r2_nfvm | ||
34 | |||
35 | +# Vector unit-stride mask load/store insns. | ||
36 | +vlm_v 000 000 1 01011 ..... 000 ..... 0000111 @r2 | ||
37 | +vsm_v 000 000 1 01011 ..... 000 ..... 0100111 @r2 | ||
38 | + | ||
39 | # Vector strided insns. | ||
40 | vlse8_v ... 010 . ..... ..... 000 ..... 0000111 @r_nfvm | ||
41 | vlse16_v ... 010 . ..... ..... 101 ..... 0000111 @r_nfvm | ||
42 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/target/riscv/vector_helper.c | ||
45 | +++ b/target/riscv/vector_helper.c | ||
46 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_US(vse16_v, int16_t, ste_h) | ||
47 | GEN_VEXT_ST_US(vse32_v, int32_t, ste_w) | ||
48 | GEN_VEXT_ST_US(vse64_v, int64_t, ste_d) | ||
49 | |||
50 | +/* | ||
51 | + *** unit stride mask load and store, EEW = 1 | ||
52 | + */ | ||
53 | +void HELPER(vlm_v)(void *vd, void *v0, target_ulong base, | ||
54 | + CPURISCVState *env, uint32_t desc) | ||
55 | +{ | ||
56 | + /* evl = ceil(vl/8) */ | ||
57 | + uint8_t evl = (env->vl + 7) >> 3; | ||
58 | + vext_ldst_us(vd, base, env, desc, lde_b, | ||
59 | + 0, evl, GETPC(), MMU_DATA_LOAD); | ||
60 | +} | ||
61 | + | ||
62 | +void HELPER(vsm_v)(void *vd, void *v0, target_ulong base, | ||
63 | + CPURISCVState *env, uint32_t desc) | ||
64 | +{ | ||
65 | + /* evl = ceil(vl/8) */ | ||
66 | + uint8_t evl = (env->vl + 7) >> 3; | ||
67 | + vext_ldst_us(vd, base, env, desc, ste_b, | ||
68 | + 0, evl, GETPC(), MMU_DATA_STORE); | ||
69 | +} | ||
70 | + | ||
71 | /* | ||
72 | *** index: access vector element from indexed memory | ||
73 | */ | ||
74 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
77 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
78 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_TRANS(vse16_v, MO_16, r2nfvm, st_us_op, st_us_check) | ||
79 | GEN_VEXT_TRANS(vse32_v, MO_32, r2nfvm, st_us_op, st_us_check) | ||
80 | GEN_VEXT_TRANS(vse64_v, MO_64, r2nfvm, st_us_op, st_us_check) | ||
81 | |||
82 | +/* | ||
83 | + *** unit stride mask load and store | ||
84 | + */ | ||
85 | +static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, uint8_t eew) | ||
86 | +{ | ||
87 | + uint32_t data = 0; | ||
88 | + gen_helper_ldst_us *fn = gen_helper_vlm_v; | ||
89 | + | ||
90 | + /* EMUL = 1, NFIELDS = 1 */ | ||
91 | + data = FIELD_DP32(data, VDATA, LMUL, 0); | ||
92 | + data = FIELD_DP32(data, VDATA, NF, 1); | ||
93 | + return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
94 | +} | ||
95 | + | ||
96 | +static bool ld_us_mask_check(DisasContext *s, arg_vlm_v *a, uint8_t eew) | ||
97 | +{ | ||
98 | + /* EMUL = 1, NFIELDS = 1 */ | ||
99 | + return require_rvv(s) && vext_check_isa_ill(s); | ||
100 | +} | ||
101 | + | ||
102 | +static bool st_us_mask_op(DisasContext *s, arg_vsm_v *a, uint8_t eew) | ||
103 | +{ | ||
104 | + uint32_t data = 0; | ||
105 | + gen_helper_ldst_us *fn = gen_helper_vsm_v; | ||
106 | + | ||
107 | + /* EMUL = 1, NFIELDS = 1 */ | ||
108 | + data = FIELD_DP32(data, VDATA, LMUL, 0); | ||
109 | + data = FIELD_DP32(data, VDATA, NF, 1); | ||
110 | + return ldst_us_trans(a->rd, a->rs1, data, fn, s, true); | ||
111 | +} | ||
112 | + | ||
113 | +static bool st_us_mask_check(DisasContext *s, arg_vsm_v *a, uint8_t eew) | ||
114 | +{ | ||
115 | + /* EMUL = 1, NFIELDS = 1 */ | ||
116 | + return require_rvv(s) && vext_check_isa_ill(s); | ||
117 | +} | ||
118 | + | ||
119 | +GEN_VEXT_TRANS(vlm_v, MO_8, vlm_v, ld_us_mask_op, ld_us_mask_check) | ||
120 | +GEN_VEXT_TRANS(vsm_v, MO_8, vsm_v, st_us_mask_op, st_us_mask_check) | ||
121 | + | ||
122 | /* | ||
123 | *** stride load and store | ||
124 | */ | ||
125 | -- | ||
126 | 2.31.1 | ||
127 | |||
128 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
5 | Message-Id: <20211210075704.23951-76-frank.chang@sifive.com> | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | --- | ||
8 | target/riscv/helper.h | 4 ++-- | ||
9 | target/riscv/insn32.decode | 4 ++-- | ||
10 | target/riscv/vector_helper.c | 4 ++-- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 4 ++-- | ||
12 | 4 files changed, 8 insertions(+), 8 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/helper.h | ||
17 | +++ b/target/riscv/helper.h | ||
18 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32) | ||
19 | |||
20 | DEF_HELPER_6(vmand_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
21 | DEF_HELPER_6(vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
22 | -DEF_HELPER_6(vmandnot_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
23 | +DEF_HELPER_6(vmandn_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
24 | DEF_HELPER_6(vmxor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
25 | DEF_HELPER_6(vmor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
26 | DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
27 | -DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
28 | +DEF_HELPER_6(vmorn_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
29 | DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32) | ||
30 | |||
31 | DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32) | ||
32 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/insn32.decode | ||
35 | +++ b/target/riscv/insn32.decode | ||
36 | @@ -XXX,XX +XXX,XX @@ vfredmax_vs 000111 . ..... ..... 001 ..... 1010111 @r_vm | ||
37 | vfwredsum_vs 1100-1 . ..... ..... 001 ..... 1010111 @r_vm | ||
38 | vmand_mm 011001 - ..... ..... 010 ..... 1010111 @r | ||
39 | vmnand_mm 011101 - ..... ..... 010 ..... 1010111 @r | ||
40 | -vmandnot_mm 011000 - ..... ..... 010 ..... 1010111 @r | ||
41 | +vmandn_mm 011000 - ..... ..... 010 ..... 1010111 @r | ||
42 | vmxor_mm 011011 - ..... ..... 010 ..... 1010111 @r | ||
43 | vmor_mm 011010 - ..... ..... 010 ..... 1010111 @r | ||
44 | vmnor_mm 011110 - ..... ..... 010 ..... 1010111 @r | ||
45 | -vmornot_mm 011100 - ..... ..... 010 ..... 1010111 @r | ||
46 | +vmorn_mm 011100 - ..... ..... 010 ..... 1010111 @r | ||
47 | vmxnor_mm 011111 - ..... ..... 010 ..... 1010111 @r | ||
48 | vcpop_m 010000 . ..... 10000 010 ..... 1010111 @r2_vm | ||
49 | vfirst_m 010000 . ..... 10001 010 ..... 1010111 @r2_vm | ||
50 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/target/riscv/vector_helper.c | ||
53 | +++ b/target/riscv/vector_helper.c | ||
54 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
55 | |||
56 | GEN_VEXT_MASK_VV(vmand_mm, DO_AND) | ||
57 | GEN_VEXT_MASK_VV(vmnand_mm, DO_NAND) | ||
58 | -GEN_VEXT_MASK_VV(vmandnot_mm, DO_ANDNOT) | ||
59 | +GEN_VEXT_MASK_VV(vmandn_mm, DO_ANDNOT) | ||
60 | GEN_VEXT_MASK_VV(vmxor_mm, DO_XOR) | ||
61 | GEN_VEXT_MASK_VV(vmor_mm, DO_OR) | ||
62 | GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR) | ||
63 | -GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT) | ||
64 | +GEN_VEXT_MASK_VV(vmorn_mm, DO_ORNOT) | ||
65 | GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR) | ||
66 | |||
67 | /* Vector count population in mask vcpop */ | ||
68 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
71 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
72 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \ | ||
73 | |||
74 | GEN_MM_TRANS(vmand_mm) | ||
75 | GEN_MM_TRANS(vmnand_mm) | ||
76 | -GEN_MM_TRANS(vmandnot_mm) | ||
77 | +GEN_MM_TRANS(vmandn_mm) | ||
78 | GEN_MM_TRANS(vmxor_mm) | ||
79 | GEN_MM_TRANS(vmor_mm) | ||
80 | GEN_MM_TRANS(vmnor_mm) | ||
81 | -GEN_MM_TRANS(vmornot_mm) | ||
82 | +GEN_MM_TRANS(vmorn_mm) | ||
83 | GEN_MM_TRANS(vmxnor_mm) | ||
84 | |||
85 | /* Vector count population in mask vcpop */ | ||
86 | -- | ||
87 | 2.31.1 | ||
88 | |||
89 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions is | ||
4 | moved to Section 11.4 in RVV v1.0 spec. Update the comment, no | ||
5 | functional changes. | ||
6 | |||
7 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20211210075704.23951-77-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
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 | ||
17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
19 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
20 | |||
21 | /* | ||
22 | * For vadc and vsbc, an illegal instruction exception is raised if the | ||
23 | - * destination vector register is v0 and LMUL > 1. (Section 12.4) | ||
24 | + * destination vector register is v0 and LMUL > 1. (Section 11.4) | ||
25 | */ | ||
26 | static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a) | ||
27 | { | ||
28 | -- | ||
29 | 2.31.1 | ||
30 | |||
31 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | SEW has the limitation which cannot exceed ELEN. | ||
4 | |||
5 | Widening instructions have a destination group with EEW = 2*SEW | ||
6 | and narrowing instructions have a source operand with EEW = 2*SEW. | ||
7 | Both of the instructions have the limitation of: 2*SEW <= ELEN. | ||
8 | |||
9 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-Id: <20211210075704.23951-78-frank.chang@sifive.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/translate.c | 2 ++ | ||
15 | target/riscv/insn_trans/trans_rvv.c.inc | 17 +++++++++++------ | ||
16 | 2 files changed, 13 insertions(+), 6 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/translate.c | ||
21 | +++ b/target/riscv/translate.c | ||
22 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
23 | int8_t lmul; | ||
24 | uint8_t sew; | ||
25 | uint16_t vlen; | ||
26 | + uint16_t elen; | ||
27 | target_ulong vstart; | ||
28 | bool vl_eq_vlmax; | ||
29 | uint8_t ntemp; | ||
30 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
31 | ctx->ext_zfh = cpu->cfg.ext_zfh; | ||
32 | ctx->ext_zfhmin = cpu->cfg.ext_zfhmin; | ||
33 | ctx->vlen = cpu->cfg.vlen; | ||
34 | + ctx->elen = cpu->cfg.elen; | ||
35 | ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS); | ||
36 | ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS); | ||
37 | ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); | ||
38 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
41 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
42 | @@ -XXX,XX +XXX,XX @@ static bool vext_check_mss(DisasContext *s, int vd, int vs1, int vs2) | ||
43 | * can not be greater than 8 vector registers (Section 5.2): | ||
44 | * => LMUL < 8. | ||
45 | * => SEW < 64. | ||
46 | - * 2. Destination vector register number is multiples of 2 * LMUL. | ||
47 | + * 2. Double-width SEW cannot greater than ELEN. | ||
48 | + * 3. Destination vector register number is multiples of 2 * LMUL. | ||
49 | * (Section 3.4.2) | ||
50 | - * 3. Destination vector register group for a masked vector | ||
51 | + * 4. Destination vector register group for a masked vector | ||
52 | * instruction cannot overlap the source mask register (v0). | ||
53 | * (Section 5.3) | ||
54 | */ | ||
55 | @@ -XXX,XX +XXX,XX @@ static bool vext_wide_check_common(DisasContext *s, int vd, int vm) | ||
56 | { | ||
57 | return (s->lmul <= 2) && | ||
58 | (s->sew < MO_64) && | ||
59 | + ((s->sew + 1) <= (s->elen >> 4)) && | ||
60 | require_align(vd, s->lmul + 1) && | ||
61 | require_vm(vm, vd); | ||
62 | } | ||
63 | @@ -XXX,XX +XXX,XX @@ static bool vext_wide_check_common(DisasContext *s, int vd, int vm) | ||
64 | * can not be greater than 8 vector registers (Section 5.2): | ||
65 | * => LMUL < 8. | ||
66 | * => SEW < 64. | ||
67 | - * 2. Source vector register number is multiples of 2 * LMUL. | ||
68 | + * 2. Double-width SEW cannot greater than ELEN. | ||
69 | + * 3. Source vector register number is multiples of 2 * LMUL. | ||
70 | * (Section 3.4.2) | ||
71 | - * 3. Destination vector register number is multiples of LMUL. | ||
72 | + * 4. Destination vector register number is multiples of LMUL. | ||
73 | * (Section 3.4.2) | ||
74 | - * 4. Destination vector register group for a masked vector | ||
75 | + * 5. Destination vector register group for a masked vector | ||
76 | * instruction cannot overlap the source mask register (v0). | ||
77 | * (Section 5.3) | ||
78 | */ | ||
79 | @@ -XXX,XX +XXX,XX @@ static bool vext_narrow_check_common(DisasContext *s, int vd, int vs2, | ||
80 | { | ||
81 | return (s->lmul <= 2) && | ||
82 | (s->sew < MO_64) && | ||
83 | + ((s->sew + 1) <= (s->elen >> 4)) && | ||
84 | require_align(vs2, s->lmul + 1) && | ||
85 | require_align(vd, s->lmul) && | ||
86 | require_vm(vm, vd); | ||
87 | @@ -XXX,XX +XXX,XX @@ GEN_OPIVV_TRANS(vredxor_vs, reduction_check) | ||
88 | /* Vector Widening Integer Reduction Instructions */ | ||
89 | static bool reduction_widen_check(DisasContext *s, arg_rmrr *a) | ||
90 | { | ||
91 | - return reduction_check(s, a) && (s->sew < MO_64); | ||
92 | + return reduction_check(s, a) && (s->sew < MO_64) && | ||
93 | + ((s->sew + 1) <= (s->elen >> 4)); | ||
94 | } | ||
95 | |||
96 | GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check) | ||
97 | -- | ||
98 | 2.31.1 | ||
99 | |||
100 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Khem Raj <raj.khem@gmail.com> | ||
1 | 2 | ||
3 | 5.4 is first stable API as far as rv32 is concerned see [1] | ||
4 | |||
5 | [1] https://sourceware.org/git/?p=glibc.git;a=commit;h=7a55dd3fb6d2c307a002a16776be84310b9c8989 | ||
6 | |||
7 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Cc: Palmer Dabbelt <palmer@dabbelt.com> | ||
10 | Cc: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Cc: Bin Meng <bin.meng@windriver.com> | ||
12 | Message-Id: <20211216073111.2890607-1-raj.khem@gmail.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | linux-user/riscv/target_syscall.h | 3 ++- | ||
16 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/linux-user/riscv/target_syscall.h b/linux-user/riscv/target_syscall.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/linux-user/riscv/target_syscall.h | ||
21 | +++ b/linux-user/riscv/target_syscall.h | ||
22 | @@ -XXX,XX +XXX,XX @@ struct target_pt_regs { | ||
23 | |||
24 | #ifdef TARGET_RISCV32 | ||
25 | #define UNAME_MACHINE "riscv32" | ||
26 | +#define UNAME_MINIMUM_RELEASE "5.4.0" | ||
27 | #else | ||
28 | #define UNAME_MACHINE "riscv64" | ||
29 | -#endif | ||
30 | #define UNAME_MINIMUM_RELEASE "4.15.0" | ||
31 | +#endif | ||
32 | |||
33 | #define TARGET_MINSIGSTKSZ 2048 | ||
34 | #define TARGET_MCL_CURRENT 1 | ||
35 | -- | ||
36 | 2.31.1 | ||
37 | |||
38 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Vineet Gupta <vineetg@rivosinc.com> | ||
1 | 2 | ||
3 | The bitmanip extension has now been ratified [1] and upstream tooling | ||
4 | (gcc/binutils) support it too, so move them out of experimental and also | ||
5 | enable by default (for better test exposure/coverage) | ||
6 | |||
7 | [1] https://wiki.riscv.org/display/TECH/Recently+Ratified+Extensions | ||
8 | |||
9 | Signed-off-by: Vineet Gupta <vineetg@rivosinc.com> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-Id: <20211216051844.3921088-1-vineetg@rivosinc.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/cpu.c | 8 ++++---- | ||
15 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.c | ||
20 | +++ b/target/riscv/cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
22 | DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
23 | |||
24 | /* These are experimental so mark with 'x-' */ | ||
25 | - DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false), | ||
26 | - DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false), | ||
27 | - DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false), | ||
28 | - DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false), | ||
29 | + DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true), | ||
30 | + DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true), | ||
31 | + DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true), | ||
32 | + DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true), | ||
33 | DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), | ||
34 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | ||
35 | /* ePMP 0.9.3 */ | ||
36 | -- | ||
37 | 2.31.1 | ||
38 | |||
39 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jessica Clarke <jrtc27@jrtc27.com> | ||
1 | 2 | ||
3 | The original BBL boot method had the kernel embedded as an opaque blob | ||
4 | that was blindly jumped to, which OpenSBI implemented as fw_payload. | ||
5 | OpenSBI then implemented fw_jump, which allows the payload to be loaded | ||
6 | elsewhere, but still blindly jumps to a fixed address at which the | ||
7 | kernel is to be loaded. Finally, OpenSBI introduced fw_dynamic, which | ||
8 | allows the previous stage to inform it where to jump to, rather than | ||
9 | having to blindly guess like fw_jump, or embed the payload as part of | ||
10 | the build like fw_payload. When used with an opaque binary (i.e. the | ||
11 | output of objcopy -O binary), it matches the behaviour of the previous | ||
12 | methods. However, when used with an ELF, QEMU currently passes on the | ||
13 | ELF's entry point address, which causes a discrepancy compared with all | ||
14 | the other boot methods if that entry point is not the first instruction | ||
15 | in the binary. | ||
16 | |||
17 | This difference specific to fw_dynamic with an ELF is not apparent when | ||
18 | booting Linux, since its entry point is the first instruction in the | ||
19 | binary. However, FreeBSD has a separate ELF entry point, following the | ||
20 | calling convention used by its bootloader, that differs from the first | ||
21 | instruction in the binary, used for the legacy SBI entry point, and so | ||
22 | the specific combination of QEMU's default fw_dynamic firmware with | ||
23 | booting FreeBSD as an ELF rather than a raw binary does not work. | ||
24 | |||
25 | Thus, align the behaviour when loading an ELF with the behaviour when | ||
26 | loading a raw binary; namely, use the base address of the loaded kernel | ||
27 | in place of the entry point. | ||
28 | |||
29 | The uImage code is left as-is in using the U-Boot header's entry point, | ||
30 | since the calling convention for that entry point is the same as the SBI | ||
31 | one and it mirrors what U-Boot will do. | ||
32 | |||
33 | Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com> | ||
34 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
35 | Message-Id: <20211214032456.70203-1-jrtc27@jrtc27.com> | ||
36 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
37 | --- | ||
38 | hw/riscv/boot.c | 13 ++++++++++--- | ||
39 | 1 file changed, 10 insertions(+), 3 deletions(-) | ||
40 | |||
41 | diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/hw/riscv/boot.c | ||
44 | +++ b/hw/riscv/boot.c | ||
45 | @@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename, | ||
46 | target_ulong kernel_start_addr, | ||
47 | symbol_fn_t sym_cb) | ||
48 | { | ||
49 | - uint64_t kernel_entry; | ||
50 | + uint64_t kernel_load_base, kernel_entry; | ||
51 | |||
52 | + /* | ||
53 | + * NB: Use low address not ELF entry point to ensure that the fw_dynamic | ||
54 | + * behaviour when loading an ELF matches the fw_payload, fw_jump and BBL | ||
55 | + * behaviour, as well as fw_dynamic with a raw binary, all of which jump to | ||
56 | + * the (expected) load address load address. This allows kernels to have | ||
57 | + * separate SBI and ELF entry points (used by FreeBSD, for example). | ||
58 | + */ | ||
59 | if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, | ||
60 | - &kernel_entry, NULL, NULL, NULL, 0, | ||
61 | + NULL, &kernel_load_base, NULL, NULL, 0, | ||
62 | EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) { | ||
63 | - return kernel_entry; | ||
64 | + return kernel_load_base; | ||
65 | } | ||
66 | |||
67 | if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL, | ||
68 | -- | ||
69 | 2.31.1 | ||
70 | |||
71 | diff view generated by jsdifflib |