1
The following changes since commit 61fee7f45955cd0bf9b79be9fa9c7ebabb5e6a85:
1
I don't have anything else queued up at the moment, so this is just
2
Richard's SME patches.
2
3
3
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/acceptance-testing-20200622' into staging (2020-06-22 20:50:10 +0100)
4
-- PMM
5
6
The following changes since commit 63b38f6c85acd312c2cab68554abf33adf4ee2b3:
7
8
Merge tag 'pull-target-arm-20220707' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-07-08 06:17:11 +0530)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200623
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220711
8
13
9
for you to fetch changes up to 539533b85fbd269f777bed931de8ccae1dd837e9:
14
for you to fetch changes up to f9982ceaf26df27d15547a3a7990a95019e9e3a8:
10
15
11
arm/virt: Add memory hot remove support (2020-06-23 11:39:48 +0100)
16
linux-user/aarch64: Add SME related hwcap entries (2022-07-11 13:43:52 +0100)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm:
15
* util/oslib-posix : qemu_init_exec_dir implementation for Mac
20
* Implement SME emulation, for both system and linux-user
16
* target/arm: Last parts of neon decodetree conversion
17
* hw/arm/virt: Add 5.0 HW compat props
18
* hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
19
* mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices
20
* mps2: Add some unimplemented-device stubs for audio and GPIO
21
* mps2-tz: Use the ARM SBCon two-wire serial bus interface
22
* target/arm: Check supported KVM features globally (not per vCPU)
23
* tests/qtest/arm-cpu-features: Add feature setting tests
24
* arm/virt: Add memory hot remove support
25
21
26
----------------------------------------------------------------
22
----------------------------------------------------------------
27
Andrew Jones (2):
23
Richard Henderson (45):
28
hw/arm/virt: Add 5.0 HW compat props
24
target/arm: Handle SME in aarch64_cpu_dump_state
29
tests/qtest/arm-cpu-features: Add feature setting tests
25
target/arm: Add infrastructure for disas_sme
26
target/arm: Trap non-streaming usage when Streaming SVE is active
27
target/arm: Mark ADR as non-streaming
28
target/arm: Mark RDFFR, WRFFR, SETFFR as non-streaming
29
target/arm: Mark BDEP, BEXT, BGRP, COMPACT, FEXPA, FTSSEL as non-streaming
30
target/arm: Mark PMULL, FMMLA as non-streaming
31
target/arm: Mark FTSMUL, FTMAD, FADDA as non-streaming
32
target/arm: Mark SMMLA, UMMLA, USMMLA as non-streaming
33
target/arm: Mark string/histo/crypto as non-streaming
34
target/arm: Mark gather/scatter load/store as non-streaming
35
target/arm: Mark gather prefetch as non-streaming
36
target/arm: Mark LDFF1 and LDNF1 as non-streaming
37
target/arm: Mark LD1RO as non-streaming
38
target/arm: Add SME enablement checks
39
target/arm: Handle SME in sve_access_check
40
target/arm: Implement SME RDSVL, ADDSVL, ADDSPL
41
target/arm: Implement SME ZERO
42
target/arm: Implement SME MOVA
43
target/arm: Implement SME LD1, ST1
44
target/arm: Export unpredicated ld/st from translate-sve.c
45
target/arm: Implement SME LDR, STR
46
target/arm: Implement SME ADDHA, ADDVA
47
target/arm: Implement FMOPA, FMOPS (non-widening)
48
target/arm: Implement BFMOPA, BFMOPS
49
target/arm: Implement FMOPA, FMOPS (widening)
50
target/arm: Implement SME integer outer product
51
target/arm: Implement PSEL
52
target/arm: Implement REVD
53
target/arm: Implement SCLAMP, UCLAMP
54
target/arm: Reset streaming sve state on exception boundaries
55
target/arm: Enable SME for -cpu max
56
linux-user/aarch64: Clear tpidr2_el0 if CLONE_SETTLS
57
linux-user/aarch64: Reset PSTATE.SM on syscalls
58
linux-user/aarch64: Add SM bit to SVE signal context
59
linux-user/aarch64: Tidy target_restore_sigframe error return
60
linux-user/aarch64: Do not allow duplicate or short sve records
61
linux-user/aarch64: Verify extra record lock succeeded
62
linux-user/aarch64: Move sve record checks into restore
63
linux-user/aarch64: Implement SME signal handling
64
linux-user: Rename sve prctls
65
linux-user/aarch64: Implement PR_SME_GET_VL, PR_SME_SET_VL
66
target/arm: Only set ZEN in reset if SVE present
67
target/arm: Enable SME for user-only
68
linux-user/aarch64: Add SME related hwcap entries
30
69
31
David CARLIER (1):
70
docs/system/arm/emulation.rst | 4 +
32
util/oslib-posix : qemu_init_exec_dir implementation for Mac
71
linux-user/aarch64/target_cpu.h | 5 +-
33
72
linux-user/aarch64/target_prctl.h | 62 +-
34
Peter Maydell (23):
73
target/arm/cpu.h | 7 +
35
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
74
target/arm/helper-sme.h | 126 ++++
36
target/arm: Convert Neon 2-reg-misc pairwise ops to decodetree
75
target/arm/helper-sve.h | 4 +
37
target/arm: Convert VZIP, VUZP to decodetree
76
target/arm/helper.h | 18 +
38
target/arm: Convert Neon narrowing moves to decodetree
77
target/arm/translate-a64.h | 45 ++
39
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
78
target/arm/translate.h | 16 +
40
target/arm: Convert Neon VCVT f16/f32 insns to decodetree
79
target/arm/sme-fa64.decode | 60 ++
41
target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree
80
target/arm/sme.decode | 88 +++
42
target/arm: Convert Neon 2-reg-misc crypto operations to decodetree
81
target/arm/sve.decode | 41 +-
43
target/arm: Rename NeonGenOneOpFn to NeonGenOne64OpFn
82
linux-user/aarch64/cpu_loop.c | 9 +
44
target/arm: Fix capitalization in NeonGenTwo{Single, Double}OPFn typedefs
83
linux-user/aarch64/signal.c | 243 ++++++--
45
target/arm: Make gen_swap_half() take separate src and dest
84
linux-user/elfload.c | 20 +
46
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
85
linux-user/syscall.c | 28 +-
47
target/arm: Convert remaining simple 2-reg-misc Neon ops
86
target/arm/cpu.c | 35 +-
48
target/arm: Convert Neon VQABS, VQNEG to decodetree
87
target/arm/cpu64.c | 11 +
49
target/arm: Convert simple fp Neon 2-reg-misc insns
88
target/arm/helper.c | 56 +-
50
target/arm: Convert Neon 2-reg-misc fp-compare-with-zero insns to decodetree
89
target/arm/sme_helper.c | 1140 +++++++++++++++++++++++++++++++++++++
51
target/arm: Convert Neon 2-reg-misc VRINT insns to decodetree
90
target/arm/sve_helper.c | 28 +
52
target/arm: Convert Neon 2-reg-misc VCVT insns to decodetree
91
target/arm/translate-a64.c | 103 +++-
53
target/arm: Convert Neon VSWP to decodetree
92
target/arm/translate-sme.c | 373 ++++++++++++
54
target/arm: Convert Neon VTRN to decodetree
93
target/arm/translate-sve.c | 393 ++++++++++---
55
target/arm: Move some functions used only in translate-neon.inc.c to that file
94
target/arm/translate-vfp.c | 12 +
56
target/arm: Remove unnecessary gen_io_end() calls
95
target/arm/translate.c | 2 +
57
target/arm: Remove dead code relating to SABA and UABA
96
target/arm/vec_helper.c | 24 +
58
97
target/arm/meson.build | 3 +
59
Philippe Mathieu-Daudé (15):
98
28 files changed, 2821 insertions(+), 135 deletions(-)
60
hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
99
create mode 100644 target/arm/sme-fa64.decode
61
hw/i2c/versatile_i2c: Add definitions for register addresses
100
create mode 100644 target/arm/sme.decode
62
hw/i2c/versatile_i2c: Add SCL/SDA definitions
101
create mode 100644 target/arm/translate-sme.c
63
hw/i2c: Add header for ARM SBCon two-wire serial bus interface
64
hw/arm: Use TYPE_VERSATILE_I2C instead of hardcoded string
65
hw/arm/mps2: Document CMSDK/FPGA APB subsystem sections
66
hw/arm/mps2: Rename CMSDK AHB peripheral region
67
hw/arm/mps2: Add CMSDK APB watchdog device
68
hw/arm/mps2: Add CMSDK AHB GPIO peripherals as unimplemented devices
69
hw/arm/mps2: Map the FPGA I/O block
70
hw/arm/mps2: Add SPI devices
71
hw/arm/mps2: Add I2C devices
72
hw/arm/mps2: Add audio I2S interface as unimplemented device
73
hw/arm/mps2-tz: Use the ARM SBCon two-wire serial bus interface
74
target/arm: Check supported KVM features globally (not per vCPU)
75
76
Shameer Kolothum (1):
77
arm/virt: Add memory hot remove support
78
79
include/hw/i2c/arm_sbcon_i2c.h | 35 ++
80
target/arm/cpu.h | 2 +-
81
target/arm/kvm_arm.h | 21 +-
82
target/arm/translate.h | 8 +-
83
target/arm/neon-dp.decode | 106 ++++
84
hw/acpi/generic_event_device.c | 29 +
85
hw/arm/mps2-tz.c | 23 +-
86
hw/arm/mps2.c | 65 ++-
87
hw/arm/realview.c | 3 +-
88
hw/arm/versatilepb.c | 3 +-
89
hw/arm/vexpress.c | 3 +-
90
hw/arm/virt.c | 63 +-
91
hw/i2c/versatile_i2c.c | 38 +-
92
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
93
target/arm/cpu.c | 2 +-
94
target/arm/cpu64.c | 10 +-
95
target/arm/kvm.c | 4 +-
96
target/arm/kvm64.c | 14 +-
97
target/arm/translate-a64.c | 20 +-
98
target/arm/translate-neon.inc.c | 1191 +++++++++++++++++++++++++++++++++++++-
99
target/arm/translate-vfp.inc.c | 7 +-
100
target/arm/translate.c | 1064 +---------------------------------
101
tests/qtest/arm-cpu-features.c | 38 +-
102
util/oslib-posix.c | 15 +
103
MAINTAINERS | 1 +
104
hw/arm/Kconfig | 8 +-
105
hw/watchdog/trace-events | 1 +
106
27 files changed, 1624 insertions(+), 1151 deletions(-)
107
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
108
diff view generated by jsdifflib
1
Convert the Neon VQABS and VQNEG insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Since these are the only ones which need cpu_env passing to
3
the helper, we wrap the helper rather than creating a whole
4
new do_2misc_env() function.
5
2
3
Dump SVCR, plus use the correct access check for Streaming Mode.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220708151540.18136-2-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-15-peter.maydell@linaro.org
9
---
9
---
10
target/arm/neon-dp.decode | 3 +++
10
target/arm/cpu.c | 17 ++++++++++++++++-
11
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
11
1 file changed, 16 insertions(+), 1 deletion(-)
12
target/arm/translate.c | 30 ++--------------------------
13
3 files changed, 40 insertions(+), 28 deletions(-)
14
12
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
15
--- a/target/arm/cpu.c
18
+++ b/target/arm/neon-dp.decode
16
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
20
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
18
int i;
21
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
19
int el = arm_current_el(env);
22
20
const char *ns_status;
23
+ VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
21
+ bool sve;
24
+ VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
22
25
+
23
qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
26
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
24
for (i = 0; i < 32; i++) {
27
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
28
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
26
el,
29
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
psr & PSTATE_SP ? 'h' : 't');
30
index XXXXXXX..XXXXXXX 100644
28
31
--- a/target/arm/translate-neon.inc.c
29
+ if (cpu_isar_feature(aa64_sme, cpu)) {
32
+++ b/target/arm/translate-neon.inc.c
30
+ qemu_fprintf(f, " SVCR=%08" PRIx64 " %c%c",
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
31
+ env->svcr,
32
+ (FIELD_EX64(env->svcr, SVCR, ZA) ? 'Z' : '-'),
33
+ (FIELD_EX64(env->svcr, SVCR, SM) ? 'S' : '-'));
34
+ }
35
if (cpu_isar_feature(aa64_bti, cpu)) {
36
qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
34
}
37
}
35
return do_2misc(s, a, gen_helper_rsqrte_u32);
38
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
36
}
39
qemu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
37
+
40
vfp_get_fpcr(env), vfp_get_fpsr(env));
38
+#define WRAP_1OP_ENV_FN(WRAPNAME, FUNC) \
41
39
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m) \
42
- if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
40
+ { \
43
+ if (cpu_isar_feature(aa64_sme, cpu) && FIELD_EX64(env->svcr, SVCR, SM)) {
41
+ FUNC(d, cpu_env, m); \
44
+ sve = sme_exception_el(env, el) == 0;
45
+ } else if (cpu_isar_feature(aa64_sve, cpu)) {
46
+ sve = sve_exception_el(env, el) == 0;
47
+ } else {
48
+ sve = false;
42
+ }
49
+ }
43
+
50
+
44
+WRAP_1OP_ENV_FN(gen_VQABS_s8, gen_helper_neon_qabs_s8)
51
+ if (sve) {
45
+WRAP_1OP_ENV_FN(gen_VQABS_s16, gen_helper_neon_qabs_s16)
52
int j, zcr_len = sve_vqm1_for_el(env, el);
46
+WRAP_1OP_ENV_FN(gen_VQABS_s32, gen_helper_neon_qabs_s32)
53
47
+WRAP_1OP_ENV_FN(gen_VQNEG_s8, gen_helper_neon_qneg_s8)
54
for (i = 0; i <= FFR_PRED_NUM; i++) {
48
+WRAP_1OP_ENV_FN(gen_VQNEG_s16, gen_helper_neon_qneg_s16)
49
+WRAP_1OP_ENV_FN(gen_VQNEG_s32, gen_helper_neon_qneg_s32)
50
+
51
+static bool trans_VQABS(DisasContext *s, arg_2misc *a)
52
+{
53
+ static NeonGenOneOpFn * const fn[] = {
54
+ gen_VQABS_s8,
55
+ gen_VQABS_s16,
56
+ gen_VQABS_s32,
57
+ NULL,
58
+ };
59
+ return do_2misc(s, a, fn[a->size]);
60
+}
61
+
62
+static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
63
+{
64
+ static NeonGenOneOpFn * const fn[] = {
65
+ gen_VQNEG_s8,
66
+ gen_VQNEG_s16,
67
+ gen_VQNEG_s32,
68
+ NULL,
69
+ };
70
+ return do_2misc(s, a, fn[a->size]);
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
case NEON_2RM_VNEG_F:
78
case NEON_2RM_VRECPE:
79
case NEON_2RM_VRSQRTE:
80
+ case NEON_2RM_VQABS:
81
+ case NEON_2RM_VQNEG:
82
/* handled by decodetree */
83
return 1;
84
case NEON_2RM_VTRN:
85
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
86
for (pass = 0; pass < (q ? 4 : 2); pass++) {
87
tmp = neon_load_reg(rm, pass);
88
switch (op) {
89
- case NEON_2RM_VQABS:
90
- switch (size) {
91
- case 0:
92
- gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
93
- break;
94
- case 1:
95
- gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
96
- break;
97
- case 2:
98
- gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
99
- break;
100
- default: abort();
101
- }
102
- break;
103
- case NEON_2RM_VQNEG:
104
- switch (size) {
105
- case 0:
106
- gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
107
- break;
108
- case 1:
109
- gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
110
- break;
111
- case 2:
112
- gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
113
- break;
114
- default: abort();
115
- }
116
- break;
117
case NEON_2RM_VCGT0_F:
118
{
119
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
120
--
55
--
121
2.20.1
56
2.25.1
122
123
diff view generated by jsdifflib
1
The NeonGenOneOpFn typedef breaks with the pattern of the other
1
From: Richard Henderson <richard.henderson@linaro.org>
2
NeonGen*Fn typedefs, because it is a TCGv_i64 -> TCGv_i64 operation
3
but it does not have '64' in its name. Rename it to NeonGenOne64OpFn,
4
so that the old name is available for a TCGv_i32 -> TCGv_i32 operation
5
(which we will need in a subsequent commit).
6
2
3
This includes the build rules for the decoder, and the
4
new file for translation, but excludes any instructions.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-10-peter.maydell@linaro.org
10
---
10
---
11
target/arm/translate.h | 2 +-
11
target/arm/translate-a64.h | 1 +
12
target/arm/translate-a64.c | 4 ++--
12
target/arm/sme.decode | 20 ++++++++++++++++++++
13
2 files changed, 3 insertions(+), 3 deletions(-)
13
target/arm/translate-a64.c | 7 ++++++-
14
target/arm/translate-sme.c | 35 +++++++++++++++++++++++++++++++++++
15
target/arm/meson.build | 2 ++
16
5 files changed, 64 insertions(+), 1 deletion(-)
17
create mode 100644 target/arm/sme.decode
18
create mode 100644 target/arm/translate-sme.c
14
19
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
22
--- a/target/arm/translate-a64.h
18
+++ b/target/arm/translate.h
23
+++ b/target/arm/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
24
@@ -XXX,XX +XXX,XX @@ static inline int pred_gvec_reg_size(DisasContext *s)
20
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
25
}
21
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
26
22
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
27
bool disas_sve(DisasContext *, uint32_t);
23
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
28
+bool disas_sme(DisasContext *, uint32_t);
24
+typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
29
25
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
30
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
26
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
31
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
27
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
32
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/target/arm/sme.decode
37
@@ -XXX,XX +XXX,XX @@
38
+# AArch64 SME instruction descriptions
39
+#
40
+# Copyright (c) 2022 Linaro, Ltd
41
+#
42
+# This library is free software; you can redistribute it and/or
43
+# modify it under the terms of the GNU Lesser General Public
44
+# License as published by the Free Software Foundation; either
45
+# version 2.1 of the License, or (at your option) any later version.
46
+#
47
+# This library is distributed in the hope that it will be useful,
48
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
49
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50
+# Lesser General Public License for more details.
51
+#
52
+# You should have received a copy of the GNU Lesser General Public
53
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
54
+
55
+#
56
+# This file is processed by scripts/decodetree.py
57
+#
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
60
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
62
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
33
} else {
63
}
34
for (pass = 0; pass < maxpass; pass++) {
64
35
TCGv_i64 tcg_op = tcg_temp_new_i64();
65
switch (extract32(insn, 25, 4)) {
36
- NeonGenOneOpFn *genfn;
66
- case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
37
- static NeonGenOneOpFn * const fns[2][2] = {
67
+ case 0x0:
38
+ NeonGenOne64OpFn *genfn;
68
+ if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
39
+ static NeonGenOne64OpFn * const fns[2][2] = {
69
+ unallocated_encoding(s);
40
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
70
+ }
41
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
71
+ break;
42
};
72
+ case 0x1: case 0x3: /* UNALLOCATED */
73
unallocated_encoding(s);
74
break;
75
case 0x2:
76
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
77
new file mode 100644
78
index XXXXXXX..XXXXXXX
79
--- /dev/null
80
+++ b/target/arm/translate-sme.c
81
@@ -XXX,XX +XXX,XX @@
82
+/*
83
+ * AArch64 SME translation
84
+ *
85
+ * Copyright (c) 2022 Linaro, Ltd
86
+ *
87
+ * This library is free software; you can redistribute it and/or
88
+ * modify it under the terms of the GNU Lesser General Public
89
+ * License as published by the Free Software Foundation; either
90
+ * version 2.1 of the License, or (at your option) any later version.
91
+ *
92
+ * This library is distributed in the hope that it will be useful,
93
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
94
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95
+ * Lesser General Public License for more details.
96
+ *
97
+ * You should have received a copy of the GNU Lesser General Public
98
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
99
+ */
100
+
101
+#include "qemu/osdep.h"
102
+#include "cpu.h"
103
+#include "tcg/tcg-op.h"
104
+#include "tcg/tcg-op-gvec.h"
105
+#include "tcg/tcg-gvec-desc.h"
106
+#include "translate.h"
107
+#include "exec/helper-gen.h"
108
+#include "translate-a64.h"
109
+#include "fpu/softfloat.h"
110
+
111
+
112
+/*
113
+ * Include the generated decoder.
114
+ */
115
+
116
+#include "decode-sme.c.inc"
117
diff --git a/target/arm/meson.build b/target/arm/meson.build
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/meson.build
120
+++ b/target/arm/meson.build
121
@@ -XXX,XX +XXX,XX @@
122
gen = [
123
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
124
+ decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
125
decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
126
decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
127
decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
128
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
129
'sme_helper.c',
130
'translate-a64.c',
131
'translate-sve.c',
132
+ 'translate-sme.c',
133
))
134
135
arm_softmmu_ss = ss.source_set()
43
--
136
--
44
2.20.1
137
2.25.1
45
46
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc insns which are implemented with
1
From: Richard Henderson <richard.henderson@linaro.org>
2
simple calls to functions that take the input, output and
2
3
fpstatus pointer.
3
This new behaviour is in the ARM pseudocode function
4
4
AArch64.CheckFPAdvSIMDEnabled, which applies to AArch32
5
via AArch32.CheckAdvSIMDOrFPEnabled when the EL to which
6
the trap would be delivered is in AArch64 mode.
7
8
Given that ARMv9 drops support for AArch32 outside EL0, the trap EL
9
detection ought to be trivially true, but the pseudocode still contains
10
a number of conditions, and QEMU has not yet committed to dropping A32
11
support for EL[12] when v9 features are present.
12
13
Since the computation of SME_TRAP_NONSTREAMING is necessarily different
14
for the two modes, we might as well preserve bits within TBFLAG_ANY and
15
allocate separate bits within TBFLAG_A32 and TBFLAG_A64 instead.
16
17
Note that DDI0616A.a has typos for bits [22:21] of LD1RO in the table
18
of instructions illegal in streaming mode.
19
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20220708151540.18136-4-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-16-peter.maydell@linaro.org
8
---
24
---
9
target/arm/translate.h | 1 +
25
target/arm/cpu.h | 7 +++
10
target/arm/neon-dp.decode | 8 +++++
26
target/arm/translate.h | 4 ++
11
target/arm/translate-neon.inc.c | 62 +++++++++++++++++++++++++++++++++
27
target/arm/sme-fa64.decode | 90 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 56 ++++-------------------------
28
target/arm/helper.c | 41 +++++++++++++++++
13
4 files changed, 78 insertions(+), 49 deletions(-)
29
target/arm/translate-a64.c | 40 ++++++++++++++++-
14
30
target/arm/translate-vfp.c | 12 +++++
31
target/arm/translate.c | 2 +
32
target/arm/meson.build | 1 +
33
8 files changed, 195 insertions(+), 2 deletions(-)
34
create mode 100644 target/arm/sme-fa64.decode
35
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
40
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
41
* the same thing as the current security state of the processor!
42
*/
43
FIELD(TBFLAG_A32, NS, 10, 1)
44
+/*
45
+ * Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not.
46
+ * This requires an SME trap from AArch32 mode when using NEON.
47
+ */
48
+FIELD(TBFLAG_A32, SME_TRAP_NONSTREAMING, 11, 1)
49
50
/*
51
* Bit usage when in AArch32 state, for M-profile only.
52
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
53
FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
54
FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
55
FIELD(TBFLAG_A64, SVL, 24, 4)
56
+/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
57
+FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
58
59
/*
60
* Helpers for using the above.
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
61
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
63
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
64
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
65
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
20
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
66
bool pstate_sm;
21
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
67
/* True if PSTATE.ZA is set. */
22
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
68
bool pstate_za;
23
+typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
69
+ /* True if non-streaming insns should raise an SME Streaming exception. */
24
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
70
+ bool sme_trap_nonstreaming;
25
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
71
+ /* True if the current instruction is non-streaming. */
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
72
+ bool is_nonstreaming;
27
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
73
/* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
28
index XXXXXXX..XXXXXXX 100644
74
bool mve_no_pred;
29
--- a/target/arm/neon-dp.decode
75
/*
30
+++ b/target/arm/neon-dp.decode
76
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
31
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
77
new file mode 100644
32
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
78
index XXXXXXX..XXXXXXX
33
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
79
--- /dev/null
34
80
+++ b/target/arm/sme-fa64.decode
35
+ VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
81
@@ -XXX,XX +XXX,XX @@
36
+
82
+# AArch64 SME allowed instruction decoding
37
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
83
+#
38
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
84
+# Copyright (c) 2022 Linaro, Ltd
39
85
+#
40
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
86
+# This library is free software; you can redistribute it and/or
41
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
87
+# modify it under the terms of the GNU Lesser General Public
42
+ VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
88
+# License as published by the Free Software Foundation; either
43
+ VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
89
+# version 2.1 of the License, or (at your option) any later version.
44
+ VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
90
+#
45
+ VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
91
+# This library is distributed in the hope that it will be useful,
46
+ VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
92
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
93
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48
]
94
+# Lesser General Public License for more details.
49
95
+#
50
# Subgroup for size != 0b11
96
+# You should have received a copy of the GNU Lesser General Public
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
97
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
52
index XXXXXXX..XXXXXXX 100644
98
+
53
--- a/target/arm/translate-neon.inc.c
99
+#
54
+++ b/target/arm/translate-neon.inc.c
100
+# This file is processed by scripts/decodetree.py
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
101
+#
56
};
102
+
57
return do_2misc(s, a, fn[a->size]);
103
+# These patterns are taken from Appendix E1.1 of DDI0616 A.a,
104
+# Arm Architecture Reference Manual Supplement,
105
+# The Scalable Matrix Extension (SME), for Armv9-A
106
+
107
+{
108
+ [
109
+ OK 0-00 1110 0000 0001 0010 11-- ---- ---- # SMOV W|Xd,Vn.B[0]
110
+ OK 0-00 1110 0000 0010 0010 11-- ---- ---- # SMOV W|Xd,Vn.H[0]
111
+ OK 0100 1110 0000 0100 0010 11-- ---- ---- # SMOV Xd,Vn.S[0]
112
+ OK 0000 1110 0000 0001 0011 11-- ---- ---- # UMOV Wd,Vn.B[0]
113
+ OK 0000 1110 0000 0010 0011 11-- ---- ---- # UMOV Wd,Vn.H[0]
114
+ OK 0000 1110 0000 0100 0011 11-- ---- ---- # UMOV Wd,Vn.S[0]
115
+ OK 0100 1110 0000 1000 0011 11-- ---- ---- # UMOV Xd,Vn.D[0]
116
+ ]
117
+ FAIL 0--0 111- ---- ---- ---- ---- ---- ---- # Advanced SIMD vector operations
118
+}
119
+
120
+{
121
+ [
122
+ OK 0101 1110 --1- ---- 11-1 11-- ---- ---- # FMULX/FRECPS/FRSQRTS (scalar)
123
+ OK 0101 1110 -10- ---- 00-1 11-- ---- ---- # FMULX/FRECPS/FRSQRTS (scalar, FP16)
124
+ OK 01-1 1110 1-10 0001 11-1 10-- ---- ---- # FRECPE/FRSQRTE/FRECPX (scalar)
125
+ OK 01-1 1110 1111 1001 11-1 10-- ---- ---- # FRECPE/FRSQRTE/FRECPX (scalar, FP16)
126
+ ]
127
+ FAIL 01-1 111- ---- ---- ---- ---- ---- ---- # Advanced SIMD single-element operations
128
+}
129
+
130
+FAIL 0-00 110- ---- ---- ---- ---- ---- ---- # Advanced SIMD structure load/store
131
+FAIL 1100 1110 ---- ---- ---- ---- ---- ---- # Advanced SIMD cryptography extensions
132
+FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
133
+
134
+# These are the "avoidance of doubt" final table of Illegal Advanced SIMD instructions
135
+# We don't actually need to include these, as the default is OK.
136
+# -001 111- ---- ---- ---- ---- ---- ---- # Scalar floating-point operations
137
+# --10 110- ---- ---- ---- ---- ---- ---- # Load/store pair of FP registers
138
+# --01 1100 ---- ---- ---- ---- ---- ---- # Load FP register (PC-relative literal)
139
+# --11 1100 --0- ---- ---- ---- ---- ---- # Load/store FP register (unscaled imm)
140
+# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
141
+# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
142
+
143
+FAIL 0000 0100 --1- ---- 1010 ---- ---- ---- # ADR
144
+FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
145
+FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
146
+FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
147
+FAIL 0010 0101 --10 1--- 1001 ---- ---- ---- # WRFFR, SETFFR
148
+FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
149
+FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
150
+FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
151
+FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
152
+FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
153
+FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
154
+FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
155
+FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
156
+FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
157
+FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
158
+FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
159
+FAIL 1000 010- -01- ---- 1--- ---- ---- ---- # SVE 32-bit gather load (vector+imm)
160
+FAIL 1000 0100 0-0- ---- 0--- ---- ---- ---- # SVE 32-bit gather load byte (scalar+vector)
161
+FAIL 1000 0100 1--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load half (scalar+vector)
162
+FAIL 1000 0101 0--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load word (scalar+vector)
163
+FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
164
+FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
165
+FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
166
+FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
167
+FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
168
+FAIL 1110 010- -00- ---- 001- ---- ---- ---- # SVE2 64-bit scatter NT store (vector+scalar)
169
+FAIL 1110 010- -10- ---- 001- ---- ---- ---- # SVE2 32-bit scatter NT store (vector+scalar)
170
+FAIL 1110 010- ---- ---- 1-0- ---- ---- ---- # SVE scatter store (scalar+32-bit vector)
171
+FAIL 1110 010- ---- ---- 101- ---- ---- ---- # SVE scatter store (misc)
172
diff --git a/target/arm/helper.c b/target/arm/helper.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/arm/helper.c
175
+++ b/target/arm/helper.c
176
@@ -XXX,XX +XXX,XX @@ int sme_exception_el(CPUARMState *env, int el)
177
return 0;
58
}
178
}
59
+
179
60
+static bool do_2misc_fp(DisasContext *s, arg_2misc *a,
180
+/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
61
+ NeonGenOneSingleOpFn *fn)
181
+static bool sme_fa64(CPUARMState *env, int el)
62
+{
182
+{
63
+ int pass;
183
+ if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
64
+ TCGv_ptr fpst;
65
+
66
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
67
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
68
+ return false;
184
+ return false;
69
+ }
185
+ }
70
+
186
+
71
+ /* UNDEF accesses to D16-D31 if they don't exist. */
187
+ if (el <= 1 && !el_is_in_host(env, el)) {
72
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
188
+ if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
73
+ ((a->vd | a->vm) & 0x10)) {
189
+ return false;
190
+ }
191
+ }
192
+ if (el <= 2 && arm_is_el2_enabled(env)) {
193
+ if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
194
+ return false;
195
+ }
196
+ }
197
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
198
+ if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
199
+ return false;
200
+ }
201
+ }
202
+
203
+ return true;
204
+}
205
+
206
/*
207
* Given that SVE is enabled, return the vector length for EL.
208
*/
209
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
210
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
211
}
212
213
+ /*
214
+ * The SME exception we are testing for is raised via
215
+ * AArch64.CheckFPAdvSIMDEnabled(), as called from
216
+ * AArch32.CheckAdvSIMDOrFPEnabled().
217
+ */
218
+ if (el == 0
219
+ && FIELD_EX64(env->svcr, SVCR, SM)
220
+ && (!arm_is_el2_enabled(env)
221
+ || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
222
+ && arm_el_is_aa64(env, 1)
223
+ && !sme_fa64(env, el)) {
224
+ DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
225
+ }
226
+
227
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
231
}
232
if (FIELD_EX64(env->svcr, SVCR, SM)) {
233
DP_TBFLAG_A64(flags, PSTATE_SM, 1);
234
+ DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
235
}
236
DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
237
}
238
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/translate-a64.c
241
+++ b/target/arm/translate-a64.c
242
@@ -XXX,XX +XXX,XX @@ static void do_vec_ld(DisasContext *s, int destidx, int element,
243
* unallocated-encoding checks (otherwise the syndrome information
244
* for the resulting exception will be incorrect).
245
*/
246
-static bool fp_access_check(DisasContext *s)
247
+static bool fp_access_check_only(DisasContext *s)
248
{
249
if (s->fp_excp_el) {
250
assert(!s->fp_access_checked);
251
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s)
252
return true;
253
}
254
255
+static bool fp_access_check(DisasContext *s)
256
+{
257
+ if (!fp_access_check_only(s)) {
74
+ return false;
258
+ return false;
75
+ }
259
+ }
76
+
260
+ if (s->sme_trap_nonstreaming && s->is_nonstreaming) {
77
+ if (a->size != 2) {
261
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
78
+ /* TODO: FP16 will be the size == 1 case */
262
+ syn_smetrap(SME_ET_Streaming, false));
79
+ return false;
263
+ return false;
80
+ }
264
+ }
81
+
265
+ return true;
82
+ if ((a->vd | a->vm) & a->q) {
266
+}
267
+
268
/* Check that SVE access is enabled. If it is, return true.
269
* If not, emit code to generate an appropriate exception and return false.
270
*/
271
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
272
default:
273
g_assert_not_reached();
274
}
275
- if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
276
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
277
return;
278
} else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
279
return;
280
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
281
}
282
}
283
284
+/*
285
+ * Include the generated SME FA64 decoder.
286
+ */
287
+
288
+#include "decode-sme-fa64.c.inc"
289
+
290
+static bool trans_OK(DisasContext *s, arg_OK *a)
291
+{
292
+ return true;
293
+}
294
+
295
+static bool trans_FAIL(DisasContext *s, arg_OK *a)
296
+{
297
+ s->is_nonstreaming = true;
298
+ return true;
299
+}
300
+
301
/**
302
* is_guarded_page:
303
* @env: The cpu environment
304
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
305
dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
306
dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
307
dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
308
+ dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
309
dc->vec_len = 0;
310
dc->vec_stride = 0;
311
dc->cp_regs = arm_cpu->cp_regs;
312
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
313
}
314
}
315
316
+ s->is_nonstreaming = false;
317
+ if (s->sme_trap_nonstreaming) {
318
+ disas_sme_fa64(s, insn);
319
+ }
320
+
321
switch (extract32(insn, 25, 4)) {
322
case 0x0:
323
if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
324
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/target/arm/translate-vfp.c
327
+++ b/target/arm/translate-vfp.c
328
@@ -XXX,XX +XXX,XX @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
329
return false;
330
}
331
332
+ /*
333
+ * Note that rebuild_hflags_a32 has already accounted for being in EL0
334
+ * and the higher EL in A64 mode, etc. Unlike A64 mode, there do not
335
+ * appear to be any insns which touch VFP which are allowed.
336
+ */
337
+ if (s->sme_trap_nonstreaming) {
338
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
339
+ syn_smetrap(SME_ET_Streaming,
340
+ s->base.pc_next - s->pc_curr == 2));
83
+ return false;
341
+ return false;
84
+ }
342
+ }
85
+
343
+
86
+ if (!vfp_access_check(s)) {
344
if (!s->vfp_enabled && !ignore_vfp_enabled) {
87
+ return true;
345
assert(!arm_dc_feature(s, ARM_FEATURE_M));
88
+ }
346
unallocated_encoding(s);
89
+
90
+ fpst = get_fpstatus_ptr(1);
91
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
92
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
93
+ fn(tmp, tmp, fpst);
94
+ neon_store_reg(a->vd, pass, tmp);
95
+ }
96
+ tcg_temp_free_ptr(fpst);
97
+
98
+ return true;
99
+}
100
+
101
+#define DO_2MISC_FP(INSN, FUNC) \
102
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
103
+ { \
104
+ return do_2misc_fp(s, a, FUNC); \
105
+ }
106
+
107
+DO_2MISC_FP(VRECPE_F, gen_helper_recpe_f32)
108
+DO_2MISC_FP(VRSQRTE_F, gen_helper_rsqrte_f32)
109
+DO_2MISC_FP(VCVT_FS, gen_helper_vfp_sitos)
110
+DO_2MISC_FP(VCVT_FU, gen_helper_vfp_uitos)
111
+DO_2MISC_FP(VCVT_SF, gen_helper_vfp_tosizs)
112
+DO_2MISC_FP(VCVT_UF, gen_helper_vfp_touizs)
113
+
114
+static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
115
+{
116
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
117
+ return false;
118
+ }
119
+ return do_2misc_fp(s, a, gen_helper_rints_exact);
120
+}
121
diff --git a/target/arm/translate.c b/target/arm/translate.c
347
diff --git a/target/arm/translate.c b/target/arm/translate.c
122
index XXXXXXX..XXXXXXX 100644
348
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/translate.c
349
--- a/target/arm/translate.c
124
+++ b/target/arm/translate.c
350
+++ b/target/arm/translate.c
125
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
351
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
126
case NEON_2RM_VRSQRTE:
352
dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
127
case NEON_2RM_VQABS:
353
dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
128
case NEON_2RM_VQNEG:
354
}
129
+ case NEON_2RM_VRECPE_F:
355
+ dc->sme_trap_nonstreaming =
130
+ case NEON_2RM_VRSQRTE_F:
356
+ EX_TBFLAG_A32(tb_flags, SME_TRAP_NONSTREAMING);
131
+ case NEON_2RM_VCVT_FS:
357
}
132
+ case NEON_2RM_VCVT_FU:
358
dc->cp_regs = cpu->cp_regs;
133
+ case NEON_2RM_VCVT_SF:
359
dc->features = env->features;
134
+ case NEON_2RM_VCVT_UF:
360
diff --git a/target/arm/meson.build b/target/arm/meson.build
135
+ case NEON_2RM_VRINTX:
361
index XXXXXXX..XXXXXXX 100644
136
/* handled by decodetree */
362
--- a/target/arm/meson.build
137
return 1;
363
+++ b/target/arm/meson.build
138
case NEON_2RM_VTRN:
364
@@ -XXX,XX +XXX,XX @@
139
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
365
gen = [
140
tcg_temp_free_i32(tcg_rmode);
366
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
141
break;
367
decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
142
}
368
+ decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'),
143
- case NEON_2RM_VRINTX:
369
decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
144
- {
370
decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
145
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
371
decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
146
- gen_helper_rints_exact(tmp, tmp, fpstatus);
147
- tcg_temp_free_ptr(fpstatus);
148
- break;
149
- }
150
case NEON_2RM_VCVTAU:
151
case NEON_2RM_VCVTAS:
152
case NEON_2RM_VCVTNU:
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
154
tcg_temp_free_ptr(fpst);
155
break;
156
}
157
- case NEON_2RM_VRECPE_F:
158
- {
159
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
160
- gen_helper_recpe_f32(tmp, tmp, fpstatus);
161
- tcg_temp_free_ptr(fpstatus);
162
- break;
163
- }
164
- case NEON_2RM_VRSQRTE_F:
165
- {
166
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
167
- gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
168
- tcg_temp_free_ptr(fpstatus);
169
- break;
170
- }
171
- case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
172
- {
173
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
174
- gen_helper_vfp_sitos(tmp, tmp, fpstatus);
175
- tcg_temp_free_ptr(fpstatus);
176
- break;
177
- }
178
- case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
179
- {
180
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
181
- gen_helper_vfp_uitos(tmp, tmp, fpstatus);
182
- tcg_temp_free_ptr(fpstatus);
183
- break;
184
- }
185
- case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
186
- {
187
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
188
- gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
189
- tcg_temp_free_ptr(fpstatus);
190
- break;
191
- }
192
- case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
193
- {
194
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
- gen_helper_vfp_touizs(tmp, tmp, fpstatus);
196
- tcg_temp_free_ptr(fpstatus);
197
- break;
198
- }
199
default:
200
/* Reserved op values were caught by the
201
* neon_2rm_sizes[] check earlier.
202
--
372
--
203
2.20.1
373
2.25.1
204
205
diff view generated by jsdifflib
1
All the other typedefs like these spell "Op" with a lowercase 'p';
1
From: Richard Henderson <richard.henderson@linaro.org>
2
remane the NeonGenTwoSingleOPFn and NeonGenTwoDoubleOPFn typedefs to
3
match.
4
2
3
Mark ADR as a non-streaming instruction, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Removing entries from sme-fa64.decode is an easy way to see
7
what remains to be done.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220708151540.18136-5-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-11-peter.maydell@linaro.org
8
---
13
---
9
target/arm/translate.h | 4 ++--
14
target/arm/translate.h | 7 +++++++
10
target/arm/translate-a64.c | 4 ++--
15
target/arm/sme-fa64.decode | 1 -
11
target/arm/translate-neon.inc.c | 2 +-
16
target/arm/translate-sve.c | 8 ++++----
12
3 files changed, 5 insertions(+), 5 deletions(-)
17
3 files changed, 11 insertions(+), 5 deletions(-)
13
18
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
21
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
22
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
23
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
19
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
24
static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
20
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
25
{ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); }
21
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
26
22
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
27
+#define TRANS_FEAT_NONSTREAMING(NAME, FEAT, FUNC, ...) \
23
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
28
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
24
+typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
29
+ { \
25
+typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
30
+ s->is_nonstreaming = true; \
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
31
+ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
27
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
32
+ }
28
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
33
+
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
34
#endif /* TARGET_ARM_TRANSLATE_H */
35
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
30
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
37
--- a/target/arm/sme-fa64.decode
32
+++ b/target/arm/translate-a64.c
38
+++ b/target/arm/sme-fa64.decode
33
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
39
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
40
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
35
TCGv_i64 tcg_zero = tcg_const_i64(0);
41
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
36
TCGv_i64 tcg_res = tcg_temp_new_i64();
42
37
- NeonGenTwoDoubleOPFn *genfn;
43
-FAIL 0000 0100 --1- ---- 1010 ---- ---- ---- # ADR
38
+ NeonGenTwoDoubleOpFn *genfn;
44
FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
39
bool swap = false;
45
FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
40
int pass;
46
FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
41
47
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
42
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
43
TCGv_i32 tcg_op = tcg_temp_new_i32();
44
TCGv_i32 tcg_zero = tcg_const_i32(0);
45
TCGv_i32 tcg_res = tcg_temp_new_i32();
46
- NeonGenTwoSingleOPFn *genfn;
47
+ NeonGenTwoSingleOpFn *genfn;
48
bool swap = false;
49
int pass, maxpasses;
50
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
49
--- a/target/arm/translate-sve.c
54
+++ b/target/arm/translate-neon.inc.c
50
+++ b/target/arm/translate-sve.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
51
@@ -XXX,XX +XXX,XX @@ static bool do_adr(DisasContext *s, arg_rrri *a, gen_helper_gvec_3 *fn)
52
return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm);
56
}
53
}
57
54
58
static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
55
-TRANS_FEAT(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32)
59
- NeonGenTwoSingleOPFn *fn)
56
-TRANS_FEAT(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64)
60
+ NeonGenTwoSingleOpFn *fn)
57
-TRANS_FEAT(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32)
61
{
58
-TRANS_FEAT(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32)
62
/* FP operations in 2-reg-and-shift group */
59
+TRANS_FEAT_NONSTREAMING(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32)
63
TCGv_i32 tmp, shiftv;
60
+TRANS_FEAT_NONSTREAMING(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64)
61
+TRANS_FEAT_NONSTREAMING(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32)
62
+TRANS_FEAT_NONSTREAMING(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32)
63
64
/*
65
*** SVE Integer Misc - Unpredicated Group
64
--
66
--
65
2.20.1
67
2.25.1
66
67
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/sme-fa64.decode | 2 --
12
target/arm/translate-sve.c | 9 ++++++---
13
2 files changed, 6 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sme-fa64.decode
18
+++ b/target/arm/sme-fa64.decode
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
20
21
FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
22
FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
23
-FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
24
-FAIL 0010 0101 --10 1--- 1001 ---- ---- ---- # WRFFR, SETFFR
25
FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
26
FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
27
FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
28
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-sve.c
31
+++ b/target/arm/translate-sve.c
32
@@ -XXX,XX +XXX,XX @@ static bool do_predset(DisasContext *s, int esz, int rd, int pat, bool setflag)
33
TRANS_FEAT(PTRUE, aa64_sve, do_predset, a->esz, a->rd, a->pat, a->s)
34
35
/* Note pat == 31 is #all, to set all elements. */
36
-TRANS_FEAT(SETFFR, aa64_sve, do_predset, 0, FFR_PRED_NUM, 31, false)
37
+TRANS_FEAT_NONSTREAMING(SETFFR, aa64_sve,
38
+ do_predset, 0, FFR_PRED_NUM, 31, false)
39
40
/* Note pat == 32 is #unimp, to set no elements. */
41
TRANS_FEAT(PFALSE, aa64_sve, do_predset, 0, a->rd, 32, false)
42
@@ -XXX,XX +XXX,XX @@ static bool trans_RDFFR_p(DisasContext *s, arg_RDFFR_p *a)
43
.rd = a->rd, .pg = a->pg, .s = a->s,
44
.rn = FFR_PRED_NUM, .rm = FFR_PRED_NUM,
45
};
46
+
47
+ s->is_nonstreaming = true;
48
return trans_AND_pppp(s, &alt_a);
49
}
50
51
-TRANS_FEAT(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM)
52
-TRANS_FEAT(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn)
53
+TRANS_FEAT_NONSTREAMING(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM)
54
+TRANS_FEAT_NONSTREAMING(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn)
55
56
static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz *a,
57
void (*gen_fn)(TCGv_i32, TCGv_ptr,
58
--
59
2.25.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/sme-fa64.decode | 3 ---
12
target/arm/translate-sve.c | 22 ++++++++++++----------
13
2 files changed, 12 insertions(+), 13 deletions(-)
14
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sme-fa64.decode
18
+++ b/target/arm/sme-fa64.decode
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
22
23
-FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
24
-FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
25
-FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
26
FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
27
FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
28
FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
29
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-sve.c
32
+++ b/target/arm/translate-sve.c
33
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
34
NULL, gen_helper_sve_fexpa_h,
35
gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
36
};
37
-TRANS_FEAT(FEXPA, aa64_sve, gen_gvec_ool_zz,
38
- fexpa_fns[a->esz], a->rd, a->rn, 0)
39
+TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
40
+ fexpa_fns[a->esz], a->rd, a->rn, 0)
41
42
static gen_helper_gvec_3 * const ftssel_fns[4] = {
43
NULL, gen_helper_sve_ftssel_h,
44
gen_helper_sve_ftssel_s, gen_helper_sve_ftssel_d,
45
};
46
-TRANS_FEAT(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz, ftssel_fns[a->esz], a, 0)
47
+TRANS_FEAT_NONSTREAMING(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz,
48
+ ftssel_fns[a->esz], a, 0)
49
50
/*
51
*** SVE Predicate Logical Operations Group
52
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(TRN2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz,
53
static gen_helper_gvec_3 * const compact_fns[4] = {
54
NULL, NULL, gen_helper_sve_compact_s, gen_helper_sve_compact_d
55
};
56
-TRANS_FEAT(COMPACT, aa64_sve, gen_gvec_ool_arg_zpz, compact_fns[a->esz], a, 0)
57
+TRANS_FEAT_NONSTREAMING(COMPACT, aa64_sve, gen_gvec_ool_arg_zpz,
58
+ compact_fns[a->esz], a, 0)
59
60
/* Call the helper that computes the ARM LastActiveElement pseudocode
61
* function, scaled by the element size. This includes the not found
62
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3 * const bext_fns[4] = {
63
gen_helper_sve2_bext_b, gen_helper_sve2_bext_h,
64
gen_helper_sve2_bext_s, gen_helper_sve2_bext_d,
65
};
66
-TRANS_FEAT(BEXT, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
67
- bext_fns[a->esz], a, 0)
68
+TRANS_FEAT_NONSTREAMING(BEXT, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
69
+ bext_fns[a->esz], a, 0)
70
71
static gen_helper_gvec_3 * const bdep_fns[4] = {
72
gen_helper_sve2_bdep_b, gen_helper_sve2_bdep_h,
73
gen_helper_sve2_bdep_s, gen_helper_sve2_bdep_d,
74
};
75
-TRANS_FEAT(BDEP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
76
- bdep_fns[a->esz], a, 0)
77
+TRANS_FEAT_NONSTREAMING(BDEP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
78
+ bdep_fns[a->esz], a, 0)
79
80
static gen_helper_gvec_3 * const bgrp_fns[4] = {
81
gen_helper_sve2_bgrp_b, gen_helper_sve2_bgrp_h,
82
gen_helper_sve2_bgrp_s, gen_helper_sve2_bgrp_d,
83
};
84
-TRANS_FEAT(BGRP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
85
- bgrp_fns[a->esz], a, 0)
86
+TRANS_FEAT_NONSTREAMING(BGRP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
87
+ bgrp_fns[a->esz], a, 0)
88
89
static gen_helper_gvec_3 * const cadd_fns[4] = {
90
gen_helper_sve2_cadd_b, gen_helper_sve2_cadd_h,
91
--
92
2.25.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
'ARM SBCon two-wire serial bus interface' is the official
3
Mark these as a non-streaming instructions, which should trap
4
name describing the pair of registers used to bitbanging
4
if full a64 support is not enabled in streaming mode.
5
I2C in the Versatile boards.
6
5
7
Make the private VersatileI2CState structure as public
8
ArmSbconI2CState.
9
Add the TYPE_ARM_SBCON_I2C, alias to our current
10
TYPE_VERSATILE_I2C model.
11
Rename the memory region description as 'arm_sbcon_i2c'.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-5-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-8-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
include/hw/i2c/arm_sbcon_i2c.h | 35 ++++++++++++++++++++++++++++++++++
11
target/arm/sme-fa64.decode | 2 --
19
hw/i2c/versatile_i2c.c | 17 +++++------------
12
target/arm/translate-sve.c | 24 +++++++++++++++---------
20
MAINTAINERS | 1 +
13
2 files changed, 15 insertions(+), 11 deletions(-)
21
3 files changed, 41 insertions(+), 12 deletions(-)
22
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
23
14
24
diff --git a/include/hw/i2c/arm_sbcon_i2c.h b/include/hw/i2c/arm_sbcon_i2c.h
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
25
new file mode 100644
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX
17
--- a/target/arm/sme-fa64.decode
27
--- /dev/null
18
+++ b/target/arm/sme-fa64.decode
28
+++ b/include/hw/i2c/arm_sbcon_i2c.h
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
29
@@ -XXX,XX +XXX,XX @@
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
30
+/*
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
31
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
22
32
+ * a.k.a.
23
-FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
33
+ * ARM Versatile I2C controller
24
-FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
34
+ *
25
FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
35
+ * Copyright (c) 2006-2007 CodeSourcery.
26
FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
36
+ * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
27
FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
37
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
28
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
38
+ *
29
index XXXXXXX..XXXXXXX 100644
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
30
--- a/target/arm/translate-sve.c
40
+ */
31
+++ b/target/arm/translate-sve.c
41
+#ifndef HW_I2C_ARM_SBCON_H
32
@@ -XXX,XX +XXX,XX @@ static bool do_trans_pmull(DisasContext *s, arg_rrr_esz *a, bool sel)
42
+#define HW_I2C_ARM_SBCON_H
33
gen_helper_gvec_pmull_q, gen_helper_sve2_pmull_h,
34
NULL, gen_helper_sve2_pmull_d,
35
};
36
- if (a->esz == 0
37
- ? !dc_isar_feature(aa64_sve2_pmull128, s)
38
- : !dc_isar_feature(aa64_sve, s)) {
43
+
39
+
44
+#include "hw/sysbus.h"
40
+ if (a->esz == 0) {
45
+#include "hw/i2c/bitbang_i2c.h"
41
+ if (!dc_isar_feature(aa64_sve2_pmull128, s)) {
46
+
42
+ return false;
47
+#define TYPE_VERSATILE_I2C "versatile_i2c"
43
+ }
48
+#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
44
+ s->is_nonstreaming = true;
49
+
45
+ } else if (!dc_isar_feature(aa64_sve, s)) {
50
+#define ARM_SBCON_I2C(obj) \
46
return false;
51
+ OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
47
}
52
+
48
return gen_gvec_ool_arg_zzz(s, fns[a->esz], a, sel);
53
+typedef struct ArmSbconI2CState {
49
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz)
54
+ /*< private >*/
50
* SVE Integer Multiply-Add (unpredicated)
55
+ SysBusDevice parent_obj;
56
+ /*< public >*/
57
+
58
+ MemoryRegion iomem;
59
+ bitbang_i2c_interface bitbang;
60
+ int out;
61
+ int in;
62
+} ArmSbconI2CState;
63
+
64
+#endif /* HW_I2C_ARM_SBCON_H */
65
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/i2c/versatile_i2c.c
68
+++ b/hw/i2c/versatile_i2c.c
69
@@ -XXX,XX +XXX,XX @@
70
/*
71
- * ARM Versatile I2C controller
72
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
73
+ * a.k.a. ARM Versatile I2C controller
74
*
75
* Copyright (c) 2006-2007 CodeSourcery.
76
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
77
@@ -XXX,XX +XXX,XX @@
78
*/
51
*/
79
52
80
#include "qemu/osdep.h"
53
-TRANS_FEAT(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz, gen_helper_fmmla_s,
81
-#include "hw/sysbus.h"
54
- a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
82
-#include "hw/i2c/bitbang_i2c.h"
55
-TRANS_FEAT(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz, gen_helper_fmmla_d,
83
+#include "hw/i2c/arm_sbcon_i2c.h"
56
- a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
84
#include "hw/registerfields.h"
57
+TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz,
85
#include "qemu/log.h"
58
+ gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra,
86
#include "qemu/module.h"
59
+ 0, FPST_FPCR)
87
60
+TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz,
88
-#define TYPE_VERSATILE_I2C "versatile_i2c"
61
+ gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra,
89
#define VERSATILE_I2C(obj) \
62
+ 0, FPST_FPCR)
90
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
63
91
64
static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = {
92
-typedef struct VersatileI2CState {
65
NULL, gen_helper_sve2_sqdmlal_zzzw_h,
93
- SysBusDevice parent_obj;
66
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
94
+typedef ArmSbconI2CState VersatileI2CState;
67
TRANS_FEAT(BFDOT_zzxz, aa64_sve_bf16, gen_gvec_ool_arg_zzxz,
95
68
gen_helper_gvec_bfdot_idx, a)
96
- MemoryRegion iomem;
69
97
- bitbang_i2c_interface bitbang;
70
-TRANS_FEAT(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
98
- int out;
71
- gen_helper_gvec_bfmmla, a, 0)
99
- int in;
72
+TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
100
-} VersatileI2CState;
73
+ gen_helper_gvec_bfmmla, a, 0)
101
74
102
REG32(CONTROL_GET, 0)
75
static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
103
REG32(CONTROL_SET, 0)
76
{
104
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_init(Object *obj)
105
bus = i2c_init_bus(dev, "i2c");
106
bitbang_i2c_init(&s->bitbang, bus);
107
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
108
- "versatile_i2c", 0x1000);
109
+ "arm_sbcon_i2c", 0x1000);
110
sysbus_init_mmio(sbd, &s->iomem);
111
}
112
113
diff --git a/MAINTAINERS b/MAINTAINERS
114
index XXXXXXX..XXXXXXX 100644
115
--- a/MAINTAINERS
116
+++ b/MAINTAINERS
117
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
118
L: qemu-arm@nongnu.org
119
S: Maintained
120
F: hw/*/versatile*
121
+F: include/hw/i2c/arm_sbcon_i2c.h
122
F: hw/misc/arm_sysctl.c
123
F: docs/system/arm/versatile.rst
124
125
--
77
--
126
2.20.1
78
2.25.1
127
128
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/sme-fa64.decode | 3 ---
12
target/arm/translate-sve.c | 15 +++++++++++----
13
2 files changed, 11 insertions(+), 7 deletions(-)
14
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sme-fa64.decode
18
+++ b/target/arm/sme-fa64.decode
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
22
23
-FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
24
-FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
25
-FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
26
FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
27
FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
28
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
29
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-sve.c
32
+++ b/target/arm/translate-sve.c
33
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = {
34
NULL, gen_helper_sve_ftmad_h,
35
gen_helper_sve_ftmad_s, gen_helper_sve_ftmad_d,
36
};
37
-TRANS_FEAT(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
38
- ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
39
- a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
40
+TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
41
+ ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
42
+ a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
43
44
/*
45
*** SVE Floating Point Accumulating Reduction Group
46
@@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
47
if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) {
48
return false;
49
}
50
+ s->is_nonstreaming = true;
51
if (!sve_access_check(s)) {
52
return true;
53
}
54
@@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
55
DO_FP3(FADD_zzz, fadd)
56
DO_FP3(FSUB_zzz, fsub)
57
DO_FP3(FMUL_zzz, fmul)
58
-DO_FP3(FTSMUL, ftsmul)
59
DO_FP3(FRECPS, recps)
60
DO_FP3(FRSQRTS, rsqrts)
61
62
#undef DO_FP3
63
64
+static gen_helper_gvec_3_ptr * const ftsmul_fns[4] = {
65
+ NULL, gen_helper_gvec_ftsmul_h,
66
+ gen_helper_gvec_ftsmul_s, gen_helper_gvec_ftsmul_d
67
+};
68
+TRANS_FEAT_NONSTREAMING(FTSMUL, aa64_sve, gen_gvec_fpst_arg_zzz,
69
+ ftsmul_fns[a->esz], a, 0)
70
+
71
/*
72
*** SVE Floating Point Arithmetic - Predicated Group
73
*/
74
--
75
2.25.1
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Some cpu features may be enabled and disabled for all configurations
3
Mark these as a non-streaming instructions, which should trap
4
that support the feature. Let's test that.
4
if full a64 support is not enabled in streaming mode.
5
5
6
A recent regression[*] inspired adding these tests.
7
8
[*] '-cpu host,pmu=on' caused a segfault
9
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20200623090622.30365-2-philmd@redhat.com
13
Message-Id: <20200623082310.17577-1-drjones@redhat.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-10-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
tests/qtest/arm-cpu-features.c | 38 ++++++++++++++++++++++++++++++----
11
target/arm/sme-fa64.decode | 1 -
18
1 file changed, 34 insertions(+), 4 deletions(-)
12
target/arm/translate-sve.c | 12 ++++++------
13
2 files changed, 6 insertions(+), 7 deletions(-)
19
14
20
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qtest/arm-cpu-features.c
17
--- a/target/arm/sme-fa64.decode
23
+++ b/tests/qtest/arm-cpu-features.c
18
+++ b/target/arm/sme-fa64.decode
24
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
25
qobject_unref(_resp); \
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
26
})
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
27
22
28
-#define assert_feature(qts, cpu_type, feature, expected_value) \
23
-FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
29
+#define resp_assert_feature(resp, feature, expected_value) \
24
FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
30
({ \
25
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
31
- QDict *_resp, *_props; \
26
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
32
+ QDict *_props; \
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
33
\
28
index XXXXXXX..XXXXXXX 100644
34
- _resp = do_query_no_props(qts, cpu_type); \
29
--- a/target/arm/translate-sve.c
35
g_assert(_resp); \
30
+++ b/target/arm/translate-sve.c
36
g_assert(resp_has_props(_resp)); \
31
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FMLALT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, true)
37
_props = resp_get_props(_resp); \
32
TRANS_FEAT(FMLSLB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, false)
38
g_assert(qdict_get(_props, feature)); \
33
TRANS_FEAT(FMLSLT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, true)
39
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
34
40
+})
35
-TRANS_FEAT(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
41
+
36
- gen_helper_gvec_smmla_b, a, 0)
42
+#define assert_feature(qts, cpu_type, feature, expected_value) \
37
-TRANS_FEAT(USMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
43
+({ \
38
- gen_helper_gvec_usmmla_b, a, 0)
44
+ QDict *_resp; \
39
-TRANS_FEAT(UMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
45
+ \
40
- gen_helper_gvec_ummla_b, a, 0)
46
+ _resp = do_query_no_props(qts, cpu_type); \
41
+TRANS_FEAT_NONSTREAMING(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
47
+ g_assert(_resp); \
42
+ gen_helper_gvec_smmla_b, a, 0)
48
+ resp_assert_feature(_resp, feature, expected_value); \
43
+TRANS_FEAT_NONSTREAMING(USMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
49
+ qobject_unref(_resp); \
44
+ gen_helper_gvec_usmmla_b, a, 0)
50
+})
45
+TRANS_FEAT_NONSTREAMING(UMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
51
+
46
+ gen_helper_gvec_ummla_b, a, 0)
52
+#define assert_set_feature(qts, cpu_type, feature, value) \
47
53
+({ \
48
TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
54
+ const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
49
gen_helper_gvec_bfdot, a, 0)
55
+ QDict *_resp; \
56
+ \
57
+ _resp = do_query(qts, cpu_type, _fmt, feature); \
58
+ g_assert(_resp); \
59
+ resp_assert_feature(_resp, feature, value); \
60
qobject_unref(_resp); \
61
})
62
63
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
64
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
65
66
/* Test expected feature presence/absence for some cpu types */
67
- assert_has_feature_enabled(qts, "max", "pmu");
68
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
69
assert_has_not_feature(qts, "cortex-a15", "aarch64");
70
71
+ /* Enabling and disabling pmu should always work. */
72
+ assert_has_feature_enabled(qts, "max", "pmu");
73
+ assert_set_feature(qts, "max", "pmu", false);
74
+ assert_set_feature(qts, "max", "pmu", true);
75
+
76
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
77
78
if (g_str_equal(qtest_get_arch(), "aarch64")) {
79
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
80
return;
81
}
82
83
+ /* Enabling and disabling kvm-no-adjvtime should always work. */
84
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
85
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
86
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
87
88
if (g_str_equal(qtest_get_arch(), "aarch64")) {
89
bool kvm_supports_sve;
90
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
91
char *error;
92
93
assert_has_feature_enabled(qts, "host", "aarch64");
94
+
95
+ /* Enabling and disabling pmu should always work. */
96
assert_has_feature_enabled(qts, "host", "pmu");
97
+ assert_set_feature(qts, "host", "pmu", false);
98
+ assert_set_feature(qts, "host", "pmu", true);
99
100
assert_error(qts, "cortex-a15",
101
"We cannot guarantee the CPU type 'cortex-a15' works "
102
--
50
--
103
2.20.1
51
2.25.1
104
105
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Mark these as non-streaming instructions, which should trap
4
Message-id: 20200617072539.32686-14-f4bug@amsat.org
4
if full a64 support is not enabled in streaming mode.
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/mps2.c | 1 +
11
target/arm/sme-fa64.decode | 1 -
9
1 file changed, 1 insertion(+)
12
target/arm/translate-sve.c | 35 ++++++++++++++++++-----------------
13
2 files changed, 18 insertions(+), 18 deletions(-)
10
14
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
17
--- a/target/arm/sme-fa64.decode
14
+++ b/hw/arm/mps2.c
18
+++ b/target/arm/sme-fa64.decode
15
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
16
0x4002a000}; /* Shield1 */
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
17
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
18
}
22
19
+ create_unimplemented_device("i2s", 0x40024000, 0x400);
23
-FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
20
24
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
21
/* In hardware this is a LAN9220; the LAN9118 is software compatible
25
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
22
* except that it doesn't support the checksum-offload feature.
26
FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-sve.c
30
+++ b/target/arm/translate-sve.c
31
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_NARROW(RSUBHNT, rsubhnt)
32
static gen_helper_gvec_flags_4 * const match_fns[4] = {
33
gen_helper_sve2_match_ppzz_b, gen_helper_sve2_match_ppzz_h, NULL, NULL
34
};
35
-TRANS_FEAT(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz])
36
+TRANS_FEAT_NONSTREAMING(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz])
37
38
static gen_helper_gvec_flags_4 * const nmatch_fns[4] = {
39
gen_helper_sve2_nmatch_ppzz_b, gen_helper_sve2_nmatch_ppzz_h, NULL, NULL
40
};
41
-TRANS_FEAT(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz])
42
+TRANS_FEAT_NONSTREAMING(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz])
43
44
static gen_helper_gvec_4 * const histcnt_fns[4] = {
45
NULL, NULL, gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d
46
};
47
-TRANS_FEAT(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz,
48
- histcnt_fns[a->esz], a, 0)
49
+TRANS_FEAT_NONSTREAMING(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz,
50
+ histcnt_fns[a->esz], a, 0)
51
52
-TRANS_FEAT(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
53
- a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0)
54
+TRANS_FEAT_NONSTREAMING(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
55
+ a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0)
56
57
DO_ZPZZ_FP(FADDP, aa64_sve2, sve2_faddp_zpzz)
58
DO_ZPZZ_FP(FMAXNMP, aa64_sve2, sve2_fmaxnmp_zpzz)
59
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SQRDCMLAH_zzzz, aa64_sve2, gen_gvec_ool_zzzz,
60
TRANS_FEAT(USDOT_zzzz, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
61
a->esz == 2 ? gen_helper_gvec_usdot_b : NULL, a, 0)
62
63
-TRANS_FEAT(AESMC, aa64_sve2_aes, gen_gvec_ool_zz,
64
- gen_helper_crypto_aesmc, a->rd, a->rd, a->decrypt)
65
+TRANS_FEAT_NONSTREAMING(AESMC, aa64_sve2_aes, gen_gvec_ool_zz,
66
+ gen_helper_crypto_aesmc, a->rd, a->rd, a->decrypt)
67
68
-TRANS_FEAT(AESE, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
69
- gen_helper_crypto_aese, a, false)
70
-TRANS_FEAT(AESD, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
71
- gen_helper_crypto_aese, a, true)
72
+TRANS_FEAT_NONSTREAMING(AESE, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
73
+ gen_helper_crypto_aese, a, false)
74
+TRANS_FEAT_NONSTREAMING(AESD, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
75
+ gen_helper_crypto_aese, a, true)
76
77
-TRANS_FEAT(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
78
- gen_helper_crypto_sm4e, a, 0)
79
-TRANS_FEAT(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
80
- gen_helper_crypto_sm4ekey, a, 0)
81
+TRANS_FEAT_NONSTREAMING(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
82
+ gen_helper_crypto_sm4e, a, 0)
83
+TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
84
+ gen_helper_crypto_sm4ekey, a, 0)
85
86
-TRANS_FEAT(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz, gen_gvec_rax1, a)
87
+TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz,
88
+ gen_gvec_rax1, a)
89
90
TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz,
91
gen_helper_sve2_fcvtnt_sh, a, 0, FPST_FPCR)
23
--
92
--
24
2.20.1
93
2.25.1
25
26
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
From 'Application Note AN385', chapter 3.14:
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
4
5
5
The SMM implements a simple SBCon interface based on I2C.
6
7
There are 4 SBCon interfaces on the FPGA APB subsystem.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-13-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-12-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/mps2.c | 8 ++++++++
11
target/arm/sme-fa64.decode | 9 ---------
15
hw/arm/Kconfig | 1 +
12
target/arm/translate-sve.c | 6 ++++++
16
2 files changed, 9 insertions(+)
13
2 files changed, 6 insertions(+), 9 deletions(-)
17
14
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2.c
17
--- a/target/arm/sme-fa64.decode
21
+++ b/hw/arm/mps2.c
18
+++ b/target/arm/sme-fa64.decode
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
23
#include "hw/misc/mps2-scc.h"
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
24
#include "hw/misc/mps2-fpgaio.h"
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
25
#include "hw/ssi/pl022.h"
22
26
+#include "hw/i2c/arm_sbcon_i2c.h"
23
-FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
27
#include "hw/net/lan9118.h"
24
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
28
#include "net/net.h"
25
FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
26
-FAIL 1000 010- -01- ---- 1--- ---- ---- ---- # SVE 32-bit gather load (vector+imm)
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
27
-FAIL 1000 0100 0-0- ---- 0--- ---- ---- ---- # SVE 32-bit gather load byte (scalar+vector)
31
qdev_get_gpio_in(orgate_dev, j));
28
-FAIL 1000 0100 1--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load half (scalar+vector)
32
}
29
-FAIL 1000 0101 0--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load word (scalar+vector)
30
FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
31
FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
32
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
33
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
34
FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
35
-FAIL 1110 010- -00- ---- 001- ---- ---- ---- # SVE2 64-bit scatter NT store (vector+scalar)
36
-FAIL 1110 010- -10- ---- 001- ---- ---- ---- # SVE2 32-bit scatter NT store (vector+scalar)
37
-FAIL 1110 010- ---- ---- 1-0- ---- ---- ---- # SVE scatter store (scalar+32-bit vector)
38
-FAIL 1110 010- ---- ---- 101- ---- ---- ---- # SVE scatter store (misc)
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-sve.c
42
+++ b/target/arm/translate-sve.c
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a)
44
if (!dc_isar_feature(aa64_sve, s)) {
45
return false;
33
}
46
}
34
+ for (i = 0; i < 4; i++) {
47
+ s->is_nonstreaming = true;
35
+ static const hwaddr i2cbase[] = {0x40022000, /* Touch */
48
if (!sve_access_check(s)) {
36
+ 0x40023000, /* Audio */
49
return true;
37
+ 0x40029000, /* Shield0 */
50
}
38
+ 0x4002a000}; /* Shield1 */
51
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a)
39
+ sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
52
if (!dc_isar_feature(aa64_sve, s)) {
40
+ }
53
return false;
41
54
}
42
/* In hardware this is a LAN9220; the LAN9118 is software compatible
55
+ s->is_nonstreaming = true;
43
* except that it doesn't support the checksum-offload feature.
56
if (!sve_access_check(s)) {
44
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
57
return true;
45
index XXXXXXX..XXXXXXX 100644
58
}
46
--- a/hw/arm/Kconfig
59
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNT1_zprz(DisasContext *s, arg_LD1_zprz *a)
47
+++ b/hw/arm/Kconfig
60
if (!dc_isar_feature(aa64_sve2, s)) {
48
@@ -XXX,XX +XXX,XX @@ config MPS2
61
return false;
49
select SPLIT_IRQ
62
}
50
select UNIMP
63
+ s->is_nonstreaming = true;
51
select CMSDK_APB_WATCHDOG
64
if (!sve_access_check(s)) {
52
+ select VERSATILE_I2C
65
return true;
53
66
}
54
config FSL_IMX7
67
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a)
55
bool
68
if (!dc_isar_feature(aa64_sve, s)) {
69
return false;
70
}
71
+ s->is_nonstreaming = true;
72
if (!sve_access_check(s)) {
73
return true;
74
}
75
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a)
76
if (!dc_isar_feature(aa64_sve, s)) {
77
return false;
78
}
79
+ s->is_nonstreaming = true;
80
if (!sve_access_check(s)) {
81
return true;
82
}
83
@@ -XXX,XX +XXX,XX @@ static bool trans_STNT1_zprz(DisasContext *s, arg_ST1_zprz *a)
84
if (!dc_isar_feature(aa64_sve2, s)) {
85
return false;
86
}
87
+ s->is_nonstreaming = true;
88
if (!sve_access_check(s)) {
89
return true;
90
}
56
--
91
--
57
2.20.1
92
2.25.1
58
59
diff view generated by jsdifflib
1
Convert the pairwise ops VPADDL and VPADAL in the 2-reg-misc grouping
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree.
3
2
4
At this point we can get rid of the weird CPU_V001 #define that was
3
Mark these as a non-streaming instructions, which should trap if full
5
used to avoid having to explicitly list all the arguments being
4
a64 support is not enabled in streaming mode. In this case, introduce
6
passed to some TCG gen/helper functions.
5
PRF_ns (prefetch non-streaming) to handle the checks.
7
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-13-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-3-peter.maydell@linaro.org
11
---
11
---
12
target/arm/neon-dp.decode | 6 ++
12
target/arm/sme-fa64.decode | 3 ---
13
target/arm/translate-neon.inc.c | 149 ++++++++++++++++++++++++++++++++
13
target/arm/sve.decode | 10 +++++-----
14
target/arm/translate.c | 35 +-------
14
target/arm/translate-sve.c | 11 +++++++++++
15
3 files changed, 157 insertions(+), 33 deletions(-)
15
3 files changed, 16 insertions(+), 8 deletions(-)
16
16
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
19
--- a/target/arm/sme-fa64.decode
20
+++ b/target/arm/neon-dp.decode
20
+++ b/target/arm/sme-fa64.decode
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
22
&2misc vm=%vm_dp vd=%vd_dp
22
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
23
23
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
24
25
+
25
-FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
26
+ VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
26
-FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
27
+ VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
27
FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
28
+
28
FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
29
+ VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
29
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
30
+ VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
30
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
31
]
31
-FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
32
32
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
33
# Subgroup for size != 0b11
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
34
--- a/target/arm/sve.decode
37
+++ b/target/arm/translate-neon.inc.c
35
+++ b/target/arm/sve.decode
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
36
@@ -XXX,XX +XXX,XX @@ LD1RO_zpri 1010010 .. 01 0.... 001 ... ..... ..... \
39
}
37
@rpri_load_msz nreg=0
38
39
# SVE 32-bit gather prefetch (scalar plus 32-bit scaled offsets)
40
-PRF 1000010 00 -1 ----- 0-- --- ----- 0 ----
41
+PRF_ns 1000010 00 -1 ----- 0-- --- ----- 0 ----
42
43
# SVE 32-bit gather prefetch (vector plus immediate)
44
-PRF 1000010 -- 00 ----- 111 --- ----- 0 ----
45
+PRF_ns 1000010 -- 00 ----- 111 --- ----- 0 ----
46
47
# SVE contiguous prefetch (scalar plus immediate)
48
PRF 1000010 11 1- ----- 0-- --- ----- 0 ----
49
@@ -XXX,XX +XXX,XX @@ LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
50
@rpri_g_load esz=3
51
52
# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
53
-PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
54
+PRF_ns 1100010 00 11 ----- 1-- --- ----- 0 ----
55
56
# SVE 64-bit gather prefetch (scalar plus unpacked 32-bit scaled offsets)
57
-PRF 1100010 00 -1 ----- 0-- --- ----- 0 ----
58
+PRF_ns 1100010 00 -1 ----- 0-- --- ----- 0 ----
59
60
# SVE 64-bit gather prefetch (vector plus immediate)
61
-PRF 1100010 -- 00 ----- 111 --- ----- 0 ----
62
+PRF_ns 1100010 -- 00 ----- 111 --- ----- 0 ----
63
64
### SVE Memory Store Group
65
66
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate-sve.c
69
+++ b/target/arm/translate-sve.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a)
40
return true;
71
return true;
41
}
72
}
42
+
73
43
+static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
74
+static bool trans_PRF_ns(DisasContext *s, arg_PRF_ns *a)
44
+ NeonGenWidenFn *widenfn,
45
+ NeonGenTwo64OpFn *opfn,
46
+ NeonGenTwo64OpFn *accfn)
47
+{
75
+{
48
+ /*
76
+ if (!dc_isar_feature(aa64_sve, s)) {
49
+ * Pairwise long operations: widen both halves of the pair,
50
+ * combine the pairs with the opfn, and then possibly accumulate
51
+ * into the destination with the accfn.
52
+ */
53
+ int pass;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
77
+ return false;
57
+ }
78
+ }
58
+
79
+ /* Prefetch is a nop within QEMU. */
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
80
+ s->is_nonstreaming = true;
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
81
+ (void)sve_access_check(s);
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if ((a->vd | a->vm) & a->q) {
66
+ return false;
67
+ }
68
+
69
+ if (!widenfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ for (pass = 0; pass < a->q + 1; pass++) {
78
+ TCGv_i32 tmp;
79
+ TCGv_i64 rm0_64, rm1_64, rd_64;
80
+
81
+ rm0_64 = tcg_temp_new_i64();
82
+ rm1_64 = tcg_temp_new_i64();
83
+ rd_64 = tcg_temp_new_i64();
84
+ tmp = neon_load_reg(a->vm, pass * 2);
85
+ widenfn(rm0_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ tmp = neon_load_reg(a->vm, pass * 2 + 1);
88
+ widenfn(rm1_64, tmp);
89
+ tcg_temp_free_i32(tmp);
90
+ opfn(rd_64, rm0_64, rm1_64);
91
+ tcg_temp_free_i64(rm0_64);
92
+ tcg_temp_free_i64(rm1_64);
93
+
94
+ if (accfn) {
95
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
96
+ neon_load_reg64(tmp64, a->vd + pass);
97
+ accfn(rd_64, tmp64, rd_64);
98
+ tcg_temp_free_i64(tmp64);
99
+ }
100
+ neon_store_reg64(rd_64, a->vd + pass);
101
+ tcg_temp_free_i64(rd_64);
102
+ }
103
+ return true;
82
+ return true;
104
+}
83
+}
105
+
84
+
106
+static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a)
85
/*
107
+{
86
* Move Prefix
108
+ static NeonGenWidenFn * const widenfn[] = {
87
*
109
+ gen_helper_neon_widen_s8,
110
+ gen_helper_neon_widen_s16,
111
+ tcg_gen_ext_i32_i64,
112
+ NULL,
113
+ };
114
+ static NeonGenTwo64OpFn * const opfn[] = {
115
+ gen_helper_neon_paddl_u16,
116
+ gen_helper_neon_paddl_u32,
117
+ tcg_gen_add_i64,
118
+ NULL,
119
+ };
120
+
121
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
122
+}
123
+
124
+static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a)
125
+{
126
+ static NeonGenWidenFn * const widenfn[] = {
127
+ gen_helper_neon_widen_u8,
128
+ gen_helper_neon_widen_u16,
129
+ tcg_gen_extu_i32_i64,
130
+ NULL,
131
+ };
132
+ static NeonGenTwo64OpFn * const opfn[] = {
133
+ gen_helper_neon_paddl_u16,
134
+ gen_helper_neon_paddl_u32,
135
+ tcg_gen_add_i64,
136
+ NULL,
137
+ };
138
+
139
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
140
+}
141
+
142
+static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a)
143
+{
144
+ static NeonGenWidenFn * const widenfn[] = {
145
+ gen_helper_neon_widen_s8,
146
+ gen_helper_neon_widen_s16,
147
+ tcg_gen_ext_i32_i64,
148
+ NULL,
149
+ };
150
+ static NeonGenTwo64OpFn * const opfn[] = {
151
+ gen_helper_neon_paddl_u16,
152
+ gen_helper_neon_paddl_u32,
153
+ tcg_gen_add_i64,
154
+ NULL,
155
+ };
156
+ static NeonGenTwo64OpFn * const accfn[] = {
157
+ gen_helper_neon_addl_u16,
158
+ gen_helper_neon_addl_u32,
159
+ tcg_gen_add_i64,
160
+ NULL,
161
+ };
162
+
163
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
164
+ accfn[a->size]);
165
+}
166
+
167
+static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
168
+{
169
+ static NeonGenWidenFn * const widenfn[] = {
170
+ gen_helper_neon_widen_u8,
171
+ gen_helper_neon_widen_u16,
172
+ tcg_gen_extu_i32_i64,
173
+ NULL,
174
+ };
175
+ static NeonGenTwo64OpFn * const opfn[] = {
176
+ gen_helper_neon_paddl_u16,
177
+ gen_helper_neon_paddl_u32,
178
+ tcg_gen_add_i64,
179
+ NULL,
180
+ };
181
+ static NeonGenTwo64OpFn * const accfn[] = {
182
+ gen_helper_neon_addl_u16,
183
+ gen_helper_neon_addl_u32,
184
+ tcg_gen_add_i64,
185
+ NULL,
186
+ };
187
+
188
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
189
+ accfn[a->size]);
190
+}
191
diff --git a/target/arm/translate.c b/target/arm/translate.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/translate.c
194
+++ b/target/arm/translate.c
195
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
196
gen_rfe(s, pc, load_cpu_field(spsr));
197
}
198
199
-#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
200
-
201
static int gen_neon_unzip(int rd, int rm, int size, int q)
202
{
203
TCGv_ptr pd, pm;
204
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
205
tcg_temp_free_i32(src);
206
}
207
208
-static inline void gen_neon_addl(int size)
209
-{
210
- switch (size) {
211
- case 0: gen_helper_neon_addl_u16(CPU_V001); break;
212
- case 1: gen_helper_neon_addl_u32(CPU_V001); break;
213
- case 2: tcg_gen_add_i64(CPU_V001); break;
214
- default: abort();
215
- }
216
-}
217
-
218
static void gen_neon_narrow_op(int op, int u, int size,
219
TCGv_i32 dest, TCGv_i64 src)
220
{
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
222
}
223
switch (op) {
224
case NEON_2RM_VREV64:
225
- /* handled by decodetree */
226
- return 1;
227
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
228
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
229
- for (pass = 0; pass < q + 1; pass++) {
230
- tmp = neon_load_reg(rm, pass * 2);
231
- gen_neon_widen(cpu_V0, tmp, size, op & 1);
232
- tmp = neon_load_reg(rm, pass * 2 + 1);
233
- gen_neon_widen(cpu_V1, tmp, size, op & 1);
234
- switch (size) {
235
- case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
236
- case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
237
- case 2: tcg_gen_add_i64(CPU_V001); break;
238
- default: abort();
239
- }
240
- if (op >= NEON_2RM_VPADAL) {
241
- /* Accumulate. */
242
- neon_load_reg64(cpu_V1, rd + pass);
243
- gen_neon_addl(size);
244
- }
245
- neon_store_reg64(cpu_V0, rd + pass);
246
- }
247
- break;
248
+ /* handled by decodetree */
249
+ return 1;
250
case NEON_2RM_VTRN:
251
if (size == 2) {
252
int n;
253
--
88
--
254
2.20.1
89
2.25.1
255
256
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
From 'Application Note AN385', chapter 3.9, SPI:
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
4
5
5
The SMM implements five PL022 SPI modules.
6
7
Two pairs of modules share the same OR-gated IRQ.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-12-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-14-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/mps2.c | 24 ++++++++++++++++++++++++
11
target/arm/sme-fa64.decode | 2 --
15
hw/arm/Kconfig | 6 +++---
12
target/arm/translate-sve.c | 2 ++
16
2 files changed, 27 insertions(+), 3 deletions(-)
13
2 files changed, 2 insertions(+), 2 deletions(-)
17
14
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2.c
17
--- a/target/arm/sme-fa64.decode
21
+++ b/hw/arm/mps2.c
18
+++ b/target/arm/sme-fa64.decode
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
23
#include "hw/timer/cmsdk-apb-dualtimer.h"
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
24
#include "hw/misc/mps2-scc.h"
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
25
#include "hw/misc/mps2-fpgaio.h"
22
26
+#include "hw/ssi/pl022.h"
23
-FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
27
#include "hw/net/lan9118.h"
24
-FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
28
#include "net/net.h"
25
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
26
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
31
qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
32
sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
33
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
34
+ sysbus_create_simple(TYPE_PL022, 0x40025000, /* External ADC */
35
+ qdev_get_gpio_in(armv7m, 22));
36
+ for (i = 0; i < 2; i++) {
37
+ static const int spi_irqno[] = {11, 24};
38
+ static const hwaddr spibase[] = {0x40020000, /* APB */
39
+ 0x40021000, /* LCD */
40
+ 0x40026000, /* Shield0 */
41
+ 0x40027000}; /* Shield1 */
42
+ DeviceState *orgate_dev;
43
+ Object *orgate;
44
+ int j;
45
+
46
+ orgate = object_new(TYPE_OR_IRQ);
47
+ object_property_set_int(orgate, 2, "num-lines", &error_fatal);
48
+ orgate_dev = DEVICE(orgate);
49
+ qdev_realize(orgate_dev, NULL, &error_fatal);
50
+ qdev_connect_gpio_out(orgate_dev, 0,
51
+ qdev_get_gpio_in(armv7m, spi_irqno[i]));
52
+ for (j = 0; j < 2; j++) {
53
+ sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
54
+ qdev_get_gpio_in(orgate_dev, j));
55
+ }
56
+ }
57
58
/* In hardware this is a LAN9220; the LAN9118 is software compatible
59
* except that it doesn't support the checksum-offload feature.
60
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
61
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/Kconfig
29
--- a/target/arm/translate-sve.c
63
+++ b/hw/arm/Kconfig
30
+++ b/target/arm/translate-sve.c
64
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
31
@@ -XXX,XX +XXX,XX @@ static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a)
65
select ARM_TIMER # sp804
32
if (!dc_isar_feature(aa64_sve, s)) {
66
select ARM_V7M
33
return false;
67
select PL011 # UART
34
}
68
- select PL022 # Serial port
35
+ s->is_nonstreaming = true;
69
+ select PL022 # SPI
36
if (sve_access_check(s)) {
70
select PL031 # RTC
37
TCGv_i64 addr = new_tmp_a64(s);
71
select PL061 # GPIO
38
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
72
select PL310 # cache controller
39
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a)
73
@@ -XXX,XX +XXX,XX @@ config STELLARIS
40
if (!dc_isar_feature(aa64_sve, s)) {
74
select CMSDK_APB_WATCHDOG
41
return false;
75
select I2C
42
}
76
select PL011 # UART
43
+ s->is_nonstreaming = true;
77
- select PL022 # Serial port
44
if (sve_access_check(s)) {
78
+ select PL022 # SPI
45
int vsz = vec_full_reg_size(s);
79
select PL061 # GPIO
46
int elements = vsz >> dtype_esz[a->dtype];
80
select SSD0303 # OLED display
81
select SSD0323 # OLED display
82
@@ -XXX,XX +XXX,XX @@ config MPS2
83
select MPS2_FPGAIO
84
select MPS2_SCC
85
select OR_IRQ
86
- select PL022 # Serial port
87
+ select PL022 # SPI
88
select PL080 # DMA controller
89
select SPLIT_IRQ
90
select UNIMP
91
--
47
--
92
2.20.1
48
2.25.1
93
94
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We already model the CMSDK APB watchdog device, let's use it!
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20200617072539.32686-9-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/mps2.c | 7 +++++++
11
target/arm/sme-fa64.decode | 3 ---
12
hw/arm/Kconfig | 1 +
12
target/arm/translate-sve.c | 2 ++
13
2 files changed, 8 insertions(+)
13
2 files changed, 2 insertions(+), 3 deletions(-)
14
14
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2.c
17
--- a/target/arm/sme-fa64.decode
18
+++ b/hw/arm/mps2.c
18
+++ b/target/arm/sme-fa64.decode
19
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
20
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
20
# --11 1100 --0- ---- ---- ---- ---- ---- # Load/store FP register (unscaled imm)
21
qdev_get_gpio_in(armv7m, 10));
21
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
22
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
22
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
23
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
23
-
24
+ TYPE_CMSDK_APB_WATCHDOG);
24
-FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
25
+ qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
25
-FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
26
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
28
+ qdev_get_gpio_in_named(armv7m, "NMI", 0));
29
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
30
31
/* FPGA APB subsystem */
32
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
34
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/Kconfig
28
--- a/target/arm/translate-sve.c
36
+++ b/hw/arm/Kconfig
29
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ config MPS2
30
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RO_zprr(DisasContext *s, arg_rprr_load *a)
38
select PL080 # DMA controller
31
if (a->rm == 31) {
39
select SPLIT_IRQ
32
return false;
40
select UNIMP
33
}
41
+ select CMSDK_APB_WATCHDOG
34
+ s->is_nonstreaming = true;
42
35
if (sve_access_check(s)) {
43
config FSL_IMX7
36
TCGv_i64 addr = new_tmp_a64(s);
44
bool
37
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
38
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RO_zpri(DisasContext *s, arg_rpri_load *a)
39
if (!dc_isar_feature(aa64_sve_f64mm, s)) {
40
return false;
41
}
42
+ s->is_nonstreaming = true;
43
if (sve_access_check(s)) {
44
TCGv_i64 addr = new_tmp_a64(s);
45
tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 32);
45
--
46
--
46
2.20.1
47
2.25.1
47
48
diff view generated by jsdifflib
1
Convert the VCVT instructions in the 2-reg-misc grouping to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
3
These functions will be used to verify that the cpu
4
is in the correct state for a given instruction.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-16-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-19-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 9 +++++
11
target/arm/translate-a64.h | 21 +++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
12
target/arm/translate-a64.c | 34 ++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 70 ++++-----------------------------
13
2 files changed, 55 insertions(+)
11
3 files changed, 87 insertions(+), 62 deletions(-)
12
14
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/translate-a64.h
16
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/translate-a64.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
18
20
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
19
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
21
unsigned int imms, unsigned int immr);
20
22
bool sve_access_check(DisasContext *s);
21
+ VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
23
+bool sme_enabled_check(DisasContext *s);
22
+ VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
24
+bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
23
+ VCVTNS 1111 001 11 . 11 .. 11 .... 0 0010 . . 0 .... @2misc
24
+ VCVTNU 1111 001 11 . 11 .. 11 .... 0 0011 . . 0 .... @2misc
25
+ VCVTPS 1111 001 11 . 11 .. 11 .... 0 0100 . . 0 .... @2misc
26
+ VCVTPU 1111 001 11 . 11 .. 11 .... 0 0101 . . 0 .... @2misc
27
+ VCVTMS 1111 001 11 . 11 .. 11 .... 0 0110 . . 0 .... @2misc
28
+ VCVTMU 1111 001 11 . 11 .. 11 .... 0 0111 . . 0 .... @2misc
29
+
25
+
30
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
26
+/* This function corresponds to CheckStreamingSVEEnabled. */
31
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
27
+static inline bool sme_sm_enabled_check(DisasContext *s)
32
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
28
+{
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
+ return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK);
30
+}
31
+
32
+/* This function corresponds to CheckSMEAndZAEnabled. */
33
+static inline bool sme_za_enabled_check(DisasContext *s)
34
+{
35
+ return sme_enabled_check_with_svcr(s, R_SVCR_ZA_MASK);
36
+}
37
+
38
+/* Note that this function corresponds to CheckStreamingSVEAndZAEnabled. */
39
+static inline bool sme_smza_enabled_check(DisasContext *s)
40
+{
41
+ return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK | R_SVCR_ZA_MASK);
42
+}
43
+
44
TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
45
TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
46
bool tag_checked, int log2_size);
47
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
34
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
49
--- a/target/arm/translate-a64.c
36
+++ b/target/arm/translate-neon.inc.c
50
+++ b/target/arm/translate-a64.c
37
@@ -XXX,XX +XXX,XX @@ DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
51
@@ -XXX,XX +XXX,XX @@ static bool sme_access_check(DisasContext *s)
38
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
52
return true;
39
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
53
}
40
DO_VRINT(VRINTP, FPROUNDING_POSINF)
54
41
+
55
+/* This function corresponds to CheckSMEEnabled. */
42
+static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed)
56
+bool sme_enabled_check(DisasContext *s)
43
+{
57
+{
44
+ /*
58
+ /*
45
+ * Handle a VCVT* operation by iterating 32 bits at a time,
59
+ * Note that unlike sve_excp_el, we have not constrained sme_excp_el
46
+ * with a specified rounding mode in operation.
60
+ * to be zero when fp_excp_el has priority. This is because we need
61
+ * sme_excp_el by itself for cpregs access checks.
47
+ */
62
+ */
48
+ int pass;
63
+ if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
49
+ TCGv_ptr fpst;
64
+ s->fp_access_checked = true;
50
+ TCGv_i32 tcg_rmode, tcg_shift;
65
+ return sme_access_check(s);
66
+ }
67
+ return fp_access_check_only(s);
68
+}
51
+
69
+
52
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
70
+/* Common subroutine for CheckSMEAnd*Enabled. */
53
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
71
+bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req)
72
+{
73
+ if (!sme_enabled_check(s)) {
54
+ return false;
74
+ return false;
55
+ }
75
+ }
56
+
76
+ if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) {
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
77
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
78
+ syn_smetrap(SME_ET_NotStreaming, false));
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
79
+ return false;
61
+ }
80
+ }
62
+
81
+ if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) {
63
+ if (a->size != 2) {
82
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
64
+ /* TODO: FP16 will be the size == 1 case */
83
+ syn_smetrap(SME_ET_InactiveZA, false));
65
+ return false;
84
+ return false;
66
+ }
85
+ }
67
+
68
+ if ((a->vd | a->vm) & a->q) {
69
+ return false;
70
+ }
71
+
72
+ if (!vfp_access_check(s)) {
73
+ return true;
74
+ }
75
+
76
+ fpst = get_fpstatus_ptr(1);
77
+ tcg_shift = tcg_const_i32(0);
78
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
79
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
80
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
81
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
82
+ if (is_signed) {
83
+ gen_helper_vfp_tosls(tmp, tmp, tcg_shift, fpst);
84
+ } else {
85
+ gen_helper_vfp_touls(tmp, tmp, tcg_shift, fpst);
86
+ }
87
+ neon_store_reg(a->vd, pass, tmp);
88
+ }
89
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
90
+ tcg_temp_free_i32(tcg_rmode);
91
+ tcg_temp_free_i32(tcg_shift);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
86
+ return true;
95
+}
87
+}
96
+
88
+
97
+#define DO_VCVT(INSN, RMODE, SIGNED) \
89
/*
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
90
* This utility function is for doing register extension with an
99
+ { \
91
* optional shift. You will likely want to pass a temporary for the
100
+ return do_vcvt(s, a, RMODE, SIGNED); \
101
+ }
102
+
103
+DO_VCVT(VCVTAU, FPROUNDING_TIEAWAY, false)
104
+DO_VCVT(VCVTAS, FPROUNDING_TIEAWAY, true)
105
+DO_VCVT(VCVTNU, FPROUNDING_TIEEVEN, false)
106
+DO_VCVT(VCVTNS, FPROUNDING_TIEEVEN, true)
107
+DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
108
+DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
109
+DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
110
+DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
116
#define NEON_2RM_VCVT_SF 62
117
#define NEON_2RM_VCVT_UF 63
118
119
-static bool neon_2rm_is_v8_op(int op)
120
-{
121
- /* Return true if this neon 2reg-misc op is ARMv8 and up */
122
- switch (op) {
123
- case NEON_2RM_VRINTN:
124
- case NEON_2RM_VRINTA:
125
- case NEON_2RM_VRINTM:
126
- case NEON_2RM_VRINTP:
127
- case NEON_2RM_VRINTZ:
128
- case NEON_2RM_VRINTX:
129
- case NEON_2RM_VCVTAU:
130
- case NEON_2RM_VCVTAS:
131
- case NEON_2RM_VCVTNU:
132
- case NEON_2RM_VCVTNS:
133
- case NEON_2RM_VCVTPU:
134
- case NEON_2RM_VCVTPS:
135
- case NEON_2RM_VCVTMU:
136
- case NEON_2RM_VCVTMS:
137
- return true;
138
- default:
139
- return false;
140
- }
141
-}
142
-
143
/* Each entry in this array has bit n set if the insn allows
144
* size value n (otherwise it will UNDEF). Since unallocated
145
* op values will have no bits set they always UNDEF.
146
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
147
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
148
return 1;
149
}
150
- if (neon_2rm_is_v8_op(op) &&
151
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
152
- return 1;
153
- }
154
if (q && ((rm | rd) & 1)) {
155
return 1;
156
}
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
case NEON_2RM_VRINTM:
159
case NEON_2RM_VRINTP:
160
case NEON_2RM_VRINTZ:
161
+ case NEON_2RM_VCVTAU:
162
+ case NEON_2RM_VCVTAS:
163
+ case NEON_2RM_VCVTNU:
164
+ case NEON_2RM_VCVTNS:
165
+ case NEON_2RM_VCVTPU:
166
+ case NEON_2RM_VCVTPS:
167
+ case NEON_2RM_VCVTMU:
168
+ case NEON_2RM_VCVTMS:
169
/* handled by decodetree */
170
return 1;
171
case NEON_2RM_VTRN:
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
173
}
174
neon_store_reg(rm, pass, tmp2);
175
break;
176
- case NEON_2RM_VCVTAU:
177
- case NEON_2RM_VCVTAS:
178
- case NEON_2RM_VCVTNU:
179
- case NEON_2RM_VCVTNS:
180
- case NEON_2RM_VCVTPU:
181
- case NEON_2RM_VCVTPS:
182
- case NEON_2RM_VCVTMU:
183
- case NEON_2RM_VCVTMS:
184
- {
185
- bool is_signed = !extract32(insn, 7, 1);
186
- TCGv_ptr fpst = get_fpstatus_ptr(1);
187
- TCGv_i32 tcg_rmode, tcg_shift;
188
- int rmode = fp_decode_rm[extract32(insn, 8, 2)];
189
-
190
- tcg_shift = tcg_const_i32(0);
191
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
192
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
193
- cpu_env);
194
-
195
- if (is_signed) {
196
- gen_helper_vfp_tosls(tmp, tmp,
197
- tcg_shift, fpst);
198
- } else {
199
- gen_helper_vfp_touls(tmp, tmp,
200
- tcg_shift, fpst);
201
- }
202
-
203
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
204
- cpu_env);
205
- tcg_temp_free_i32(tcg_rmode);
206
- tcg_temp_free_i32(tcg_shift);
207
- tcg_temp_free_ptr(fpst);
208
- break;
209
- }
210
default:
211
/* Reserved op values were caught by the
212
* neon_2rm_sizes[] check earlier.
213
--
92
--
214
2.20.1
93
2.25.1
215
216
diff view generated by jsdifflib
1
In commit cfdb2c0c95ae9205b0 ("target/arm: Vectorize SABA/UABA") we
1
From: Richard Henderson <richard.henderson@linaro.org>
2
replaced the old handling of SABA/UABA with a vectorized implementation
3
which returns early rather than falling into the loop-ever-elements
4
code. We forgot to delete the part of the old looping code that
5
did the accumulate step, and Coverity correctly warns (CID 1428955)
6
that this code is now dead. Delete it.
7
2
8
Fixes: cfdb2c0c95ae9205b0
3
The pseudocode for CheckSVEEnabled gains a check for Streaming
4
SVE mode, and for SME present but SVE absent.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-17-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200619171547.29780-1-peter.maydell@linaro.org
13
---
10
---
14
target/arm/translate-a64.c | 12 ------------
11
target/arm/translate-a64.c | 22 ++++++++++++++++------
15
1 file changed, 12 deletions(-)
12
1 file changed, 16 insertions(+), 6 deletions(-)
16
13
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
16
--- a/target/arm/translate-a64.c
20
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s)
22
genfn(tcg_res, tcg_op1, tcg_op2);
19
return true;
23
}
20
}
24
21
25
- if (opcode == 0xf) {
22
-/* Check that SVE access is enabled. If it is, return true.
26
- /* SABA, UABA: accumulating ops */
23
+/*
27
- static NeonGenTwoOpFn * const fns[3] = {
24
+ * Check that SVE access is enabled. If it is, return true.
28
- gen_helper_neon_add_u8,
25
* If not, emit code to generate an appropriate exception and return false.
29
- gen_helper_neon_add_u16,
26
+ * This function corresponds to CheckSVEEnabled().
30
- tcg_gen_add_i32,
27
*/
31
- };
28
bool sve_access_check(DisasContext *s)
29
{
30
- if (s->sve_excp_el) {
31
- assert(!s->sve_access_checked);
32
- s->sve_access_checked = true;
32
-
33
-
33
- read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
34
+ if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
34
- fns[size](tcg_res, tcg_op1, tcg_res);
35
+ assert(dc_isar_feature(aa64_sme, s));
35
- }
36
+ if (!sme_sm_enabled_check(s)) {
36
-
37
+ goto fail_exit;
37
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
38
+ }
38
39
+ } else if (s->sve_excp_el) {
39
tcg_temp_free_i32(tcg_res);
40
gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
41
syn_sve_access_trap(), s->sve_excp_el);
42
- return false;
43
+ goto fail_exit;
44
}
45
s->sve_access_checked = true;
46
return fp_access_check(s);
47
+
48
+ fail_exit:
49
+ /* Assert that we only raise one exception per instruction. */
50
+ assert(!s->sve_access_checked);
51
+ s->sve_access_checked = true;
52
+ return false;
53
}
54
55
/*
40
--
56
--
41
2.20.1
57
2.25.1
42
43
diff view generated by jsdifflib
1
Convert the remaining ops in the Neon 2-reg-misc group which
1
From: Richard Henderson <richard.henderson@linaro.org>
2
can be implemented simply with our do_2misc() helper.
3
2
3
These SME instructions are nominally within the SVE decode space,
4
so we add them to sve.decode and translate-sve.c.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-18-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-14-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 10 +++++
11
target/arm/translate-a64.h | 12 ++++++++++++
9
target/arm/translate-neon.inc.c | 69 +++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 5 ++++-
10
target/arm/translate.c | 38 ++++--------------
13
target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 86 insertions(+), 31 deletions(-)
14
3 files changed, 54 insertions(+), 1 deletion(-)
12
15
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
18
--- a/target/arm/translate-a64.h
16
+++ b/target/arm/neon-dp.decode
19
+++ b/target/arm/translate-a64.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
18
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
21
return s->vl;
19
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
20
21
+ VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
22
+ VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
23
+ VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
24
+
25
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
26
27
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
28
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
29
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
30
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
31
32
+ VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
33
+ VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
34
+
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
37
38
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
39
40
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
41
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
42
+
43
+ VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
44
+ VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
45
]
46
47
# Subgroup for size != 0b11
48
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/translate-neon.inc.c
51
+++ b/target/arm/translate-neon.inc.c
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a)
53
}
54
return do_2misc(s, a, gen_rev16);
55
}
22
}
56
+
23
57
+static bool trans_VCLS(DisasContext *s, arg_2misc *a)
24
+/* Return the byte size of the vector register, SVL / 8. */
25
+static inline int streaming_vec_reg_size(DisasContext *s)
58
+{
26
+{
59
+ static NeonGenOneOpFn * const fn[] = {
27
+ return s->svl;
60
+ gen_helper_neon_cls_s8,
61
+ gen_helper_neon_cls_s16,
62
+ gen_helper_neon_cls_s32,
63
+ NULL,
64
+ };
65
+ return do_2misc(s, a, fn[a->size]);
66
+}
28
+}
67
+
29
+
68
+static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm)
30
/*
31
* Return the offset info CPUARMState of the predicate vector register Pn.
32
* Note for this purpose, FFR is P16.
33
@@ -XXX,XX +XXX,XX @@ static inline int pred_full_reg_size(DisasContext *s)
34
return s->vl >> 3;
35
}
36
37
+/* Return the byte size of the predicate register, SVL / 64. */
38
+static inline int streaming_pred_reg_size(DisasContext *s)
69
+{
39
+{
70
+ tcg_gen_clzi_i32(rd, rm, 32);
40
+ return s->svl >> 3;
71
+}
41
+}
72
+
42
+
73
+static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
43
/*
44
* Round up the size of a register to a size allowed by
45
* the tcg vector infrastructure. Any operation which uses this
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ INDEX_ri 00000100 esz:2 1 imm:s5 010001 rn:5 rd:5
51
# SVE index generation (register start, register increment)
52
INDEX_rr 00000100 .. 1 ..... 010011 ..... ..... @rd_rn_rm
53
54
-### SVE Stack Allocation Group
55
+### SVE / Streaming SVE Stack Allocation Group
56
57
# SVE stack frame adjustment
58
ADDVL 00000100 001 ..... 01010 ...... ..... @rd_rn_i6
59
+ADDSVL 00000100 001 ..... 01011 ...... ..... @rd_rn_i6
60
ADDPL 00000100 011 ..... 01010 ...... ..... @rd_rn_i6
61
+ADDSPL 00000100 011 ..... 01011 ...... ..... @rd_rn_i6
62
63
# SVE stack frame size
64
RDVL 00000100 101 11111 01010 imm:s6 rd:5
65
+RDSVL 00000100 101 11111 01011 imm:s6 rd:5
66
67
### SVE Bitwise Shift - Unpredicated Group
68
69
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-sve.c
72
+++ b/target/arm/translate-sve.c
73
@@ -XXX,XX +XXX,XX @@ static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
74
return true;
75
}
76
77
+static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a)
74
+{
78
+{
75
+ static NeonGenOneOpFn * const fn[] = {
79
+ if (!dc_isar_feature(aa64_sme, s)) {
76
+ gen_helper_neon_clz_u8,
80
+ return false;
77
+ gen_helper_neon_clz_u16,
81
+ }
78
+ do_VCLZ_32,
82
+ if (sme_enabled_check(s)) {
79
+ NULL,
83
+ TCGv_i64 rd = cpu_reg_sp(s, a->rd);
80
+ };
84
+ TCGv_i64 rn = cpu_reg_sp(s, a->rn);
81
+ return do_2misc(s, a, fn[a->size]);
85
+ tcg_gen_addi_i64(rd, rn, a->imm * streaming_vec_reg_size(s));
86
+ }
87
+ return true;
82
+}
88
+}
83
+
89
+
84
+static bool trans_VCNT(DisasContext *s, arg_2misc *a)
90
static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
91
{
92
if (!dc_isar_feature(aa64_sve, s)) {
93
@@ -XXX,XX +XXX,XX @@ static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
94
return true;
95
}
96
97
+static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a)
85
+{
98
+{
86
+ if (a->size != 0) {
99
+ if (!dc_isar_feature(aa64_sme, s)) {
87
+ return false;
100
+ return false;
88
+ }
101
+ }
89
+ return do_2misc(s, a, gen_helper_neon_cnt_u8);
102
+ if (sme_enabled_check(s)) {
103
+ TCGv_i64 rd = cpu_reg_sp(s, a->rd);
104
+ TCGv_i64 rn = cpu_reg_sp(s, a->rn);
105
+ tcg_gen_addi_i64(rd, rn, a->imm * streaming_pred_reg_size(s));
106
+ }
107
+ return true;
90
+}
108
+}
91
+
109
+
92
+static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
110
static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
111
{
112
if (!dc_isar_feature(aa64_sve, s)) {
113
@@ -XXX,XX +XXX,XX @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
114
return true;
115
}
116
117
+static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
93
+{
118
+{
94
+ if (a->size != 2) {
119
+ if (!dc_isar_feature(aa64_sme, s)) {
95
+ return false;
120
+ return false;
96
+ }
121
+ }
97
+ /* TODO: FP16 : size == 1 */
122
+ if (sme_enabled_check(s)) {
98
+ return do_2misc(s, a, gen_helper_vfp_abss);
123
+ TCGv_i64 reg = cpu_reg(s, a->rd);
124
+ tcg_gen_movi_i64(reg, a->imm * streaming_vec_reg_size(s));
125
+ }
126
+ return true;
99
+}
127
+}
100
+
128
+
101
+static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
129
/*
102
+{
130
*** SVE Compute Vector Address Group
103
+ if (a->size != 2) {
131
*/
104
+ return false;
105
+ }
106
+ /* TODO: FP16 : size == 1 */
107
+ return do_2misc(s, a, gen_helper_vfp_negs);
108
+}
109
+
110
+static bool trans_VRECPE(DisasContext *s, arg_2misc *a)
111
+{
112
+ if (a->size != 2) {
113
+ return false;
114
+ }
115
+ return do_2misc(s, a, gen_helper_recpe_u32);
116
+}
117
+
118
+static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
119
+{
120
+ if (a->size != 2) {
121
+ return false;
122
+ }
123
+ return do_2misc(s, a, gen_helper_rsqrte_u32);
124
+}
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
130
case NEON_2RM_SHA1SU1:
131
case NEON_2RM_VREV32:
132
case NEON_2RM_VREV16:
133
+ case NEON_2RM_VCLS:
134
+ case NEON_2RM_VCLZ:
135
+ case NEON_2RM_VCNT:
136
+ case NEON_2RM_VABS_F:
137
+ case NEON_2RM_VNEG_F:
138
+ case NEON_2RM_VRECPE:
139
+ case NEON_2RM_VRSQRTE:
140
/* handled by decodetree */
141
return 1;
142
case NEON_2RM_VTRN:
143
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
144
for (pass = 0; pass < (q ? 4 : 2); pass++) {
145
tmp = neon_load_reg(rm, pass);
146
switch (op) {
147
- case NEON_2RM_VCLS:
148
- switch (size) {
149
- case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
150
- case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
151
- case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
152
- default: abort();
153
- }
154
- break;
155
- case NEON_2RM_VCLZ:
156
- switch (size) {
157
- case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
158
- case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
159
- case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
160
- default: abort();
161
- }
162
- break;
163
- case NEON_2RM_VCNT:
164
- gen_helper_neon_cnt_u8(tmp, tmp);
165
- break;
166
case NEON_2RM_VQABS:
167
switch (size) {
168
case 0:
169
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
170
tcg_temp_free_ptr(fpstatus);
171
break;
172
}
173
- case NEON_2RM_VABS_F:
174
- gen_helper_vfp_abss(tmp, tmp);
175
- break;
176
- case NEON_2RM_VNEG_F:
177
- gen_helper_vfp_negs(tmp, tmp);
178
- break;
179
case NEON_2RM_VSWP:
180
tmp2 = neon_load_reg(rd, pass);
181
neon_store_reg(rm, pass, tmp2);
182
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
183
tcg_temp_free_ptr(fpst);
184
break;
185
}
186
- case NEON_2RM_VRECPE:
187
- gen_helper_recpe_u32(tmp, tmp);
188
- break;
189
- case NEON_2RM_VRSQRTE:
190
- gen_helper_rsqrte_u32(tmp, tmp);
191
- break;
192
case NEON_2RM_VRECPE_F:
193
{
194
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
--
132
--
196
2.20.1
133
2.25.1
197
198
diff view generated by jsdifflib
1
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-19-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200616170844.13318-2-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-dp.decode | 12 ++++++++
8
target/arm/helper-sme.h | 2 ++
8
target/arm/translate-neon.inc.c | 50 +++++++++++++++++++++++++++++++++
9
target/arm/sme.decode | 4 ++++
9
target/arm/translate.c | 24 ++--------------
10
target/arm/sme_helper.c | 25 +++++++++++++++++++++++++
10
3 files changed, 64 insertions(+), 22 deletions(-)
11
target/arm/translate-sme.c | 13 +++++++++++++
12
4 files changed, 44 insertions(+)
11
13
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
16
--- a/target/arm/helper-sme.h
15
+++ b/target/arm/neon-dp.decode
17
+++ b/target/arm/helper-sme.h
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
@@ -XXX,XX +XXX,XX @@
17
vm=%vm_dp vd=%vd_dp size=1
19
18
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
20
DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
19
vm=%vm_dp vd=%vd_dp size=2
21
DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
20
+
22
+
21
+ ##################################################################
23
+DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
22
+ # 2-reg-misc grouping:
24
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
23
+ # 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
25
index XXXXXXX..XXXXXXX 100644
24
+ ##################################################################
26
--- a/target/arm/sme.decode
27
+++ b/target/arm/sme.decode
28
@@ -XXX,XX +XXX,XX @@
29
#
30
# This file is processed by scripts/decodetree.py
31
#
25
+
32
+
26
+ &2misc vd vm q size
33
+### SME Misc
27
+
34
+
28
+ @2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
35
+ZERO 11000000 00 001 00000000000 imm:8
29
+ &2misc vm=%vm_dp vd=%vd_dp
36
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
30
+
31
+ VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
32
]
33
34
# Subgroup for size != 0b11
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
--- a/target/arm/sme_helper.c
38
+++ b/target/arm/translate-neon.inc.c
39
+++ b/target/arm/sme_helper.c
39
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
40
@@ -XXX,XX +XXX,XX @@ void helper_set_pstate_za(CPUARMState *env, uint32_t i)
40
a->q ? 16 : 8, a->q ? 16 : 8);
41
memset(env->zarray, 0, sizeof(env->zarray));
41
return true;
42
}
42
}
43
}
43
+
44
+
44
+static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
45
+void helper_sme_zero(CPUARMState *env, uint32_t imm, uint32_t svl)
45
+{
46
+{
46
+ int pass, half;
47
+ uint32_t i;
47
+
48
+
48
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
+ /*
50
+ * Special case clearing the entire ZA space.
51
+ * This falls into the CONSTRAINED UNPREDICTABLE zeroing of any
52
+ * parts of the ZA storage outside of SVL.
53
+ */
54
+ if (imm == 0xff) {
55
+ memset(env->zarray, 0, sizeof(env->zarray));
56
+ return;
57
+ }
58
+
59
+ /*
60
+ * Recall that ZAnH.D[m] is spread across ZA[n+8*m],
61
+ * so each row is discontiguous within ZA[].
62
+ */
63
+ for (i = 0; i < svl; i++) {
64
+ if (imm & (1 << (i % 8))) {
65
+ memset(&env->zarray[i], 0, svl);
66
+ }
67
+ }
68
+}
69
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-sme.c
72
+++ b/target/arm/translate-sme.c
73
@@ -XXX,XX +XXX,XX @@
74
*/
75
76
#include "decode-sme.c.inc"
77
+
78
+
79
+static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
80
+{
81
+ if (!dc_isar_feature(aa64_sme, s)) {
49
+ return false;
82
+ return false;
50
+ }
83
+ }
51
+
84
+ if (sme_za_enabled_check(s)) {
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
85
+ gen_helper_sme_zero(cpu_env, tcg_constant_i32(a->imm),
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
86
+ tcg_constant_i32(streaming_vec_reg_size(s)));
54
+ ((a->vd | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vd | a->vm) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (a->size == 3) {
63
+ return false;
64
+ }
65
+
66
+ if (!vfp_access_check(s)) {
67
+ return true;
68
+ }
69
+
70
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
71
+ TCGv_i32 tmp[2];
72
+
73
+ for (half = 0; half < 2; half++) {
74
+ tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
75
+ switch (a->size) {
76
+ case 0:
77
+ tcg_gen_bswap32_i32(tmp[half], tmp[half]);
78
+ break;
79
+ case 1:
80
+ gen_swap_half(tmp[half]);
81
+ break;
82
+ case 2:
83
+ break;
84
+ default:
85
+ g_assert_not_reached();
86
+ }
87
+ }
88
+ neon_store_reg(a->vd, pass * 2, tmp[1]);
89
+ neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
90
+ }
87
+ }
91
+ return true;
88
+ return true;
92
+}
89
+}
93
diff --git a/target/arm/translate.c b/target/arm/translate.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/translate.c
96
+++ b/target/arm/translate.c
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
}
99
switch (op) {
100
case NEON_2RM_VREV64:
101
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
102
- tmp = neon_load_reg(rm, pass * 2);
103
- tmp2 = neon_load_reg(rm, pass * 2 + 1);
104
- switch (size) {
105
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
106
- case 1: gen_swap_half(tmp); break;
107
- case 2: /* no-op */ break;
108
- default: abort();
109
- }
110
- neon_store_reg(rd, pass * 2 + 1, tmp);
111
- if (size == 2) {
112
- neon_store_reg(rd, pass * 2, tmp2);
113
- } else {
114
- switch (size) {
115
- case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
116
- case 1: gen_swap_half(tmp2); break;
117
- default: abort();
118
- }
119
- neon_store_reg(rd, pass * 2, tmp2);
120
- }
121
- }
122
- break;
123
+ /* handled by decodetree */
124
+ return 1;
125
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
126
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
127
for (pass = 0; pass < q + 1; pass++) {
128
--
90
--
129
2.20.1
91
2.25.1
130
131
diff view generated by jsdifflib
1
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree.
3
2
3
We can reuse the SVE functions for implementing moves to/from
4
horizontal tile slices, but we need new ones for moves to/from
5
vertical tile slices.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-20-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
7
---
11
---
8
target/arm/translate.h | 1 +
12
target/arm/helper-sme.h | 12 +++
9
target/arm/neon-dp.decode | 2 ++
13
target/arm/helper-sve.h | 2 +
10
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
14
target/arm/translate-a64.h | 8 ++
11
target/arm/translate.c | 12 ++-----
15
target/arm/translate.h | 5 ++
12
4 files changed, 60 insertions(+), 10 deletions(-)
16
target/arm/sme.decode | 15 ++++
17
target/arm/sme_helper.c | 151 ++++++++++++++++++++++++++++++++++++-
18
target/arm/sve_helper.c | 12 +++
19
target/arm/translate-sme.c | 127 +++++++++++++++++++++++++++++++
20
8 files changed, 331 insertions(+), 1 deletion(-)
13
21
22
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper-sme.h
25
+++ b/target/arm/helper-sme.h
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
27
DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
28
29
DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
30
+
31
+/* Move to/from vertical array slices, i.e. columns, so 'c'. */
32
+DEF_HELPER_FLAGS_4(sme_mova_cz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sme_mova_zc_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_4(sme_mova_cz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(sme_mova_zc_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(sme_mova_cz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(sme_mova_zc_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(sme_mova_cz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(sme_mova_zc_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(sme_mova_cz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(sme_mova_zc_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper-sve.h
45
+++ b/target/arm/helper-sve.h
46
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
47
void, ptr, ptr, ptr, ptr, i32)
48
DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
49
void, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_q, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
53
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_b, TCG_CALL_NO_RWG,
54
void, ptr, ptr, ptr, ptr, i32)
55
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate-a64.h
58
+++ b/target/arm/translate-a64.h
59
@@ -XXX,XX +XXX,XX @@ static inline int pred_gvec_reg_size(DisasContext *s)
60
return size_for_gvec(pred_full_reg_size(s));
61
}
62
63
+/* Return a newly allocated pointer to the predicate register. */
64
+static inline TCGv_ptr pred_full_reg_ptr(DisasContext *s, int regno)
65
+{
66
+ TCGv_ptr ret = tcg_temp_new_ptr();
67
+ tcg_gen_addi_ptr(ret, cpu_env, pred_full_reg_offset(s, regno));
68
+ return ret;
69
+}
70
+
71
bool disas_sve(DisasContext *, uint32_t);
72
bool disas_sme(DisasContext *, uint32_t);
73
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
74
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
76
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
77
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
78
@@ -XXX,XX +XXX,XX @@ static inline int plus_2(DisasContext *s, int x)
19
uint32_t, uint32_t, uint32_t);
79
return x + 2;
20
80
}
21
/* Function prototype for gen_ functions for calling Neon helpers */
81
22
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
82
+static inline int plus_12(DisasContext *s, int x)
23
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
83
+{
24
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
84
+ return x + 12;
25
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
85
+}
26
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
86
+
27
index XXXXXXX..XXXXXXX 100644
87
static inline int times_2(DisasContext *s, int x)
28
--- a/target/arm/neon-dp.decode
88
{
29
+++ b/target/arm/neon-dp.decode
89
return x * 2;
30
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
90
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
31
&2misc vm=%vm_dp vd=%vd_dp q=1
91
index XXXXXXX..XXXXXXX 100644
32
92
--- a/target/arm/sme.decode
33
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
93
+++ b/target/arm/sme.decode
34
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
94
@@ -XXX,XX +XXX,XX @@
35
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
95
### SME Misc
36
96
37
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
97
ZERO 11000000 00 001 00000000000 imm:8
38
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
98
+
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
99
+### SME Move into/from Array
40
index XXXXXXX..XXXXXXX 100644
100
+
41
--- a/target/arm/translate-neon.inc.c
101
+%mova_rs 13:2 !function=plus_12
42
+++ b/target/arm/translate-neon.inc.c
102
+&mova esz rs pg zr za_imm v:bool to_vec:bool
43
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
103
+
44
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
104
+MOVA 11000000 esz:2 00000 0 v:1 .. pg:3 zr:5 0 za_imm:4 \
45
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
105
+ &mova to_vec=0 rs=%mova_rs
46
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
106
+MOVA 11000000 11 00000 1 v:1 .. pg:3 zr:5 0 za_imm:4 \
47
+
107
+ &mova to_vec=0 rs=%mova_rs esz=4
48
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
108
+
49
+{
109
+MOVA 11000000 esz:2 00001 0 v:1 .. pg:3 0 za_imm:4 zr:5 \
50
+ int pass;
110
+ &mova to_vec=1 rs=%mova_rs
51
+
111
+MOVA 11000000 11 00001 1 v:1 .. pg:3 0 za_imm:4 zr:5 \
52
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
112
+ &mova to_vec=1 rs=%mova_rs esz=4
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
113
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/sme_helper.c
116
+++ b/target/arm/sme_helper.c
117
@@ -XXX,XX +XXX,XX @@
118
119
#include "qemu/osdep.h"
120
#include "cpu.h"
121
-#include "internals.h"
122
+#include "tcg/tcg-gvec-desc.h"
123
#include "exec/helper-proto.h"
124
+#include "qemu/int128.h"
125
+#include "vec_internal.h"
126
127
/* ResetSVEState */
128
void arm_reset_sve_state(CPUARMState *env)
129
@@ -XXX,XX +XXX,XX @@ void helper_sme_zero(CPUARMState *env, uint32_t imm, uint32_t svl)
130
}
131
}
132
}
133
+
134
+
135
+/*
136
+ * When considering the ZA storage as an array of elements of
137
+ * type T, the index within that array of the Nth element of
138
+ * a vertical slice of a tile can be calculated like this,
139
+ * regardless of the size of type T. This is because the tiles
140
+ * are interleaved, so if type T is size N bytes then row 1 of
141
+ * the tile is N rows away from row 0. The division by N to
142
+ * convert a byte offset into an array index and the multiplication
143
+ * by N to convert from vslice-index-within-the-tile to
144
+ * the index within the ZA storage cancel out.
145
+ */
146
+#define tile_vslice_index(i) ((i) * sizeof(ARMVectorReg))
147
+
148
+/*
149
+ * When doing byte arithmetic on the ZA storage, the element
150
+ * byteoff bytes away in a tile vertical slice is always this
151
+ * many bytes away in the ZA storage, regardless of the
152
+ * size of the tile element, assuming that byteoff is a multiple
153
+ * of the element size. Again this is because of the interleaving
154
+ * of the tiles. For instance if we have 1 byte per element then
155
+ * each row of the ZA storage has one byte of the vslice data,
156
+ * and (counting from 0) byte 8 goes in row 8 of the storage
157
+ * at offset (8 * row-size-in-bytes).
158
+ * If we have 8 bytes per element then each row of the ZA storage
159
+ * has 8 bytes of the data, but there are 8 interleaved tiles and
160
+ * so byte 8 of the data goes into row 1 of the tile,
161
+ * which is again row 8 of the storage, so the offset is still
162
+ * (8 * row-size-in-bytes). Similarly for other element sizes.
163
+ */
164
+#define tile_vslice_offset(byteoff) ((byteoff) * sizeof(ARMVectorReg))
165
+
166
+
167
+/*
168
+ * Move Zreg vector to ZArray column.
169
+ */
170
+#define DO_MOVA_C(NAME, TYPE, H) \
171
+void HELPER(NAME)(void *za, void *vn, void *vg, uint32_t desc) \
172
+{ \
173
+ int i, oprsz = simd_oprsz(desc); \
174
+ for (i = 0; i < oprsz; ) { \
175
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
176
+ do { \
177
+ if (pg & 1) { \
178
+ *(TYPE *)(za + tile_vslice_offset(i)) = *(TYPE *)(vn + H(i)); \
179
+ } \
180
+ i += sizeof(TYPE); \
181
+ pg >>= sizeof(TYPE); \
182
+ } while (i & 15); \
183
+ } \
184
+}
185
+
186
+DO_MOVA_C(sme_mova_cz_b, uint8_t, H1)
187
+DO_MOVA_C(sme_mova_cz_h, uint16_t, H1_2)
188
+DO_MOVA_C(sme_mova_cz_s, uint32_t, H1_4)
189
+
190
+void HELPER(sme_mova_cz_d)(void *za, void *vn, void *vg, uint32_t desc)
191
+{
192
+ int i, oprsz = simd_oprsz(desc) / 8;
193
+ uint8_t *pg = vg;
194
+ uint64_t *n = vn;
195
+ uint64_t *a = za;
196
+
197
+ for (i = 0; i < oprsz; i++) {
198
+ if (pg[H1(i)] & 1) {
199
+ a[tile_vslice_index(i)] = n[i];
200
+ }
201
+ }
202
+}
203
+
204
+void HELPER(sme_mova_cz_q)(void *za, void *vn, void *vg, uint32_t desc)
205
+{
206
+ int i, oprsz = simd_oprsz(desc) / 16;
207
+ uint16_t *pg = vg;
208
+ Int128 *n = vn;
209
+ Int128 *a = za;
210
+
211
+ /*
212
+ * Int128 is used here simply to copy 16 bytes, and to simplify
213
+ * the address arithmetic.
214
+ */
215
+ for (i = 0; i < oprsz; i++) {
216
+ if (pg[H2(i)] & 1) {
217
+ a[tile_vslice_index(i)] = n[i];
218
+ }
219
+ }
220
+}
221
+
222
+#undef DO_MOVA_C
223
+
224
+/*
225
+ * Move ZArray column to Zreg vector.
226
+ */
227
+#define DO_MOVA_Z(NAME, TYPE, H) \
228
+void HELPER(NAME)(void *vd, void *za, void *vg, uint32_t desc) \
229
+{ \
230
+ int i, oprsz = simd_oprsz(desc); \
231
+ for (i = 0; i < oprsz; ) { \
232
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
233
+ do { \
234
+ if (pg & 1) { \
235
+ *(TYPE *)(vd + H(i)) = *(TYPE *)(za + tile_vslice_offset(i)); \
236
+ } \
237
+ i += sizeof(TYPE); \
238
+ pg >>= sizeof(TYPE); \
239
+ } while (i & 15); \
240
+ } \
241
+}
242
+
243
+DO_MOVA_Z(sme_mova_zc_b, uint8_t, H1)
244
+DO_MOVA_Z(sme_mova_zc_h, uint16_t, H1_2)
245
+DO_MOVA_Z(sme_mova_zc_s, uint32_t, H1_4)
246
+
247
+void HELPER(sme_mova_zc_d)(void *vd, void *za, void *vg, uint32_t desc)
248
+{
249
+ int i, oprsz = simd_oprsz(desc) / 8;
250
+ uint8_t *pg = vg;
251
+ uint64_t *d = vd;
252
+ uint64_t *a = za;
253
+
254
+ for (i = 0; i < oprsz; i++) {
255
+ if (pg[H1(i)] & 1) {
256
+ d[i] = a[tile_vslice_index(i)];
257
+ }
258
+ }
259
+}
260
+
261
+void HELPER(sme_mova_zc_q)(void *vd, void *za, void *vg, uint32_t desc)
262
+{
263
+ int i, oprsz = simd_oprsz(desc) / 16;
264
+ uint16_t *pg = vg;
265
+ Int128 *d = vd;
266
+ Int128 *a = za;
267
+
268
+ /*
269
+ * Int128 is used here simply to copy 16 bytes, and to simplify
270
+ * the address arithmetic.
271
+ */
272
+ for (i = 0; i < oprsz; i++, za += sizeof(ARMVectorReg)) {
273
+ if (pg[H2(i)] & 1) {
274
+ d[i] = a[tile_vslice_index(i)];
275
+ }
276
+ }
277
+}
278
+
279
+#undef DO_MOVA_Z
280
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/arm/sve_helper.c
283
+++ b/target/arm/sve_helper.c
284
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sel_zpzz_d)(void *vd, void *vn, void *vm,
285
}
286
}
287
288
+void HELPER(sve_sel_zpzz_q)(void *vd, void *vn, void *vm,
289
+ void *vg, uint32_t desc)
290
+{
291
+ intptr_t i, opr_sz = simd_oprsz(desc) / 16;
292
+ Int128 *d = vd, *n = vn, *m = vm;
293
+ uint16_t *pg = vg;
294
+
295
+ for (i = 0; i < opr_sz; i += 1) {
296
+ d[i] = (pg[H2(i)] & 1 ? n : m)[i];
297
+ }
298
+}
299
+
300
/* Two operand comparison controlled by a predicate.
301
* ??? It is very tempting to want to be able to expand this inline
302
* with x86 instructions, e.g.
303
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/target/arm/translate-sme.c
306
+++ b/target/arm/translate-sme.c
307
@@ -XXX,XX +XXX,XX @@
308
#include "decode-sme.c.inc"
309
310
311
+/*
312
+ * Resolve tile.size[index] to a host pointer, where tile and index
313
+ * are always decoded together, dependent on the element size.
314
+ */
315
+static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
316
+ int tile_index, bool vertical)
317
+{
318
+ int tile = tile_index >> (4 - esz);
319
+ int index = esz == MO_128 ? 0 : extract32(tile_index, 0, 4 - esz);
320
+ int pos, len, offset;
321
+ TCGv_i32 tmp;
322
+ TCGv_ptr addr;
323
+
324
+ /* Compute the final index, which is Rs+imm. */
325
+ tmp = tcg_temp_new_i32();
326
+ tcg_gen_trunc_tl_i32(tmp, cpu_reg(s, rs));
327
+ tcg_gen_addi_i32(tmp, tmp, index);
328
+
329
+ /* Prepare a power-of-two modulo via extraction of @len bits. */
330
+ len = ctz32(streaming_vec_reg_size(s)) - esz;
331
+
332
+ if (vertical) {
333
+ /*
334
+ * Compute the byte offset of the index within the tile:
335
+ * (index % (svl / size)) * size
336
+ * = (index % (svl >> esz)) << esz
337
+ * Perform the power-of-two modulo via extraction of the low @len bits.
338
+ * Perform the multiply by shifting left by @pos bits.
339
+ * Perform these operations simultaneously via deposit into zero.
340
+ */
341
+ pos = esz;
342
+ tcg_gen_deposit_z_i32(tmp, tmp, pos, len);
343
+
344
+ /*
345
+ * For big-endian, adjust the indexed column byte offset within
346
+ * the uint64_t host words that make up env->zarray[].
347
+ */
348
+ if (HOST_BIG_ENDIAN && esz < MO_64) {
349
+ tcg_gen_xori_i32(tmp, tmp, 8 - (1 << esz));
350
+ }
351
+ } else {
352
+ /*
353
+ * Compute the byte offset of the index within the tile:
354
+ * (index % (svl / size)) * (size * sizeof(row))
355
+ * = (index % (svl >> esz)) << (esz + log2(sizeof(row)))
356
+ */
357
+ pos = esz + ctz32(sizeof(ARMVectorReg));
358
+ tcg_gen_deposit_z_i32(tmp, tmp, pos, len);
359
+
360
+ /* Row slices are always aligned and need no endian adjustment. */
361
+ }
362
+
363
+ /* The tile byte offset within env->zarray is the row. */
364
+ offset = tile * sizeof(ARMVectorReg);
365
+
366
+ /* Include the byte offset of zarray to make this relative to env. */
367
+ offset += offsetof(CPUARMState, zarray);
368
+ tcg_gen_addi_i32(tmp, tmp, offset);
369
+
370
+ /* Add the byte offset to env to produce the final pointer. */
371
+ addr = tcg_temp_new_ptr();
372
+ tcg_gen_ext_i32_ptr(addr, tmp);
373
+ tcg_temp_free_i32(tmp);
374
+ tcg_gen_add_ptr(addr, addr, cpu_env);
375
+
376
+ return addr;
377
+}
378
+
379
static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
380
{
381
if (!dc_isar_feature(aa64_sme, s)) {
382
@@ -XXX,XX +XXX,XX @@ static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
383
}
384
return true;
385
}
386
+
387
+static bool trans_MOVA(DisasContext *s, arg_MOVA *a)
388
+{
389
+ static gen_helper_gvec_4 * const h_fns[5] = {
390
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
391
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d,
392
+ gen_helper_sve_sel_zpzz_q
393
+ };
394
+ static gen_helper_gvec_3 * const cz_fns[5] = {
395
+ gen_helper_sme_mova_cz_b, gen_helper_sme_mova_cz_h,
396
+ gen_helper_sme_mova_cz_s, gen_helper_sme_mova_cz_d,
397
+ gen_helper_sme_mova_cz_q,
398
+ };
399
+ static gen_helper_gvec_3 * const zc_fns[5] = {
400
+ gen_helper_sme_mova_zc_b, gen_helper_sme_mova_zc_h,
401
+ gen_helper_sme_mova_zc_s, gen_helper_sme_mova_zc_d,
402
+ gen_helper_sme_mova_zc_q,
403
+ };
404
+
405
+ TCGv_ptr t_za, t_zr, t_pg;
406
+ TCGv_i32 t_desc;
407
+ int svl;
408
+
409
+ if (!dc_isar_feature(aa64_sme, s)) {
54
+ return false;
410
+ return false;
55
+ }
411
+ }
56
+
412
+ if (!sme_smza_enabled_check(s)) {
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (!fn) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
413
+ return true;
73
+ }
414
+ }
74
+
415
+
75
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
416
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v);
76
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
417
+ t_zr = vec_full_reg_ptr(s, a->zr);
77
+ fn(tmp, tmp);
418
+ t_pg = pred_full_reg_ptr(s, a->pg);
78
+ neon_store_reg(a->vd, pass, tmp);
419
+
79
+ }
420
+ svl = streaming_vec_reg_size(s);
421
+ t_desc = tcg_constant_i32(simd_desc(svl, svl, 0));
422
+
423
+ if (a->v) {
424
+ /* Vertical slice -- use sme mova helpers. */
425
+ if (a->to_vec) {
426
+ zc_fns[a->esz](t_zr, t_za, t_pg, t_desc);
427
+ } else {
428
+ cz_fns[a->esz](t_za, t_zr, t_pg, t_desc);
429
+ }
430
+ } else {
431
+ /* Horizontal slice -- reuse sve sel helpers. */
432
+ if (a->to_vec) {
433
+ h_fns[a->esz](t_zr, t_za, t_zr, t_pg, t_desc);
434
+ } else {
435
+ h_fns[a->esz](t_za, t_zr, t_za, t_pg, t_desc);
436
+ }
437
+ }
438
+
439
+ tcg_temp_free_ptr(t_za);
440
+ tcg_temp_free_ptr(t_zr);
441
+ tcg_temp_free_ptr(t_pg);
80
+
442
+
81
+ return true;
443
+ return true;
82
+}
444
+}
83
+
84
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
85
+{
86
+ static NeonGenOneOpFn * const fn[] = {
87
+ tcg_gen_bswap32_i32,
88
+ gen_swap_half,
89
+ NULL,
90
+ NULL,
91
+ };
92
+ return do_2misc(s, a, fn[a->size]);
93
+}
94
+
95
+static bool trans_VREV16(DisasContext *s, arg_2misc *a)
96
+{
97
+ if (a->size != 0) {
98
+ return false;
99
+ }
100
+ return do_2misc(s, a, gen_rev16);
101
+}
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate.c
105
+++ b/target/arm/translate.c
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
107
case NEON_2RM_AESE: case NEON_2RM_AESMC:
108
case NEON_2RM_SHA1H:
109
case NEON_2RM_SHA1SU1:
110
+ case NEON_2RM_VREV32:
111
+ case NEON_2RM_VREV16:
112
/* handled by decodetree */
113
return 1;
114
case NEON_2RM_VTRN:
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
116
for (pass = 0; pass < (q ? 4 : 2); pass++) {
117
tmp = neon_load_reg(rm, pass);
118
switch (op) {
119
- case NEON_2RM_VREV32:
120
- switch (size) {
121
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
122
- case 1: gen_swap_half(tmp, tmp); break;
123
- default: abort();
124
- }
125
- break;
126
- case NEON_2RM_VREV16:
127
- gen_rev16(tmp, tmp);
128
- break;
129
case NEON_2RM_VCLS:
130
switch (size) {
131
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
132
--
445
--
133
2.20.1
446
2.25.1
134
135
diff view generated by jsdifflib
1
Convert to decodetree the insns in the Neon 2-reg-misc grouping which
1
From: Richard Henderson <richard.henderson@linaro.org>
2
we implement using gvec.
3
2
3
We cannot reuse the SVE functions for LD[1-4] and ST[1-4],
4
because those functions accept only a Zreg register number.
5
For SME, we want to pass a pointer into ZA storage.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-21-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-8-peter.maydell@linaro.org
7
---
11
---
8
target/arm/neon-dp.decode | 11 +++++++
12
target/arm/helper-sme.h | 82 +++++
9
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
13
target/arm/sme.decode | 9 +
10
target/arm/translate.c | 35 +++++----------------
14
target/arm/sme_helper.c | 595 +++++++++++++++++++++++++++++++++++++
11
3 files changed, 74 insertions(+), 27 deletions(-)
15
target/arm/translate-sme.c | 70 +++++
16
4 files changed, 756 insertions(+)
12
17
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
20
--- a/target/arm/helper-sme.h
16
+++ b/target/arm/neon-dp.decode
21
+++ b/target/arm/helper-sme.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sme_mova_cz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
23
DEF_HELPER_FLAGS_4(sme_mova_zc_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
24
DEF_HELPER_FLAGS_4(sme_mova_cz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
25
DEF_HELPER_FLAGS_4(sme_mova_zc_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
+ VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
26
+
22
+
27
+DEF_HELPER_FLAGS_5(sme_ld1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
23
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
28
+DEF_HELPER_FLAGS_5(sme_ld1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
24
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
29
+DEF_HELPER_FLAGS_5(sme_ld1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
25
30
+DEF_HELPER_FLAGS_5(sme_ld1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
26
+ VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
31
+
27
+ VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
32
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
28
+ VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
33
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
29
+ VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
34
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
30
+ VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
35
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
31
+
36
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
32
+ VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
37
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
33
+ VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
38
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
34
+
39
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
40
+
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
41
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
37
42
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
43
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
44
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
49
+
50
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
56
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
58
+
59
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
61
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
63
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
65
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
67
+
68
+DEF_HELPER_FLAGS_5(sme_st1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
69
+DEF_HELPER_FLAGS_5(sme_st1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_5(sme_st1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
71
+DEF_HELPER_FLAGS_5(sme_st1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
72
+
73
+DEF_HELPER_FLAGS_5(sme_st1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
74
+DEF_HELPER_FLAGS_5(sme_st1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
75
+DEF_HELPER_FLAGS_5(sme_st1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
76
+DEF_HELPER_FLAGS_5(sme_st1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_5(sme_st1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
78
+DEF_HELPER_FLAGS_5(sme_st1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_5(sme_st1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
80
+DEF_HELPER_FLAGS_5(sme_st1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
81
+
82
+DEF_HELPER_FLAGS_5(sme_st1s_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_5(sme_st1s_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
84
+DEF_HELPER_FLAGS_5(sme_st1s_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_5(sme_st1s_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
86
+DEF_HELPER_FLAGS_5(sme_st1s_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
87
+DEF_HELPER_FLAGS_5(sme_st1s_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
88
+DEF_HELPER_FLAGS_5(sme_st1s_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
89
+DEF_HELPER_FLAGS_5(sme_st1s_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
90
+
91
+DEF_HELPER_FLAGS_5(sme_st1d_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
92
+DEF_HELPER_FLAGS_5(sme_st1d_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
93
+DEF_HELPER_FLAGS_5(sme_st1d_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
94
+DEF_HELPER_FLAGS_5(sme_st1d_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
95
+DEF_HELPER_FLAGS_5(sme_st1d_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
96
+DEF_HELPER_FLAGS_5(sme_st1d_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
97
+DEF_HELPER_FLAGS_5(sme_st1d_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
98
+DEF_HELPER_FLAGS_5(sme_st1d_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
99
+
100
+DEF_HELPER_FLAGS_5(sme_st1q_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
101
+DEF_HELPER_FLAGS_5(sme_st1q_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
102
+DEF_HELPER_FLAGS_5(sme_st1q_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
103
+DEF_HELPER_FLAGS_5(sme_st1q_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
104
+DEF_HELPER_FLAGS_5(sme_st1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
105
+DEF_HELPER_FLAGS_5(sme_st1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
106
+DEF_HELPER_FLAGS_5(sme_st1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
107
+DEF_HELPER_FLAGS_5(sme_st1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
108
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
39
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-neon.inc.c
110
--- a/target/arm/sme.decode
41
+++ b/target/arm/translate-neon.inc.c
111
+++ b/target/arm/sme.decode
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
112
@@ -XXX,XX +XXX,XX @@ MOVA 11000000 esz:2 00001 0 v:1 .. pg:3 0 za_imm:4 zr:5 \
113
&mova to_vec=1 rs=%mova_rs
114
MOVA 11000000 11 00001 1 v:1 .. pg:3 0 za_imm:4 zr:5 \
115
&mova to_vec=1 rs=%mova_rs esz=4
116
+
117
+### SME Memory
118
+
119
+&ldst esz rs pg rn rm za_imm v:bool st:bool
120
+
121
+LDST1 1110000 0 esz:2 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
122
+ &ldst rs=%mova_rs
123
+LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
124
+ &ldst esz=4 rs=%mova_rs
125
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/sme_helper.c
128
+++ b/target/arm/sme_helper.c
129
@@ -XXX,XX +XXX,XX @@
130
131
#include "qemu/osdep.h"
132
#include "cpu.h"
133
+#include "internals.h"
134
#include "tcg/tcg-gvec-desc.h"
135
#include "exec/helper-proto.h"
136
+#include "exec/cpu_ldst.h"
137
+#include "exec/exec-all.h"
138
#include "qemu/int128.h"
139
#include "vec_internal.h"
140
+#include "sve_ldst_internal.h"
141
142
/* ResetSVEState */
143
void arm_reset_sve_state(CPUARMState *env)
144
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_mova_zc_q)(void *vd, void *za, void *vg, uint32_t desc)
145
}
146
147
#undef DO_MOVA_Z
148
+
149
+/*
150
+ * Clear elements in a tile slice comprising len bytes.
151
+ */
152
+
153
+typedef void ClearFn(void *ptr, size_t off, size_t len);
154
+
155
+static void clear_horizontal(void *ptr, size_t off, size_t len)
156
+{
157
+ memset(ptr + off, 0, len);
158
+}
159
+
160
+static void clear_vertical_b(void *vptr, size_t off, size_t len)
161
+{
162
+ for (size_t i = 0; i < len; ++i) {
163
+ *(uint8_t *)(vptr + tile_vslice_offset(i + off)) = 0;
164
+ }
165
+}
166
+
167
+static void clear_vertical_h(void *vptr, size_t off, size_t len)
168
+{
169
+ for (size_t i = 0; i < len; i += 2) {
170
+ *(uint16_t *)(vptr + tile_vslice_offset(i + off)) = 0;
171
+ }
172
+}
173
+
174
+static void clear_vertical_s(void *vptr, size_t off, size_t len)
175
+{
176
+ for (size_t i = 0; i < len; i += 4) {
177
+ *(uint32_t *)(vptr + tile_vslice_offset(i + off)) = 0;
178
+ }
179
+}
180
+
181
+static void clear_vertical_d(void *vptr, size_t off, size_t len)
182
+{
183
+ for (size_t i = 0; i < len; i += 8) {
184
+ *(uint64_t *)(vptr + tile_vslice_offset(i + off)) = 0;
185
+ }
186
+}
187
+
188
+static void clear_vertical_q(void *vptr, size_t off, size_t len)
189
+{
190
+ for (size_t i = 0; i < len; i += 16) {
191
+ memset(vptr + tile_vslice_offset(i + off), 0, 16);
192
+ }
193
+}
194
+
195
+/*
196
+ * Copy elements from an array into a tile slice comprising len bytes.
197
+ */
198
+
199
+typedef void CopyFn(void *dst, const void *src, size_t len);
200
+
201
+static void copy_horizontal(void *dst, const void *src, size_t len)
202
+{
203
+ memcpy(dst, src, len);
204
+}
205
+
206
+static void copy_vertical_b(void *vdst, const void *vsrc, size_t len)
207
+{
208
+ const uint8_t *src = vsrc;
209
+ uint8_t *dst = vdst;
210
+ size_t i;
211
+
212
+ for (i = 0; i < len; ++i) {
213
+ dst[tile_vslice_index(i)] = src[i];
214
+ }
215
+}
216
+
217
+static void copy_vertical_h(void *vdst, const void *vsrc, size_t len)
218
+{
219
+ const uint16_t *src = vsrc;
220
+ uint16_t *dst = vdst;
221
+ size_t i;
222
+
223
+ for (i = 0; i < len / 2; ++i) {
224
+ dst[tile_vslice_index(i)] = src[i];
225
+ }
226
+}
227
+
228
+static void copy_vertical_s(void *vdst, const void *vsrc, size_t len)
229
+{
230
+ const uint32_t *src = vsrc;
231
+ uint32_t *dst = vdst;
232
+ size_t i;
233
+
234
+ for (i = 0; i < len / 4; ++i) {
235
+ dst[tile_vslice_index(i)] = src[i];
236
+ }
237
+}
238
+
239
+static void copy_vertical_d(void *vdst, const void *vsrc, size_t len)
240
+{
241
+ const uint64_t *src = vsrc;
242
+ uint64_t *dst = vdst;
243
+ size_t i;
244
+
245
+ for (i = 0; i < len / 8; ++i) {
246
+ dst[tile_vslice_index(i)] = src[i];
247
+ }
248
+}
249
+
250
+static void copy_vertical_q(void *vdst, const void *vsrc, size_t len)
251
+{
252
+ for (size_t i = 0; i < len; i += 16) {
253
+ memcpy(vdst + tile_vslice_offset(i), vsrc + i, 16);
254
+ }
255
+}
256
+
257
+/*
258
+ * Host and TLB primitives for vertical tile slice addressing.
259
+ */
260
+
261
+#define DO_LD(NAME, TYPE, HOST, TLB) \
262
+static inline void sme_##NAME##_v_host(void *za, intptr_t off, void *host) \
263
+{ \
264
+ TYPE val = HOST(host); \
265
+ *(TYPE *)(za + tile_vslice_offset(off)) = val; \
266
+} \
267
+static inline void sme_##NAME##_v_tlb(CPUARMState *env, void *za, \
268
+ intptr_t off, target_ulong addr, uintptr_t ra) \
269
+{ \
270
+ TYPE val = TLB(env, useronly_clean_ptr(addr), ra); \
271
+ *(TYPE *)(za + tile_vslice_offset(off)) = val; \
272
+}
273
+
274
+#define DO_ST(NAME, TYPE, HOST, TLB) \
275
+static inline void sme_##NAME##_v_host(void *za, intptr_t off, void *host) \
276
+{ \
277
+ TYPE val = *(TYPE *)(za + tile_vslice_offset(off)); \
278
+ HOST(host, val); \
279
+} \
280
+static inline void sme_##NAME##_v_tlb(CPUARMState *env, void *za, \
281
+ intptr_t off, target_ulong addr, uintptr_t ra) \
282
+{ \
283
+ TYPE val = *(TYPE *)(za + tile_vslice_offset(off)); \
284
+ TLB(env, useronly_clean_ptr(addr), val, ra); \
285
+}
286
+
287
+/*
288
+ * The ARMVectorReg elements are stored in host-endian 64-bit units.
289
+ * For 128-bit quantities, the sequence defined by the Elem[] pseudocode
290
+ * corresponds to storing the two 64-bit pieces in little-endian order.
291
+ */
292
+#define DO_LDQ(HNAME, VNAME, BE, HOST, TLB) \
293
+static inline void HNAME##_host(void *za, intptr_t off, void *host) \
294
+{ \
295
+ uint64_t val0 = HOST(host), val1 = HOST(host + 8); \
296
+ uint64_t *ptr = za + off; \
297
+ ptr[0] = BE ? val1 : val0, ptr[1] = BE ? val0 : val1; \
298
+} \
299
+static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
300
+{ \
301
+ HNAME##_host(za, tile_vslice_offset(off), host); \
302
+} \
303
+static inline void HNAME##_tlb(CPUARMState *env, void *za, intptr_t off, \
304
+ target_ulong addr, uintptr_t ra) \
305
+{ \
306
+ uint64_t val0 = TLB(env, useronly_clean_ptr(addr), ra); \
307
+ uint64_t val1 = TLB(env, useronly_clean_ptr(addr + 8), ra); \
308
+ uint64_t *ptr = za + off; \
309
+ ptr[0] = BE ? val1 : val0, ptr[1] = BE ? val0 : val1; \
310
+} \
311
+static inline void VNAME##_v_tlb(CPUARMState *env, void *za, intptr_t off, \
312
+ target_ulong addr, uintptr_t ra) \
313
+{ \
314
+ HNAME##_tlb(env, za, tile_vslice_offset(off), addr, ra); \
315
+}
316
+
317
+#define DO_STQ(HNAME, VNAME, BE, HOST, TLB) \
318
+static inline void HNAME##_host(void *za, intptr_t off, void *host) \
319
+{ \
320
+ uint64_t *ptr = za + off; \
321
+ HOST(host, ptr[BE]); \
322
+ HOST(host + 1, ptr[!BE]); \
323
+} \
324
+static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
325
+{ \
326
+ HNAME##_host(za, tile_vslice_offset(off), host); \
327
+} \
328
+static inline void HNAME##_tlb(CPUARMState *env, void *za, intptr_t off, \
329
+ target_ulong addr, uintptr_t ra) \
330
+{ \
331
+ uint64_t *ptr = za + off; \
332
+ TLB(env, useronly_clean_ptr(addr), ptr[BE], ra); \
333
+ TLB(env, useronly_clean_ptr(addr + 8), ptr[!BE], ra); \
334
+} \
335
+static inline void VNAME##_v_tlb(CPUARMState *env, void *za, intptr_t off, \
336
+ target_ulong addr, uintptr_t ra) \
337
+{ \
338
+ HNAME##_tlb(env, za, tile_vslice_offset(off), addr, ra); \
339
+}
340
+
341
+DO_LD(ld1b, uint8_t, ldub_p, cpu_ldub_data_ra)
342
+DO_LD(ld1h_be, uint16_t, lduw_be_p, cpu_lduw_be_data_ra)
343
+DO_LD(ld1h_le, uint16_t, lduw_le_p, cpu_lduw_le_data_ra)
344
+DO_LD(ld1s_be, uint32_t, ldl_be_p, cpu_ldl_be_data_ra)
345
+DO_LD(ld1s_le, uint32_t, ldl_le_p, cpu_ldl_le_data_ra)
346
+DO_LD(ld1d_be, uint64_t, ldq_be_p, cpu_ldq_be_data_ra)
347
+DO_LD(ld1d_le, uint64_t, ldq_le_p, cpu_ldq_le_data_ra)
348
+
349
+DO_LDQ(sve_ld1qq_be, sme_ld1q_be, 1, ldq_be_p, cpu_ldq_be_data_ra)
350
+DO_LDQ(sve_ld1qq_le, sme_ld1q_le, 0, ldq_le_p, cpu_ldq_le_data_ra)
351
+
352
+DO_ST(st1b, uint8_t, stb_p, cpu_stb_data_ra)
353
+DO_ST(st1h_be, uint16_t, stw_be_p, cpu_stw_be_data_ra)
354
+DO_ST(st1h_le, uint16_t, stw_le_p, cpu_stw_le_data_ra)
355
+DO_ST(st1s_be, uint32_t, stl_be_p, cpu_stl_be_data_ra)
356
+DO_ST(st1s_le, uint32_t, stl_le_p, cpu_stl_le_data_ra)
357
+DO_ST(st1d_be, uint64_t, stq_be_p, cpu_stq_be_data_ra)
358
+DO_ST(st1d_le, uint64_t, stq_le_p, cpu_stq_le_data_ra)
359
+
360
+DO_STQ(sve_st1qq_be, sme_st1q_be, 1, stq_be_p, cpu_stq_be_data_ra)
361
+DO_STQ(sve_st1qq_le, sme_st1q_le, 0, stq_le_p, cpu_stq_le_data_ra)
362
+
363
+#undef DO_LD
364
+#undef DO_ST
365
+#undef DO_LDQ
366
+#undef DO_STQ
367
+
368
+/*
369
+ * Common helper for all contiguous predicated loads.
370
+ */
371
+
372
+static inline QEMU_ALWAYS_INLINE
373
+void sme_ld1(CPUARMState *env, void *za, uint64_t *vg,
374
+ const target_ulong addr, uint32_t desc, const uintptr_t ra,
375
+ const int esz, uint32_t mtedesc, bool vertical,
376
+ sve_ldst1_host_fn *host_fn,
377
+ sve_ldst1_tlb_fn *tlb_fn,
378
+ ClearFn *clr_fn,
379
+ CopyFn *cpy_fn)
380
+{
381
+ const intptr_t reg_max = simd_oprsz(desc);
382
+ const intptr_t esize = 1 << esz;
383
+ intptr_t reg_off, reg_last;
384
+ SVEContLdSt info;
385
+ void *host;
386
+ int flags;
387
+
388
+ /* Find the active elements. */
389
+ if (!sve_cont_ldst_elements(&info, addr, vg, reg_max, esz, esize)) {
390
+ /* The entire predicate was false; no load occurs. */
391
+ clr_fn(za, 0, reg_max);
392
+ return;
393
+ }
394
+
395
+ /* Probe the page(s). Exit with exception for any invalid page. */
396
+ sve_cont_ldst_pages(&info, FAULT_ALL, env, addr, MMU_DATA_LOAD, ra);
397
+
398
+ /* Handle watchpoints for all active elements. */
399
+ sve_cont_ldst_watchpoints(&info, env, vg, addr, esize, esize,
400
+ BP_MEM_READ, ra);
401
+
402
+ /*
403
+ * Handle mte checks for all active elements.
404
+ * Since TBI must be set for MTE, !mtedesc => !mte_active.
405
+ */
406
+ if (mtedesc) {
407
+ sve_cont_ldst_mte_check(&info, env, vg, addr, esize, esize,
408
+ mtedesc, ra);
409
+ }
410
+
411
+ flags = info.page[0].flags | info.page[1].flags;
412
+ if (unlikely(flags != 0)) {
413
+#ifdef CONFIG_USER_ONLY
414
+ g_assert_not_reached();
415
+#else
416
+ /*
417
+ * At least one page includes MMIO.
418
+ * Any bus operation can fail with cpu_transaction_failed,
419
+ * which for ARM will raise SyncExternal. Perform the load
420
+ * into scratch memory to preserve register state until the end.
421
+ */
422
+ ARMVectorReg scratch = { };
423
+
424
+ reg_off = info.reg_off_first[0];
425
+ reg_last = info.reg_off_last[1];
426
+ if (reg_last < 0) {
427
+ reg_last = info.reg_off_split;
428
+ if (reg_last < 0) {
429
+ reg_last = info.reg_off_last[0];
430
+ }
431
+ }
432
+
433
+ do {
434
+ uint64_t pg = vg[reg_off >> 6];
435
+ do {
436
+ if ((pg >> (reg_off & 63)) & 1) {
437
+ tlb_fn(env, &scratch, reg_off, addr + reg_off, ra);
438
+ }
439
+ reg_off += esize;
440
+ } while (reg_off & 63);
441
+ } while (reg_off <= reg_last);
442
+
443
+ cpy_fn(za, &scratch, reg_max);
444
+ return;
445
+#endif
446
+ }
447
+
448
+ /* The entire operation is in RAM, on valid pages. */
449
+
450
+ reg_off = info.reg_off_first[0];
451
+ reg_last = info.reg_off_last[0];
452
+ host = info.page[0].host;
453
+
454
+ if (!vertical) {
455
+ memset(za, 0, reg_max);
456
+ } else if (reg_off) {
457
+ clr_fn(za, 0, reg_off);
458
+ }
459
+
460
+ while (reg_off <= reg_last) {
461
+ uint64_t pg = vg[reg_off >> 6];
462
+ do {
463
+ if ((pg >> (reg_off & 63)) & 1) {
464
+ host_fn(za, reg_off, host + reg_off);
465
+ } else if (vertical) {
466
+ clr_fn(za, reg_off, esize);
467
+ }
468
+ reg_off += esize;
469
+ } while (reg_off <= reg_last && (reg_off & 63));
470
+ }
471
+
472
+ /*
473
+ * Use the slow path to manage the cross-page misalignment.
474
+ * But we know this is RAM and cannot trap.
475
+ */
476
+ reg_off = info.reg_off_split;
477
+ if (unlikely(reg_off >= 0)) {
478
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
479
+ }
480
+
481
+ reg_off = info.reg_off_first[1];
482
+ if (unlikely(reg_off >= 0)) {
483
+ reg_last = info.reg_off_last[1];
484
+ host = info.page[1].host;
485
+
486
+ do {
487
+ uint64_t pg = vg[reg_off >> 6];
488
+ do {
489
+ if ((pg >> (reg_off & 63)) & 1) {
490
+ host_fn(za, reg_off, host + reg_off);
491
+ } else if (vertical) {
492
+ clr_fn(za, reg_off, esize);
493
+ }
494
+ reg_off += esize;
495
+ } while (reg_off & 63);
496
+ } while (reg_off <= reg_last);
497
+ }
498
+}
499
+
500
+static inline QEMU_ALWAYS_INLINE
501
+void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
502
+ target_ulong addr, uint32_t desc, uintptr_t ra,
503
+ const int esz, bool vertical,
504
+ sve_ldst1_host_fn *host_fn,
505
+ sve_ldst1_tlb_fn *tlb_fn,
506
+ ClearFn *clr_fn,
507
+ CopyFn *cpy_fn)
508
+{
509
+ uint32_t mtedesc = desc >> (SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
510
+ int bit55 = extract64(addr, 55, 1);
511
+
512
+ /* Remove mtedesc from the normal sve descriptor. */
513
+ desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
514
+
515
+ /* Perform gross MTE suppression early. */
516
+ if (!tbi_check(desc, bit55) ||
517
+ tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
518
+ mtedesc = 0;
519
+ }
520
+
521
+ sme_ld1(env, za, vg, addr, desc, ra, esz, mtedesc, vertical,
522
+ host_fn, tlb_fn, clr_fn, cpy_fn);
523
+}
524
+
525
+#define DO_LD(L, END, ESZ) \
526
+void HELPER(sme_ld1##L##END##_h)(CPUARMState *env, void *za, void *vg, \
527
+ target_ulong addr, uint32_t desc) \
528
+{ \
529
+ sme_ld1(env, za, vg, addr, desc, GETPC(), ESZ, 0, false, \
530
+ sve_ld1##L##L##END##_host, sve_ld1##L##L##END##_tlb, \
531
+ clear_horizontal, copy_horizontal); \
532
+} \
533
+void HELPER(sme_ld1##L##END##_v)(CPUARMState *env, void *za, void *vg, \
534
+ target_ulong addr, uint32_t desc) \
535
+{ \
536
+ sme_ld1(env, za, vg, addr, desc, GETPC(), ESZ, 0, true, \
537
+ sme_ld1##L##END##_v_host, sme_ld1##L##END##_v_tlb, \
538
+ clear_vertical_##L, copy_vertical_##L); \
539
+} \
540
+void HELPER(sme_ld1##L##END##_h_mte)(CPUARMState *env, void *za, void *vg, \
541
+ target_ulong addr, uint32_t desc) \
542
+{ \
543
+ sme_ld1_mte(env, za, vg, addr, desc, GETPC(), ESZ, false, \
544
+ sve_ld1##L##L##END##_host, sve_ld1##L##L##END##_tlb, \
545
+ clear_horizontal, copy_horizontal); \
546
+} \
547
+void HELPER(sme_ld1##L##END##_v_mte)(CPUARMState *env, void *za, void *vg, \
548
+ target_ulong addr, uint32_t desc) \
549
+{ \
550
+ sme_ld1_mte(env, za, vg, addr, desc, GETPC(), ESZ, true, \
551
+ sme_ld1##L##END##_v_host, sme_ld1##L##END##_v_tlb, \
552
+ clear_vertical_##L, copy_vertical_##L); \
553
+}
554
+
555
+DO_LD(b, , MO_8)
556
+DO_LD(h, _be, MO_16)
557
+DO_LD(h, _le, MO_16)
558
+DO_LD(s, _be, MO_32)
559
+DO_LD(s, _le, MO_32)
560
+DO_LD(d, _be, MO_64)
561
+DO_LD(d, _le, MO_64)
562
+DO_LD(q, _be, MO_128)
563
+DO_LD(q, _le, MO_128)
564
+
565
+#undef DO_LD
566
+
567
+/*
568
+ * Common helper for all contiguous predicated stores.
569
+ */
570
+
571
+static inline QEMU_ALWAYS_INLINE
572
+void sme_st1(CPUARMState *env, void *za, uint64_t *vg,
573
+ const target_ulong addr, uint32_t desc, const uintptr_t ra,
574
+ const int esz, uint32_t mtedesc, bool vertical,
575
+ sve_ldst1_host_fn *host_fn,
576
+ sve_ldst1_tlb_fn *tlb_fn)
577
+{
578
+ const intptr_t reg_max = simd_oprsz(desc);
579
+ const intptr_t esize = 1 << esz;
580
+ intptr_t reg_off, reg_last;
581
+ SVEContLdSt info;
582
+ void *host;
583
+ int flags;
584
+
585
+ /* Find the active elements. */
586
+ if (!sve_cont_ldst_elements(&info, addr, vg, reg_max, esz, esize)) {
587
+ /* The entire predicate was false; no store occurs. */
588
+ return;
589
+ }
590
+
591
+ /* Probe the page(s). Exit with exception for any invalid page. */
592
+ sve_cont_ldst_pages(&info, FAULT_ALL, env, addr, MMU_DATA_STORE, ra);
593
+
594
+ /* Handle watchpoints for all active elements. */
595
+ sve_cont_ldst_watchpoints(&info, env, vg, addr, esize, esize,
596
+ BP_MEM_WRITE, ra);
597
+
598
+ /*
599
+ * Handle mte checks for all active elements.
600
+ * Since TBI must be set for MTE, !mtedesc => !mte_active.
601
+ */
602
+ if (mtedesc) {
603
+ sve_cont_ldst_mte_check(&info, env, vg, addr, esize, esize,
604
+ mtedesc, ra);
605
+ }
606
+
607
+ flags = info.page[0].flags | info.page[1].flags;
608
+ if (unlikely(flags != 0)) {
609
+#ifdef CONFIG_USER_ONLY
610
+ g_assert_not_reached();
611
+#else
612
+ /*
613
+ * At least one page includes MMIO.
614
+ * Any bus operation can fail with cpu_transaction_failed,
615
+ * which for ARM will raise SyncExternal. We cannot avoid
616
+ * this fault and will leave with the store incomplete.
617
+ */
618
+ reg_off = info.reg_off_first[0];
619
+ reg_last = info.reg_off_last[1];
620
+ if (reg_last < 0) {
621
+ reg_last = info.reg_off_split;
622
+ if (reg_last < 0) {
623
+ reg_last = info.reg_off_last[0];
624
+ }
625
+ }
626
+
627
+ do {
628
+ uint64_t pg = vg[reg_off >> 6];
629
+ do {
630
+ if ((pg >> (reg_off & 63)) & 1) {
631
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
632
+ }
633
+ reg_off += esize;
634
+ } while (reg_off & 63);
635
+ } while (reg_off <= reg_last);
636
+ return;
637
+#endif
638
+ }
639
+
640
+ reg_off = info.reg_off_first[0];
641
+ reg_last = info.reg_off_last[0];
642
+ host = info.page[0].host;
643
+
644
+ while (reg_off <= reg_last) {
645
+ uint64_t pg = vg[reg_off >> 6];
646
+ do {
647
+ if ((pg >> (reg_off & 63)) & 1) {
648
+ host_fn(za, reg_off, host + reg_off);
649
+ }
650
+ reg_off += 1 << esz;
651
+ } while (reg_off <= reg_last && (reg_off & 63));
652
+ }
653
+
654
+ /*
655
+ * Use the slow path to manage the cross-page misalignment.
656
+ * But we know this is RAM and cannot trap.
657
+ */
658
+ reg_off = info.reg_off_split;
659
+ if (unlikely(reg_off >= 0)) {
660
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
661
+ }
662
+
663
+ reg_off = info.reg_off_first[1];
664
+ if (unlikely(reg_off >= 0)) {
665
+ reg_last = info.reg_off_last[1];
666
+ host = info.page[1].host;
667
+
668
+ do {
669
+ uint64_t pg = vg[reg_off >> 6];
670
+ do {
671
+ if ((pg >> (reg_off & 63)) & 1) {
672
+ host_fn(za, reg_off, host + reg_off);
673
+ }
674
+ reg_off += 1 << esz;
675
+ } while (reg_off & 63);
676
+ } while (reg_off <= reg_last);
677
+ }
678
+}
679
+
680
+static inline QEMU_ALWAYS_INLINE
681
+void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
682
+ uint32_t desc, uintptr_t ra, int esz, bool vertical,
683
+ sve_ldst1_host_fn *host_fn,
684
+ sve_ldst1_tlb_fn *tlb_fn)
685
+{
686
+ uint32_t mtedesc = desc >> (SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
687
+ int bit55 = extract64(addr, 55, 1);
688
+
689
+ /* Remove mtedesc from the normal sve descriptor. */
690
+ desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
691
+
692
+ /* Perform gross MTE suppression early. */
693
+ if (!tbi_check(desc, bit55) ||
694
+ tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
695
+ mtedesc = 0;
696
+ }
697
+
698
+ sme_st1(env, za, vg, addr, desc, ra, esz, mtedesc,
699
+ vertical, host_fn, tlb_fn);
700
+}
701
+
702
+#define DO_ST(L, END, ESZ) \
703
+void HELPER(sme_st1##L##END##_h)(CPUARMState *env, void *za, void *vg, \
704
+ target_ulong addr, uint32_t desc) \
705
+{ \
706
+ sme_st1(env, za, vg, addr, desc, GETPC(), ESZ, 0, false, \
707
+ sve_st1##L##L##END##_host, sve_st1##L##L##END##_tlb); \
708
+} \
709
+void HELPER(sme_st1##L##END##_v)(CPUARMState *env, void *za, void *vg, \
710
+ target_ulong addr, uint32_t desc) \
711
+{ \
712
+ sme_st1(env, za, vg, addr, desc, GETPC(), ESZ, 0, true, \
713
+ sme_st1##L##END##_v_host, sme_st1##L##END##_v_tlb); \
714
+} \
715
+void HELPER(sme_st1##L##END##_h_mte)(CPUARMState *env, void *za, void *vg, \
716
+ target_ulong addr, uint32_t desc) \
717
+{ \
718
+ sme_st1_mte(env, za, vg, addr, desc, GETPC(), ESZ, false, \
719
+ sve_st1##L##L##END##_host, sve_st1##L##L##END##_tlb); \
720
+} \
721
+void HELPER(sme_st1##L##END##_v_mte)(CPUARMState *env, void *za, void *vg, \
722
+ target_ulong addr, uint32_t desc) \
723
+{ \
724
+ sme_st1_mte(env, za, vg, addr, desc, GETPC(), ESZ, true, \
725
+ sme_st1##L##END##_v_host, sme_st1##L##END##_v_tlb); \
726
+}
727
+
728
+DO_ST(b, , MO_8)
729
+DO_ST(h, _be, MO_16)
730
+DO_ST(h, _le, MO_16)
731
+DO_ST(s, _be, MO_32)
732
+DO_ST(s, _le, MO_32)
733
+DO_ST(d, _be, MO_64)
734
+DO_ST(d, _le, MO_64)
735
+DO_ST(q, _be, MO_128)
736
+DO_ST(q, _le, MO_128)
737
+
738
+#undef DO_ST
739
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
740
index XXXXXXX..XXXXXXX 100644
741
--- a/target/arm/translate-sme.c
742
+++ b/target/arm/translate-sme.c
743
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVA(DisasContext *s, arg_MOVA *a)
43
744
44
return true;
745
return true;
45
}
746
}
46
+
747
+
47
+static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
748
+static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
48
+{
749
+{
49
+ int vec_size = a->q ? 16 : 8;
750
+ typedef void GenLdSt1(TCGv_env, TCGv_ptr, TCGv_ptr, TCGv, TCGv_i32);
50
+ int rd_ofs = neon_reg_offset(a->vd, 0);
751
+
51
+ int rm_ofs = neon_reg_offset(a->vm, 0);
752
+ /*
52
+
753
+ * Indexed by [esz][be][v][mte][st], which is (except for load/store)
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
754
+ * also the order in which the elements appear in the function names,
755
+ * and so how we must concatenate the pieces.
756
+ */
757
+
758
+#define FN_LS(F) { gen_helper_sme_ld1##F, gen_helper_sme_st1##F }
759
+#define FN_MTE(F) { FN_LS(F), FN_LS(F##_mte) }
760
+#define FN_HV(F) { FN_MTE(F##_h), FN_MTE(F##_v) }
761
+#define FN_END(L, B) { FN_HV(L), FN_HV(B) }
762
+
763
+ static GenLdSt1 * const fns[5][2][2][2][2] = {
764
+ FN_END(b, b),
765
+ FN_END(h_le, h_be),
766
+ FN_END(s_le, s_be),
767
+ FN_END(d_le, d_be),
768
+ FN_END(q_le, q_be),
769
+ };
770
+
771
+#undef FN_LS
772
+#undef FN_MTE
773
+#undef FN_HV
774
+#undef FN_END
775
+
776
+ TCGv_ptr t_za, t_pg;
777
+ TCGv_i64 addr;
778
+ int svl, desc = 0;
779
+ bool be = s->be_data == MO_BE;
780
+ bool mte = s->mte_active[0];
781
+
782
+ if (!dc_isar_feature(aa64_sme, s)) {
54
+ return false;
783
+ return false;
55
+ }
784
+ }
56
+
785
+ if (!sme_smza_enabled_check(s)) {
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size == 3) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
786
+ return true;
73
+ }
787
+ }
74
+
788
+
75
+ fn(a->size, rd_ofs, rm_ofs, vec_size, vec_size);
789
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v);
76
+
790
+ t_pg = pred_full_reg_ptr(s, a->pg);
791
+ addr = tcg_temp_new_i64();
792
+
793
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
794
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
795
+
796
+ if (mte) {
797
+ desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
798
+ desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
799
+ desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
800
+ desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
801
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
802
+ desc <<= SVE_MTEDESC_SHIFT;
803
+ } else {
804
+ addr = clean_data_tbi(s, addr);
805
+ }
806
+ svl = streaming_vec_reg_size(s);
807
+ desc = simd_desc(svl, svl, desc);
808
+
809
+ fns[a->esz][be][a->v][mte][a->st](cpu_env, t_za, t_pg, addr,
810
+ tcg_constant_i32(desc));
811
+
812
+ tcg_temp_free_ptr(t_za);
813
+ tcg_temp_free_ptr(t_pg);
814
+ tcg_temp_free_i64(addr);
77
+ return true;
815
+ return true;
78
+}
816
+}
79
+
80
+#define DO_2MISC_VEC(INSN, FN) \
81
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
82
+ { \
83
+ return do_2misc_vec(s, a, FN); \
84
+ }
85
+
86
+DO_2MISC_VEC(VNEG, tcg_gen_gvec_neg)
87
+DO_2MISC_VEC(VABS, tcg_gen_gvec_abs)
88
+DO_2MISC_VEC(VCEQ0, gen_gvec_ceq0)
89
+DO_2MISC_VEC(VCGT0, gen_gvec_cgt0)
90
+DO_2MISC_VEC(VCLE0, gen_gvec_cle0)
91
+DO_2MISC_VEC(VCGE0, gen_gvec_cge0)
92
+DO_2MISC_VEC(VCLT0, gen_gvec_clt0)
93
+
94
+static bool trans_VMVN(DisasContext *s, arg_2misc *a)
95
+{
96
+ if (a->size != 0) {
97
+ return false;
98
+ }
99
+ return do_2misc_vec(s, a, tcg_gen_gvec_not);
100
+}
101
diff --git a/target/arm/translate.c b/target/arm/translate.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/translate.c
104
+++ b/target/arm/translate.c
105
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
106
int size;
107
int pass;
108
int u;
109
- int vec_size;
110
TCGv_i32 tmp, tmp2;
111
112
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
113
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
114
VFP_DREG_D(rd, insn);
115
VFP_DREG_M(rm, insn);
116
size = (insn >> 20) & 3;
117
- vec_size = q ? 16 : 8;
118
rd_ofs = neon_reg_offset(rd, 0);
119
rm_ofs = neon_reg_offset(rm, 0);
120
121
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
122
case NEON_2RM_VSHLL:
123
case NEON_2RM_VCVT_F16_F32:
124
case NEON_2RM_VCVT_F32_F16:
125
+ case NEON_2RM_VMVN:
126
+ case NEON_2RM_VNEG:
127
+ case NEON_2RM_VABS:
128
+ case NEON_2RM_VCEQ0:
129
+ case NEON_2RM_VCGT0:
130
+ case NEON_2RM_VCLE0:
131
+ case NEON_2RM_VCGE0:
132
+ case NEON_2RM_VCLT0:
133
/* handled by decodetree */
134
return 1;
135
case NEON_2RM_VTRN:
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
q ? gen_helper_crypto_sha256su0
138
: gen_helper_crypto_sha1su1);
139
break;
140
- case NEON_2RM_VMVN:
141
- tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
142
- break;
143
- case NEON_2RM_VNEG:
144
- tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
145
- break;
146
- case NEON_2RM_VABS:
147
- tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
148
- break;
149
-
150
- case NEON_2RM_VCEQ0:
151
- gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
152
- break;
153
- case NEON_2RM_VCGT0:
154
- gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
155
- break;
156
- case NEON_2RM_VCLE0:
157
- gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
158
- break;
159
- case NEON_2RM_VCGE0:
160
- gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
161
- break;
162
- case NEON_2RM_VCLT0:
163
- gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
164
- break;
165
166
default:
167
elementwise:
168
--
817
--
169
2.20.1
818
2.25.1
170
171
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since commit d70c996df23f, when enabling the PMU we get:
3
Add a TCGv_ptr base argument, which will be cpu_env for SVE.
4
We will reuse this for SME save and restore array insns.
4
5
5
$ qemu-system-aarch64 -cpu host,pmu=on -M virt,accel=kvm,gic-version=3
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Segmentation fault (core dumped)
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Message-id: 20220708151540.18136-22-richard.henderson@linaro.org
8
Thread 1 "qemu-system-aar" received signal SIGSEGV, Segmentation fault.
9
0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
10
2588 ret = ioctl(s->fd, type, arg);
11
(gdb) bt
12
#0 0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
13
#1 0x0000aaaaaae31568 in kvm_check_extension (s=0x0, extension=126) at accel/kvm/kvm-all.c:916
14
#2 0x0000aaaaaafce254 in kvm_arm_pmu_supported (cpu=0xaaaaac214ab0) at target/arm/kvm.c:213
15
#3 0x0000aaaaaafc0f94 in arm_set_pmu (obj=0xaaaaac214ab0, value=true, errp=0xffffffffe438) at target/arm/cpu.c:1111
16
#4 0x0000aaaaab5533ac in property_set_bool (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", opaque=0xaaaaac222730, errp=0xffffffffe438) at qom/object.c:2170
17
#5 0x0000aaaaab5512f0 in object_property_set (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1328
18
#6 0x0000aaaaab551e10 in object_property_parse (obj=0xaaaaac214ab0, string=0xaaaaac11b4c0 "on", name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1561
19
#7 0x0000aaaaab54ee8c in object_apply_global_props (obj=0xaaaaac214ab0, props=0xaaaaac018e20, errp=0xaaaaabd6fd88 <error_fatal>) at qom/object.c:407
20
#8 0x0000aaaaab1dd5a4 in qdev_prop_set_globals (dev=0xaaaaac214ab0) at hw/core/qdev-properties.c:1218
21
#9 0x0000aaaaab1d9fac in device_post_init (obj=0xaaaaac214ab0) at hw/core/qdev.c:1050
22
...
23
#15 0x0000aaaaab54f310 in object_initialize_with_type (obj=0xaaaaac214ab0, size=52208, type=0xaaaaabe237f0) at qom/object.c:512
24
#16 0x0000aaaaab54fa24 in object_new_with_type (type=0xaaaaabe237f0) at qom/object.c:687
25
#17 0x0000aaaaab54fa80 in object_new (typename=0xaaaaabe23970 "host-arm-cpu") at qom/object.c:702
26
#18 0x0000aaaaaaf04a74 in machvirt_init (machine=0xaaaaac0a8550) at hw/arm/virt.c:1770
27
#19 0x0000aaaaab1e8720 in machine_run_board_init (machine=0xaaaaac0a8550) at hw/core/machine.c:1138
28
#20 0x0000aaaaaaf95394 in qemu_init (argc=5, argv=0xffffffffea58, envp=0xffffffffea88) at softmmu/vl.c:4348
29
#21 0x0000aaaaaada3f74 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at softmmu/main.c:48
30
31
This is because in frame #2, cpu->kvm_state is still NULL
32
(the vCPU is not yet realized).
33
34
KVM has a hard requirement of all cores supporting the same
35
feature set. We only need to check if the accelerator supports
36
a feature, not each vCPU individually.
37
38
Fix by removing the 'CPUState *cpu' argument from the
39
kvm_arm_<FEATURE>_supported() functions.
40
41
Fixes: d70c996df23f ('Use CPUState::kvm_state in kvm_arm_pmu_supported')
42
Reported-by: Haibo Xu <haibo.xu@linaro.org>
43
Reviewed-by: Andrew Jones <drjones@redhat.com>
44
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
45
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
46
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
47
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
10
---
50
target/arm/kvm_arm.h | 21 +++++++++------------
11
target/arm/translate-a64.h | 3 +++
51
target/arm/cpu.c | 2 +-
12
target/arm/translate-sve.c | 48 ++++++++++++++++++++++++++++----------
52
target/arm/cpu64.c | 10 +++++-----
13
2 files changed, 39 insertions(+), 12 deletions(-)
53
target/arm/kvm.c | 4 ++--
54
target/arm/kvm64.c | 14 +++++---------
55
5 files changed, 22 insertions(+), 29 deletions(-)
56
14
57
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
15
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
58
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/kvm_arm.h
17
--- a/target/arm/translate-a64.h
60
+++ b/target/arm/kvm_arm.h
18
+++ b/target/arm/translate-a64.h
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj);
19
@@ -XXX,XX +XXX,XX @@ void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
62
20
uint32_t rm_ofs, int64_t shift,
63
/**
21
uint32_t opr_sz, uint32_t max_sz);
64
* kvm_arm_aarch32_supported:
22
65
- * @cs: CPUState
23
+void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);
66
*
24
+void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);
67
- * Returns: true if the KVM VCPU can enable AArch32 mode
25
+
68
+ * Returns: true if KVM can enable AArch32 mode
26
#endif /* TARGET_ARM_TRANSLATE_A64_H */
69
* and false otherwise.
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-sve.c
30
+++ b/target/arm/translate-sve.c
31
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
32
* The load should begin at the address Rn + IMM.
70
*/
33
*/
71
-bool kvm_arm_aarch32_supported(CPUState *cs);
34
72
+bool kvm_arm_aarch32_supported(void);
35
-static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
73
36
+void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
74
/**
37
+ int len, int rn, int imm)
75
* kvm_arm_pmu_supported:
76
- * @cs: CPUState
77
*
78
- * Returns: true if the KVM VCPU can enable its PMU
79
+ * Returns: true if KVM can enable the PMU
80
* and false otherwise.
81
*/
82
-bool kvm_arm_pmu_supported(CPUState *cs);
83
+bool kvm_arm_pmu_supported(void);
84
85
/**
86
* kvm_arm_sve_supported:
87
- * @cs: CPUState
88
*
89
- * Returns true if the KVM VCPU can enable SVE and false otherwise.
90
+ * Returns true if KVM can enable SVE and false otherwise.
91
*/
92
-bool kvm_arm_sve_supported(CPUState *cs);
93
+bool kvm_arm_sve_supported(void);
94
95
/**
96
* kvm_arm_get_max_vm_ipa_size:
97
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
98
99
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
100
101
-static inline bool kvm_arm_aarch32_supported(CPUState *cs)
102
+static inline bool kvm_arm_aarch32_supported(void)
103
{
38
{
104
return false;
39
int len_align = QEMU_ALIGN_DOWN(len, 8);
105
}
40
int len_remain = len % 8;
106
41
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
107
-static inline bool kvm_arm_pmu_supported(CPUState *cs)
42
t0 = tcg_temp_new_i64();
108
+static inline bool kvm_arm_pmu_supported(void)
43
for (i = 0; i < len_align; i += 8) {
109
{
44
tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ);
110
return false;
45
- tcg_gen_st_i64(t0, cpu_env, vofs + i);
111
}
46
+ tcg_gen_st_i64(t0, base, vofs + i);
112
47
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
113
-static inline bool kvm_arm_sve_supported(CPUState *cs)
114
+static inline bool kvm_arm_sve_supported(void)
115
{
116
return false;
117
}
118
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/cpu.c
121
+++ b/target/arm/cpu.c
122
@@ -XXX,XX +XXX,XX @@ static void arm_set_pmu(Object *obj, bool value, Error **errp)
123
ARMCPU *cpu = ARM_CPU(obj);
124
125
if (value) {
126
- if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
127
+ if (kvm_enabled() && !kvm_arm_pmu_supported()) {
128
error_setg(errp, "'pmu' feature not supported by KVM on this host");
129
return;
130
}
48
}
131
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
tcg_temp_free_i64(t0);
132
index XXXXXXX..XXXXXXX 100644
50
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
133
--- a/target/arm/cpu64.c
51
clean_addr = new_tmp_a64_local(s);
134
+++ b/target/arm/cpu64.c
52
tcg_gen_mov_i64(clean_addr, t0);
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
53
136
54
+ if (base != cpu_env) {
137
/* Collect the set of vector lengths supported by KVM. */
55
+ TCGv_ptr b = tcg_temp_local_new_ptr();
138
bitmap_zero(kvm_supported, ARM_MAX_VQ);
56
+ tcg_gen_mov_ptr(b, base);
139
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
57
+ base = b;
140
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
58
+ }
141
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
59
+
142
} else if (kvm_enabled()) {
60
gen_set_label(loop);
143
assert(!cpu_isar_feature(aa64_sve, cpu));
61
144
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
62
t0 = tcg_temp_new_i64();
145
return;
63
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
64
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
65
66
tp = tcg_temp_new_ptr();
67
- tcg_gen_add_ptr(tp, cpu_env, i);
68
+ tcg_gen_add_ptr(tp, base, i);
69
tcg_gen_addi_ptr(i, i, 8);
70
tcg_gen_st_i64(t0, tp, vofs);
71
tcg_temp_free_ptr(tp);
72
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
73
74
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
75
tcg_temp_free_ptr(i);
76
+
77
+ if (base != cpu_env) {
78
+ tcg_temp_free_ptr(base);
79
+ assert(len_remain == 0);
80
+ }
146
}
81
}
147
82
148
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
83
/*
149
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
84
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
150
error_setg(errp, "cannot set sve-max-vq");
85
default:
151
error_append_hint(errp, "SVE not supported by KVM on this host\n");
86
g_assert_not_reached();
152
return;
87
}
153
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
88
- tcg_gen_st_i64(t0, cpu_env, vofs + len_align);
154
return;
89
+ tcg_gen_st_i64(t0, base, vofs + len_align);
155
}
90
tcg_temp_free_i64(t0);
156
157
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
158
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
159
error_setg(errp, "cannot enable %s", name);
160
error_append_hint(errp, "SVE not supported by KVM on this host\n");
161
return;
162
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
163
return;
164
}
165
166
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
167
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
168
error_setg(errp, "'sve' feature not supported by KVM on this host");
169
return;
170
}
171
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
172
* uniform execution state like do_interrupt.
173
*/
174
if (value == false) {
175
- if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
176
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
177
error_setg(errp, "'aarch64' feature cannot be disabled "
178
"unless KVM is enabled and 32-bit EL1 "
179
"is supported");
180
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/arm/kvm.c
183
+++ b/target/arm/kvm.c
184
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj)
185
}
91
}
186
}
92
}
187
93
188
-bool kvm_arm_pmu_supported(CPUState *cpu)
94
/* Similarly for stores. */
189
+bool kvm_arm_pmu_supported(void)
95
-static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
96
+void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
97
+ int len, int rn, int imm)
190
{
98
{
191
- return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
99
int len_align = QEMU_ALIGN_DOWN(len, 8);
192
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
100
int len_remain = len % 8;
193
}
101
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
194
102
195
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
103
t0 = tcg_temp_new_i64();
196
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
104
for (i = 0; i < len_align; i += 8) {
197
index XXXXXXX..XXXXXXX 100644
105
- tcg_gen_ld_i64(t0, cpu_env, vofs + i);
198
--- a/target/arm/kvm64.c
106
+ tcg_gen_ld_i64(t0, base, vofs + i);
199
+++ b/target/arm/kvm64.c
107
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ);
200
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
108
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
109
}
110
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
111
clean_addr = new_tmp_a64_local(s);
112
tcg_gen_mov_i64(clean_addr, t0);
113
114
+ if (base != cpu_env) {
115
+ TCGv_ptr b = tcg_temp_local_new_ptr();
116
+ tcg_gen_mov_ptr(b, base);
117
+ base = b;
118
+ }
119
+
120
gen_set_label(loop);
121
122
t0 = tcg_temp_new_i64();
123
tp = tcg_temp_new_ptr();
124
- tcg_gen_add_ptr(tp, cpu_env, i);
125
+ tcg_gen_add_ptr(tp, base, i);
126
tcg_gen_ld_i64(t0, tp, vofs);
127
tcg_gen_addi_ptr(i, i, 8);
128
tcg_temp_free_ptr(tp);
129
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
130
131
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
132
tcg_temp_free_ptr(i);
133
+
134
+ if (base != cpu_env) {
135
+ tcg_temp_free_ptr(base);
136
+ assert(len_remain == 0);
137
+ }
138
}
139
140
/* Predicate register stores can be any multiple of 2. */
141
if (len_remain) {
142
t0 = tcg_temp_new_i64();
143
- tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
144
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
145
146
switch (len_remain) {
147
case 2:
148
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_zri(DisasContext *s, arg_rri *a)
149
if (sve_access_check(s)) {
150
int size = vec_full_reg_size(s);
151
int off = vec_full_reg_offset(s, a->rd);
152
- do_ldr(s, off, size, a->rn, a->imm * size);
153
+ gen_sve_ldr(s, cpu_env, off, size, a->rn, a->imm * size);
154
}
201
return true;
155
return true;
202
}
156
}
203
157
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a)
204
-bool kvm_arm_aarch32_supported(CPUState *cpu)
158
if (sve_access_check(s)) {
205
+bool kvm_arm_aarch32_supported(void)
159
int size = pred_full_reg_size(s);
206
{
160
int off = pred_full_reg_offset(s, a->rd);
207
- KVMState *s = KVM_STATE(current_accel());
161
- do_ldr(s, off, size, a->rn, a->imm * size);
208
-
162
+ gen_sve_ldr(s, cpu_env, off, size, a->rn, a->imm * size);
209
- return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
163
}
210
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
164
return true;
211
}
165
}
212
166
@@ -XXX,XX +XXX,XX @@ static bool trans_STR_zri(DisasContext *s, arg_rri *a)
213
-bool kvm_arm_sve_supported(CPUState *cpu)
167
if (sve_access_check(s)) {
214
+bool kvm_arm_sve_supported(void)
168
int size = vec_full_reg_size(s);
215
{
169
int off = vec_full_reg_offset(s, a->rd);
216
- KVMState *s = KVM_STATE(current_accel());
170
- do_str(s, off, size, a->rn, a->imm * size);
217
-
171
+ gen_sve_str(s, cpu_env, off, size, a->rn, a->imm * size);
218
- return kvm_check_extension(s, KVM_CAP_ARM_SVE);
172
}
219
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
173
return true;
220
}
174
}
221
175
@@ -XXX,XX +XXX,XX @@ static bool trans_STR_pri(DisasContext *s, arg_rri *a)
222
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
176
if (sve_access_check(s)) {
223
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
177
int size = pred_full_reg_size(s);
224
env->features &= ~(1ULL << ARM_FEATURE_PMU);
178
int off = pred_full_reg_offset(s, a->rd);
179
- do_str(s, off, size, a->rn, a->imm * size);
180
+ gen_sve_str(s, cpu_env, off, size, a->rn, a->imm * size);
225
}
181
}
226
if (cpu_isar_feature(aa64_sve, cpu)) {
182
return true;
227
- assert(kvm_arm_sve_supported(cs));
183
}
228
+ assert(kvm_arm_sve_supported());
229
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
230
}
231
232
--
184
--
233
2.20.1
185
2.25.1
234
235
diff view generated by jsdifflib
1
Convert the Neon insns in the 2-reg-misc group which are
1
From: Richard Henderson <richard.henderson@linaro.org>
2
VCVT between f32 and f16 to decodetree.
3
2
3
We can reuse the SVE functions for LDR and STR, passing in the
4
base of the ZA vector and a zero offset.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-23-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-7-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 3 ++
11
target/arm/sme.decode | 7 +++++++
9
target/arm/translate-neon.inc.c | 96 +++++++++++++++++++++++++++++++++
12
target/arm/translate-sme.c | 24 ++++++++++++++++++++++++
10
target/arm/translate.c | 65 ++--------------------
13
2 files changed, 31 insertions(+)
11
3 files changed, 102 insertions(+), 62 deletions(-)
12
14
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/sme.decode
16
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/sme.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
@@ -XXX,XX +XXX,XX @@ LDST1 1110000 0 esz:2 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
18
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
20
&ldst rs=%mova_rs
19
21
LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
20
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
22
&ldst esz=4 rs=%mova_rs
21
+
23
+
22
+ VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
24
+&ldstr rv rn imm
23
+ VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
25
+@ldstr ....... ... . ...... .. ... rn:5 . imm:4 \
24
]
26
+ &ldstr rv=%mova_rs
25
27
+
26
# Subgroup for size != 0b11
28
+LDR 1110000 100 0 000000 .. 000 ..... 0 .... @ldstr
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
+STR 1110000 100 1 000000 .. 000 ..... 0 .... @ldstr
30
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
28
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
32
--- a/target/arm/translate-sme.c
30
+++ b/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-sme.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
32
tcg_temp_free_i32(rm1);
35
tcg_temp_free_i64(addr);
33
return true;
36
return true;
34
}
37
}
35
+
38
+
36
+static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
39
+typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int);
40
+
41
+static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
37
+{
42
+{
38
+ TCGv_ptr fpst;
43
+ int svl = streaming_vec_reg_size(s);
39
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
44
+ int imm = a->imm;
45
+ TCGv_ptr base;
40
+
46
+
41
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
47
+ if (!sme_za_enabled_check(s)) {
42
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
43
+ return false;
44
+ }
45
+
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
48
+ ((a->vd | a->vm) & 0x10)) {
49
+ return false;
50
+ }
51
+
52
+ if ((a->vm & 1) || (a->size != 1)) {
53
+ return false;
54
+ }
55
+
56
+ if (!vfp_access_check(s)) {
57
+ return true;
48
+ return true;
58
+ }
49
+ }
59
+
50
+
60
+ fpst = get_fpstatus_ptr(true);
51
+ /* ZA[n] equates to ZA0H.B[n]. */
61
+ ahp = get_ahp_flag();
52
+ base = get_tile_rowcol(s, MO_8, a->rv, imm, false);
62
+ tmp = neon_load_reg(a->vm, 0);
63
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
64
+ tmp2 = neon_load_reg(a->vm, 1);
65
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
66
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
67
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
68
+ tcg_temp_free_i32(tmp);
69
+ tmp = neon_load_reg(a->vm, 2);
70
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
71
+ tmp3 = neon_load_reg(a->vm, 3);
72
+ neon_store_reg(a->vd, 0, tmp2);
73
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
74
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
75
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
76
+ neon_store_reg(a->vd, 1, tmp3);
77
+ tcg_temp_free_i32(tmp);
78
+ tcg_temp_free_i32(ahp);
79
+ tcg_temp_free_ptr(fpst);
80
+
53
+
54
+ fn(s, base, 0, svl, a->rn, imm * svl);
55
+
56
+ tcg_temp_free_ptr(base);
81
+ return true;
57
+ return true;
82
+}
58
+}
83
+
59
+
84
+static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
60
+TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr)
85
+{
61
+TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str)
86
+ TCGv_ptr fpst;
87
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
88
+
89
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
90
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
91
+ return false;
92
+ }
93
+
94
+ /* UNDEF accesses to D16-D31 if they don't exist. */
95
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
96
+ ((a->vd | a->vm) & 0x10)) {
97
+ return false;
98
+ }
99
+
100
+ if ((a->vd & 1) || (a->size != 1)) {
101
+ return false;
102
+ }
103
+
104
+ if (!vfp_access_check(s)) {
105
+ return true;
106
+ }
107
+
108
+ fpst = get_fpstatus_ptr(true);
109
+ ahp = get_ahp_flag();
110
+ tmp3 = tcg_temp_new_i32();
111
+ tmp = neon_load_reg(a->vm, 0);
112
+ tmp2 = neon_load_reg(a->vm, 1);
113
+ tcg_gen_ext16u_i32(tmp3, tmp);
114
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
115
+ neon_store_reg(a->vd, 0, tmp3);
116
+ tcg_gen_shri_i32(tmp, tmp, 16);
117
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
118
+ neon_store_reg(a->vd, 1, tmp);
119
+ tmp3 = tcg_temp_new_i32();
120
+ tcg_gen_ext16u_i32(tmp3, tmp2);
121
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
122
+ neon_store_reg(a->vd, 2, tmp3);
123
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
124
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
125
+ neon_store_reg(a->vd, 3, tmp2);
126
+ tcg_temp_free_i32(ahp);
127
+ tcg_temp_free_ptr(fpst);
128
+
129
+ return true;
130
+}
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
136
int pass;
137
int u;
138
int vec_size;
139
- TCGv_i32 tmp, tmp2, tmp3;
140
+ TCGv_i32 tmp, tmp2;
141
142
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
143
return 1;
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
145
case NEON_2RM_VZIP:
146
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
147
case NEON_2RM_VSHLL:
148
+ case NEON_2RM_VCVT_F16_F32:
149
+ case NEON_2RM_VCVT_F32_F16:
150
/* handled by decodetree */
151
return 1;
152
case NEON_2RM_VTRN:
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
154
goto elementwise;
155
}
156
break;
157
- case NEON_2RM_VCVT_F16_F32:
158
- {
159
- TCGv_ptr fpst;
160
- TCGv_i32 ahp;
161
-
162
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
163
- q || (rm & 1)) {
164
- return 1;
165
- }
166
- fpst = get_fpstatus_ptr(true);
167
- ahp = get_ahp_flag();
168
- tmp = neon_load_reg(rm, 0);
169
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
170
- tmp2 = neon_load_reg(rm, 1);
171
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
172
- tcg_gen_shli_i32(tmp2, tmp2, 16);
173
- tcg_gen_or_i32(tmp2, tmp2, tmp);
174
- tcg_temp_free_i32(tmp);
175
- tmp = neon_load_reg(rm, 2);
176
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
177
- tmp3 = neon_load_reg(rm, 3);
178
- neon_store_reg(rd, 0, tmp2);
179
- gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
180
- tcg_gen_shli_i32(tmp3, tmp3, 16);
181
- tcg_gen_or_i32(tmp3, tmp3, tmp);
182
- neon_store_reg(rd, 1, tmp3);
183
- tcg_temp_free_i32(tmp);
184
- tcg_temp_free_i32(ahp);
185
- tcg_temp_free_ptr(fpst);
186
- break;
187
- }
188
- case NEON_2RM_VCVT_F32_F16:
189
- {
190
- TCGv_ptr fpst;
191
- TCGv_i32 ahp;
192
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
193
- q || (rd & 1)) {
194
- return 1;
195
- }
196
- fpst = get_fpstatus_ptr(true);
197
- ahp = get_ahp_flag();
198
- tmp3 = tcg_temp_new_i32();
199
- tmp = neon_load_reg(rm, 0);
200
- tmp2 = neon_load_reg(rm, 1);
201
- tcg_gen_ext16u_i32(tmp3, tmp);
202
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
203
- neon_store_reg(rd, 0, tmp3);
204
- tcg_gen_shri_i32(tmp, tmp, 16);
205
- gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
206
- neon_store_reg(rd, 1, tmp);
207
- tmp3 = tcg_temp_new_i32();
208
- tcg_gen_ext16u_i32(tmp3, tmp2);
209
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
210
- neon_store_reg(rd, 2, tmp3);
211
- tcg_gen_shri_i32(tmp2, tmp2, 16);
212
- gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
213
- neon_store_reg(rd, 3, tmp2);
214
- tcg_temp_free_i32(ahp);
215
- tcg_temp_free_ptr(fpst);
216
- break;
217
- }
218
case NEON_2RM_AESE: case NEON_2RM_AESMC:
219
if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
220
return 1;
221
--
62
--
222
2.20.1
63
2.25.1
223
224
diff view generated by jsdifflib
1
The functions neon_element_offset(), neon_load_element(),
1
From: Richard Henderson <richard.henderson@linaro.org>
2
neon_load_element64(), neon_store_element() and
3
neon_store_element64() are used only in the translate-neon.inc.c
4
file, so move their definitions there.
5
2
6
Since the .inc.c file is #included in translate.c this doesn't make
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
much difference currently, but it's a more logical place to put the
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
functions and it might be helpful if we ever decide to try to make
5
Message-id: 20220708151540.18136-24-richard.henderson@linaro.org
9
the .inc.c files genuinely separate compilation units.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sme.h | 5 +++
9
target/arm/sme.decode | 11 +++++
10
target/arm/sme_helper.c | 90 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sme.c | 31 +++++++++++++
12
4 files changed, 137 insertions(+)
10
13
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200616170844.13318-22-peter.maydell@linaro.org
14
---
15
target/arm/translate-neon.inc.c | 101 ++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 101 --------------------------------
17
2 files changed, 101 insertions(+), 101 deletions(-)
18
19
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-neon.inc.c
16
--- a/target/arm/helper-sme.h
22
+++ b/target/arm/translate-neon.inc.c
17
+++ b/target/arm/helper-sme.h
23
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_st1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i
24
#include "decode-neon-ls.inc.c"
19
DEF_HELPER_FLAGS_5(sme_st1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
25
#include "decode-neon-shared.inc.c"
20
DEF_HELPER_FLAGS_5(sme_st1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
26
21
DEF_HELPER_FLAGS_5(sme_st1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
27
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
22
+
28
+ * where 0 is the least significant end of the register.
23
+DEF_HELPER_FLAGS_5(sme_addha_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
29
+ */
24
+DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
30
+static inline long
25
+DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
+neon_element_offset(int reg, int element, MemOp size)
26
+DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/sme.decode
30
+++ b/target/arm/sme.decode
31
@@ -XXX,XX +XXX,XX @@ LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
32
33
LDR 1110000 100 0 000000 .. 000 ..... 0 .... @ldstr
34
STR 1110000 100 1 000000 .. 000 ..... 0 .... @ldstr
35
+
36
+### SME Add Vector to Array
37
+
38
+&adda zad zn pm pn
39
+@adda_32 ........ .. ..... . pm:3 pn:3 zn:5 ... zad:2 &adda
40
+@adda_64 ........ .. ..... . pm:3 pn:3 zn:5 .. zad:3 &adda
41
+
42
+ADDHA_s 11000000 10 01000 0 ... ... ..... 000 .. @adda_32
43
+ADDVA_s 11000000 10 01000 1 ... ... ..... 000 .. @adda_32
44
+ADDHA_d 11000000 11 01000 0 ... ... ..... 00 ... @adda_64
45
+ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
46
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sme_helper.c
49
+++ b/target/arm/sme_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_ST(q, _be, MO_128)
51
DO_ST(q, _le, MO_128)
52
53
#undef DO_ST
54
+
55
+void HELPER(sme_addha_s)(void *vzda, void *vzn, void *vpn,
56
+ void *vpm, uint32_t desc)
32
+{
57
+{
33
+ int element_size = 1 << size;
58
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
34
+ int ofs = element * element_size;
59
+ uint64_t *pn = vpn, *pm = vpm;
35
+#ifdef HOST_WORDS_BIGENDIAN
60
+ uint32_t *zda = vzda, *zn = vzn;
36
+ /* Calculate the offset assuming fully little-endian,
37
+ * then XOR to account for the order of the 8-byte units.
38
+ */
39
+ if (element_size < 8) {
40
+ ofs ^= 8 - element_size;
41
+ }
42
+#endif
43
+ return neon_reg_offset(reg, 0) + ofs;
44
+}
45
+
61
+
46
+static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
62
+ for (row = 0; row < oprsz; ) {
47
+{
63
+ uint64_t pa = pn[row >> 4];
48
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
64
+ do {
49
+
65
+ if (pa & 1) {
50
+ switch (mop) {
66
+ for (col = 0; col < oprsz; ) {
51
+ case MO_UB:
67
+ uint64_t pb = pm[col >> 4];
52
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
68
+ do {
53
+ break;
69
+ if (pb & 1) {
54
+ case MO_UW:
70
+ zda[tile_vslice_index(row) + H4(col)] += zn[H4(col)];
55
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
71
+ }
56
+ break;
72
+ pb >>= 4;
57
+ case MO_UL:
73
+ } while (++col & 15);
58
+ tcg_gen_ld_i32(var, cpu_env, offset);
74
+ }
59
+ break;
75
+ }
60
+ default:
76
+ pa >>= 4;
61
+ g_assert_not_reached();
77
+ } while (++row & 15);
62
+ }
78
+ }
63
+}
79
+}
64
+
80
+
65
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
81
+void HELPER(sme_addha_d)(void *vzda, void *vzn, void *vpn,
82
+ void *vpm, uint32_t desc)
66
+{
83
+{
67
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
84
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
85
+ uint8_t *pn = vpn, *pm = vpm;
86
+ uint64_t *zda = vzda, *zn = vzn;
68
+
87
+
69
+ switch (mop) {
88
+ for (row = 0; row < oprsz; ++row) {
70
+ case MO_UB:
89
+ if (pn[H1(row)] & 1) {
71
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
90
+ for (col = 0; col < oprsz; ++col) {
72
+ break;
91
+ if (pm[H1(col)] & 1) {
73
+ case MO_UW:
92
+ zda[tile_vslice_index(row) + col] += zn[col];
74
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
93
+ }
75
+ break;
94
+ }
76
+ case MO_UL:
95
+ }
77
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
78
+ break;
79
+ case MO_Q:
80
+ tcg_gen_ld_i64(var, cpu_env, offset);
81
+ break;
82
+ default:
83
+ g_assert_not_reached();
84
+ }
96
+ }
85
+}
97
+}
86
+
98
+
87
+static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
99
+void HELPER(sme_addva_s)(void *vzda, void *vzn, void *vpn,
100
+ void *vpm, uint32_t desc)
88
+{
101
+{
89
+ long offset = neon_element_offset(reg, ele, size);
102
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
103
+ uint64_t *pn = vpn, *pm = vpm;
104
+ uint32_t *zda = vzda, *zn = vzn;
90
+
105
+
91
+ switch (size) {
106
+ for (row = 0; row < oprsz; ) {
92
+ case MO_8:
107
+ uint64_t pa = pn[row >> 4];
93
+ tcg_gen_st8_i32(var, cpu_env, offset);
108
+ do {
94
+ break;
109
+ if (pa & 1) {
95
+ case MO_16:
110
+ uint32_t zn_row = zn[H4(row)];
96
+ tcg_gen_st16_i32(var, cpu_env, offset);
111
+ for (col = 0; col < oprsz; ) {
97
+ break;
112
+ uint64_t pb = pm[col >> 4];
98
+ case MO_32:
113
+ do {
99
+ tcg_gen_st_i32(var, cpu_env, offset);
114
+ if (pb & 1) {
100
+ break;
115
+ zda[tile_vslice_index(row) + H4(col)] += zn_row;
101
+ default:
116
+ }
102
+ g_assert_not_reached();
117
+ pb >>= 4;
118
+ } while (++col & 15);
119
+ }
120
+ }
121
+ pa >>= 4;
122
+ } while (++row & 15);
103
+ }
123
+ }
104
+}
124
+}
105
+
125
+
106
+static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
126
+void HELPER(sme_addva_d)(void *vzda, void *vzn, void *vpn,
127
+ void *vpm, uint32_t desc)
107
+{
128
+{
108
+ long offset = neon_element_offset(reg, ele, size);
129
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
130
+ uint8_t *pn = vpn, *pm = vpm;
131
+ uint64_t *zda = vzda, *zn = vzn;
109
+
132
+
110
+ switch (size) {
133
+ for (row = 0; row < oprsz; ++row) {
111
+ case MO_8:
134
+ if (pn[H1(row)] & 1) {
112
+ tcg_gen_st8_i64(var, cpu_env, offset);
135
+ uint64_t zn_row = zn[row];
113
+ break;
136
+ for (col = 0; col < oprsz; ++col) {
114
+ case MO_16:
137
+ if (pm[H1(col)] & 1) {
115
+ tcg_gen_st16_i64(var, cpu_env, offset);
138
+ zda[tile_vslice_index(row) + col] += zn_row;
116
+ break;
139
+ }
117
+ case MO_32:
140
+ }
118
+ tcg_gen_st32_i64(var, cpu_env, offset);
141
+ }
119
+ break;
120
+ case MO_64:
121
+ tcg_gen_st_i64(var, cpu_env, offset);
122
+ break;
123
+ default:
124
+ g_assert_not_reached();
125
+ }
142
+ }
126
+}
143
+}
144
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-sme.c
147
+++ b/target/arm/translate-sme.c
148
@@ -XXX,XX +XXX,XX @@ static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
149
150
TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr)
151
TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str)
127
+
152
+
128
static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
153
+static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz,
129
{
154
+ gen_helper_gvec_4 *fn)
130
int opr_sz;
155
+{
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
+ int svl = streaming_vec_reg_size(s);
132
index XXXXXXX..XXXXXXX 100644
157
+ uint32_t desc = simd_desc(svl, svl, 0);
133
--- a/target/arm/translate.c
158
+ TCGv_ptr za, zn, pn, pm;
134
+++ b/target/arm/translate.c
159
+
135
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
160
+ if (!sme_smza_enabled_check(s)) {
136
return vfp_reg_offset(0, sreg);
161
+ return true;
137
}
162
+ }
138
163
+
139
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
164
+ /* Sum XZR+zad to find ZAd. */
140
- * where 0 is the least significant end of the register.
165
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
141
- */
166
+ zn = vec_full_reg_ptr(s, a->zn);
142
-static inline long
167
+ pn = pred_full_reg_ptr(s, a->pn);
143
-neon_element_offset(int reg, int element, MemOp size)
168
+ pm = pred_full_reg_ptr(s, a->pm);
144
-{
169
+
145
- int element_size = 1 << size;
170
+ fn(za, zn, pn, pm, tcg_constant_i32(desc));
146
- int ofs = element * element_size;
171
+
147
-#ifdef HOST_WORDS_BIGENDIAN
172
+ tcg_temp_free_ptr(za);
148
- /* Calculate the offset assuming fully little-endian,
173
+ tcg_temp_free_ptr(zn);
149
- * then XOR to account for the order of the 8-byte units.
174
+ tcg_temp_free_ptr(pn);
150
- */
175
+ tcg_temp_free_ptr(pm);
151
- if (element_size < 8) {
176
+ return true;
152
- ofs ^= 8 - element_size;
177
+}
153
- }
178
+
154
-#endif
179
+TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addha_s)
155
- return neon_reg_offset(reg, 0) + ofs;
180
+TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
156
-}
181
+TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
157
-
182
+TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
158
static TCGv_i32 neon_load_reg(int reg, int pass)
159
{
160
TCGv_i32 tmp = tcg_temp_new_i32();
161
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
162
return tmp;
163
}
164
165
-static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
166
-{
167
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
168
-
169
- switch (mop) {
170
- case MO_UB:
171
- tcg_gen_ld8u_i32(var, cpu_env, offset);
172
- break;
173
- case MO_UW:
174
- tcg_gen_ld16u_i32(var, cpu_env, offset);
175
- break;
176
- case MO_UL:
177
- tcg_gen_ld_i32(var, cpu_env, offset);
178
- break;
179
- default:
180
- g_assert_not_reached();
181
- }
182
-}
183
-
184
-static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
185
-{
186
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
187
-
188
- switch (mop) {
189
- case MO_UB:
190
- tcg_gen_ld8u_i64(var, cpu_env, offset);
191
- break;
192
- case MO_UW:
193
- tcg_gen_ld16u_i64(var, cpu_env, offset);
194
- break;
195
- case MO_UL:
196
- tcg_gen_ld32u_i64(var, cpu_env, offset);
197
- break;
198
- case MO_Q:
199
- tcg_gen_ld_i64(var, cpu_env, offset);
200
- break;
201
- default:
202
- g_assert_not_reached();
203
- }
204
-}
205
-
206
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
207
{
208
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
209
tcg_temp_free_i32(var);
210
}
211
212
-static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
213
-{
214
- long offset = neon_element_offset(reg, ele, size);
215
-
216
- switch (size) {
217
- case MO_8:
218
- tcg_gen_st8_i32(var, cpu_env, offset);
219
- break;
220
- case MO_16:
221
- tcg_gen_st16_i32(var, cpu_env, offset);
222
- break;
223
- case MO_32:
224
- tcg_gen_st_i32(var, cpu_env, offset);
225
- break;
226
- default:
227
- g_assert_not_reached();
228
- }
229
-}
230
-
231
-static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
232
-{
233
- long offset = neon_element_offset(reg, ele, size);
234
-
235
- switch (size) {
236
- case MO_8:
237
- tcg_gen_st8_i64(var, cpu_env, offset);
238
- break;
239
- case MO_16:
240
- tcg_gen_st16_i64(var, cpu_env, offset);
241
- break;
242
- case MO_32:
243
- tcg_gen_st32_i64(var, cpu_env, offset);
244
- break;
245
- case MO_64:
246
- tcg_gen_st_i64(var, cpu_env, offset);
247
- break;
248
- default:
249
- g_assert_not_reached();
250
- }
251
-}
252
-
253
static inline void neon_load_reg64(TCGv_i64 var, int reg)
254
{
255
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
256
--
183
--
257
2.20.1
184
2.25.1
258
259
diff view generated by jsdifflib
1
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
1
From: Richard Henderson <richard.henderson@linaro.org>
2
group to decodetree.
3
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20220708151540.18136-25-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200616170844.13318-5-peter.maydell@linaro.org
7
---
7
---
8
target/arm/neon-dp.decode | 9 ++++
8
target/arm/helper-sme.h | 5 +++
9
target/arm/translate-neon.inc.c | 59 ++++++++++++++++++++++++
9
target/arm/sme.decode | 9 +++++
10
target/arm/translate.c | 81 +--------------------------------
10
target/arm/sme_helper.c | 69 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 70 insertions(+), 79 deletions(-)
11
target/arm/translate-sme.c | 32 ++++++++++++++++++
12
4 files changed, 115 insertions(+)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/target/arm/helper-sme.h
16
+++ b/target/arm/neon-dp.decode
17
+++ b/target/arm/helper-sme.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_addha_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
18
19
DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
20
DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
&2misc vm=%vm_dp vd=%vd_dp
21
DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
+ @2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
22
+ &2misc vm=%vm_dp vd=%vd_dp q=0
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
25
26
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
27
28
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
29
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
30
+
22
+
31
+ VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
23
+DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
32
+ # VQMOVUN: unsigned result (source is always signed)
24
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
33
+ VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
25
+DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
34
+ # VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
26
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
35
+ VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
36
+ VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
37
]
38
39
# Subgroup for size != 0b11
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.inc.c
29
--- a/target/arm/sme.decode
43
+++ b/target/arm/translate-neon.inc.c
30
+++ b/target/arm/sme.decode
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
31
@@ -XXX,XX +XXX,XX @@ ADDHA_s 11000000 10 01000 0 ... ... ..... 000 .. @adda_32
45
};
32
ADDVA_s 11000000 10 01000 1 ... ... ..... 000 .. @adda_32
46
return do_zip_uzp(s, a, fn[a->q][a->size]);
33
ADDHA_d 11000000 11 01000 0 ... ... ..... 00 ... @adda_64
34
ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
35
+
36
+### SME Outer Product
37
+
38
+&op zad zn zm pm pn sub:bool
39
+@op_32 ........ ... zm:5 pm:3 pn:3 zn:5 sub:1 .. zad:2 &op
40
+@op_64 ........ ... zm:5 pm:3 pn:3 zn:5 sub:1 . zad:3 &op
41
+
42
+FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
43
+FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
44
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/sme_helper.c
47
+++ b/target/arm/sme_helper.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "exec/cpu_ldst.h"
50
#include "exec/exec-all.h"
51
#include "qemu/int128.h"
52
+#include "fpu/softfloat.h"
53
#include "vec_internal.h"
54
#include "sve_ldst_internal.h"
55
56
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_addva_d)(void *vzda, void *vzn, void *vpn,
57
}
58
}
47
}
59
}
48
+
60
+
49
+static bool do_vmovn(DisasContext *s, arg_2misc *a,
61
+void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn,
50
+ NeonGenNarrowEnvFn *narrowfn)
62
+ void *vpm, void *vst, uint32_t desc)
51
+{
63
+{
52
+ TCGv_i64 rm;
64
+ intptr_t row, col, oprsz = simd_maxsz(desc);
53
+ TCGv_i32 rd0, rd1;
65
+ uint32_t neg = simd_data(desc) << 31;
66
+ uint16_t *pn = vpn, *pm = vpm;
67
+ float_status fpst;
54
+
68
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
69
+ /*
56
+ return false;
70
+ * Make a copy of float_status because this operation does not
71
+ * update the cumulative fp exception status. It also produces
72
+ * default nans.
73
+ */
74
+ fpst = *(float_status *)vst;
75
+ set_default_nan_mode(true, &fpst);
76
+
77
+ for (row = 0; row < oprsz; ) {
78
+ uint16_t pa = pn[H2(row >> 4)];
79
+ do {
80
+ if (pa & 1) {
81
+ void *vza_row = vza + tile_vslice_offset(row);
82
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row)) ^ neg;
83
+
84
+ for (col = 0; col < oprsz; ) {
85
+ uint16_t pb = pm[H2(col >> 4)];
86
+ do {
87
+ if (pb & 1) {
88
+ uint32_t *a = vza_row + H1_4(col);
89
+ uint32_t *m = vzm + H1_4(col);
90
+ *a = float32_muladd(n, *m, *a, 0, vst);
91
+ }
92
+ col += 4;
93
+ pb >>= 4;
94
+ } while (col & 15);
95
+ }
96
+ }
97
+ row += 4;
98
+ pa >>= 4;
99
+ } while (row & 15);
57
+ }
100
+ }
101
+}
58
+
102
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
103
+void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, void *vpn,
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
104
+ void *vpm, void *vst, uint32_t desc)
61
+ ((a->vd | a->vm) & 0x10)) {
105
+{
62
+ return false;
106
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
107
+ uint64_t neg = (uint64_t)simd_data(desc) << 63;
108
+ uint64_t *za = vza, *zn = vzn, *zm = vzm;
109
+ uint8_t *pn = vpn, *pm = vpm;
110
+ float_status fpst = *(float_status *)vst;
111
+
112
+ set_default_nan_mode(true, &fpst);
113
+
114
+ for (row = 0; row < oprsz; ++row) {
115
+ if (pn[H1(row)] & 1) {
116
+ uint64_t *za_row = &za[tile_vslice_index(row)];
117
+ uint64_t n = zn[row] ^ neg;
118
+
119
+ for (col = 0; col < oprsz; ++col) {
120
+ if (pm[H1(col)] & 1) {
121
+ uint64_t *a = &za_row[col];
122
+ *a = float64_muladd(n, zm[col], *a, 0, &fpst);
123
+ }
124
+ }
125
+ }
63
+ }
126
+ }
127
+}
128
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate-sme.c
131
+++ b/target/arm/translate-sme.c
132
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addha_s)
133
TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
134
TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
135
TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
64
+
136
+
65
+ if (a->vm & 1) {
137
+static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
66
+ return false;
138
+ gen_helper_gvec_5_ptr *fn)
67
+ }
139
+{
140
+ int svl = streaming_vec_reg_size(s);
141
+ uint32_t desc = simd_desc(svl, svl, a->sub);
142
+ TCGv_ptr za, zn, zm, pn, pm, fpst;
68
+
143
+
69
+ if (!narrowfn) {
144
+ if (!sme_smza_enabled_check(s)) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
145
+ return true;
75
+ }
146
+ }
76
+
147
+
77
+ rm = tcg_temp_new_i64();
148
+ /* Sum XZR+zad to find ZAd. */
78
+ rd0 = tcg_temp_new_i32();
149
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
79
+ rd1 = tcg_temp_new_i32();
150
+ zn = vec_full_reg_ptr(s, a->zn);
151
+ zm = vec_full_reg_ptr(s, a->zm);
152
+ pn = pred_full_reg_ptr(s, a->pn);
153
+ pm = pred_full_reg_ptr(s, a->pm);
154
+ fpst = fpstatus_ptr(FPST_FPCR);
80
+
155
+
81
+ neon_load_reg64(rm, a->vm);
156
+ fn(za, zn, zm, pn, pm, fpst, tcg_constant_i32(desc));
82
+ narrowfn(rd0, cpu_env, rm);
157
+
83
+ neon_load_reg64(rm, a->vm + 1);
158
+ tcg_temp_free_ptr(za);
84
+ narrowfn(rd1, cpu_env, rm);
159
+ tcg_temp_free_ptr(zn);
85
+ neon_store_reg(a->vd, 0, rd0);
160
+ tcg_temp_free_ptr(pn);
86
+ neon_store_reg(a->vd, 1, rd1);
161
+ tcg_temp_free_ptr(pm);
87
+ tcg_temp_free_i64(rm);
162
+ tcg_temp_free_ptr(fpst);
88
+ return true;
163
+ return true;
89
+}
164
+}
90
+
165
+
91
+#define DO_VMOVN(INSN, FUNC) \
166
+TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
92
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
167
+TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
93
+ { \
94
+ static NeonGenNarrowEnvFn * const narrowfn[] = { \
95
+ FUNC##8, \
96
+ FUNC##16, \
97
+ FUNC##32, \
98
+ NULL, \
99
+ }; \
100
+ return do_vmovn(s, a, narrowfn[a->size]); \
101
+ }
102
+
103
+DO_VMOVN(VMOVN, gen_neon_narrow_u)
104
+DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
105
+DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
106
+DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
112
tcg_temp_free_i32(rd);
113
}
114
115
-static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
116
-{
117
- switch (size) {
118
- case 0: gen_helper_neon_narrow_u8(dest, src); break;
119
- case 1: gen_helper_neon_narrow_u16(dest, src); break;
120
- case 2: tcg_gen_extrl_i64_i32(dest, src); break;
121
- default: abort();
122
- }
123
-}
124
-
125
-static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
126
-{
127
- switch (size) {
128
- case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
129
- case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
130
- case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
131
- default: abort();
132
- }
133
-}
134
-
135
-static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
136
-{
137
- switch (size) {
138
- case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
139
- case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
140
- case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
141
- default: abort();
142
- }
143
-}
144
-
145
-static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
146
-{
147
- switch (size) {
148
- case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
149
- case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
150
- case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
151
- default: abort();
152
- }
153
-}
154
-
155
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
156
{
157
if (u) {
158
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
159
tcg_temp_free_i32(src);
160
}
161
162
-static void gen_neon_narrow_op(int op, int u, int size,
163
- TCGv_i32 dest, TCGv_i64 src)
164
-{
165
- if (op) {
166
- if (u) {
167
- gen_neon_unarrow_sats(size, dest, src);
168
- } else {
169
- gen_neon_narrow(size, dest, src);
170
- }
171
- } else {
172
- if (u) {
173
- gen_neon_narrow_satu(size, dest, src);
174
- } else {
175
- gen_neon_narrow_sats(size, dest, src);
176
- }
177
- }
178
-}
179
-
180
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
181
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
182
* table A7-13.
183
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
184
!arm_dc_feature(s, ARM_FEATURE_V8)) {
185
return 1;
186
}
187
- if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
188
- q && ((rm | rd) & 1)) {
189
+ if (q && ((rm | rd) & 1)) {
190
return 1;
191
}
192
switch (op) {
193
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
194
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
195
case NEON_2RM_VUZP:
196
case NEON_2RM_VZIP:
197
+ case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
198
/* handled by decodetree */
199
return 1;
200
case NEON_2RM_VTRN:
201
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
202
goto elementwise;
203
}
204
break;
205
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
206
- /* also VQMOVUN; op field and mnemonics don't line up */
207
- if (rm & 1) {
208
- return 1;
209
- }
210
- tmp2 = NULL;
211
- for (pass = 0; pass < 2; pass++) {
212
- neon_load_reg64(cpu_V0, rm + pass);
213
- tmp = tcg_temp_new_i32();
214
- gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
215
- tmp, cpu_V0);
216
- if (pass == 0) {
217
- tmp2 = tmp;
218
- } else {
219
- neon_store_reg(rd, 0, tmp2);
220
- neon_store_reg(rd, 1, tmp);
221
- }
222
- }
223
- break;
224
case NEON_2RM_VSHLL:
225
if (q || (rd & 1)) {
226
return 1;
227
--
168
--
228
2.20.1
169
2.25.1
229
230
diff view generated by jsdifflib
1
Convert the Neon VZIP and VUZP insns in the 2-reg-misc group to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20220708151540.18136-26-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200616170844.13318-4-peter.maydell@linaro.org
7
---
7
---
8
target/arm/neon-dp.decode | 3 ++
8
target/arm/helper-sme.h | 2 ++
9
target/arm/translate-neon.inc.c | 74 ++++++++++++++++++++++++++
9
target/arm/sme.decode | 2 ++
10
target/arm/translate.c | 92 +--------------------------------
10
target/arm/sme_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 79 insertions(+), 90 deletions(-)
11
target/arm/translate-sme.c | 30 ++++++++++++++++++++
12
4 files changed, 90 insertions(+)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/target/arm/helper-sme.h
16
+++ b/target/arm/neon-dp.decode
17
+++ b/target/arm/helper-sme.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
18
19
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
19
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
20
DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
20
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
21
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
22
+DEF_HELPER_FLAGS_6(sme_bfmopa, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/sme.decode
27
+++ b/target/arm/sme.decode
28
@@ -XXX,XX +XXX,XX @@ ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
29
30
FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
31
FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
21
+
32
+
22
+ VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
33
+BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
23
+ VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
34
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
24
]
25
26
# Subgroup for size != 0b11
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
36
--- a/target/arm/sme_helper.c
30
+++ b/target/arm/translate-neon.inc.c
37
+++ b/target/arm/sme_helper.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
38
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, void *vpn,
32
return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
39
}
33
accfn[a->size]);
40
}
34
}
41
}
35
+
42
+
36
+typedef void ZipFn(TCGv_ptr, TCGv_ptr);
43
+/*
44
+ * Alter PAIR as needed for controlling predicates being false,
45
+ * and for NEG on an enabled row element.
46
+ */
47
+static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t neg)
48
+{
49
+ /*
50
+ * The pseudocode uses a conditional negate after the conditional zero.
51
+ * It is simpler here to unconditionally negate before conditional zero.
52
+ */
53
+ pair ^= neg;
54
+ if (!(pg & 1)) {
55
+ pair &= 0xffff0000u;
56
+ }
57
+ if (!(pg & 4)) {
58
+ pair &= 0x0000ffffu;
59
+ }
60
+ return pair;
61
+}
37
+
62
+
38
+static bool do_zip_uzp(DisasContext *s, arg_2misc *a,
63
+void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
39
+ ZipFn *fn)
64
+ void *vpm, uint32_t desc)
40
+{
65
+{
41
+ TCGv_ptr pd, pm;
66
+ intptr_t row, col, oprsz = simd_maxsz(desc);
67
+ uint32_t neg = simd_data(desc) * 0x80008000u;
68
+ uint16_t *pn = vpn, *pm = vpm;
42
+
69
+
43
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
70
+ for (row = 0; row < oprsz; ) {
44
+ return false;
71
+ uint16_t prow = pn[H2(row >> 4)];
72
+ do {
73
+ void *vza_row = vza + tile_vslice_offset(row);
74
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row));
75
+
76
+ n = f16mop_adj_pair(n, prow, neg);
77
+
78
+ for (col = 0; col < oprsz; ) {
79
+ uint16_t pcol = pm[H2(col >> 4)];
80
+ do {
81
+ if (prow & pcol & 0b0101) {
82
+ uint32_t *a = vza_row + H1_4(col);
83
+ uint32_t m = *(uint32_t *)(vzm + H1_4(col));
84
+
85
+ m = f16mop_adj_pair(m, pcol, 0);
86
+ *a = bfdotadd(*a, n, m);
87
+
88
+ col += 4;
89
+ pcol >>= 4;
90
+ }
91
+ } while (col & 15);
92
+ }
93
+ row += 4;
94
+ prow >>= 4;
95
+ } while (row & 15);
45
+ }
96
+ }
97
+}
98
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-sme.c
101
+++ b/target/arm/translate-sme.c
102
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
103
TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
104
TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
105
106
+static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
107
+ gen_helper_gvec_5 *fn)
108
+{
109
+ int svl = streaming_vec_reg_size(s);
110
+ uint32_t desc = simd_desc(svl, svl, a->sub);
111
+ TCGv_ptr za, zn, zm, pn, pm;
46
+
112
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
113
+ if (!sme_smza_enabled_check(s)) {
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vm) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!fn) {
58
+ /* Bad size or size/q combination */
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
114
+ return true;
64
+ }
115
+ }
65
+
116
+
66
+ pd = vfp_reg_ptr(true, a->vd);
117
+ /* Sum XZR+zad to find ZAd. */
67
+ pm = vfp_reg_ptr(true, a->vm);
118
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
68
+ fn(pd, pm);
119
+ zn = vec_full_reg_ptr(s, a->zn);
69
+ tcg_temp_free_ptr(pd);
120
+ zm = vec_full_reg_ptr(s, a->zm);
121
+ pn = pred_full_reg_ptr(s, a->pn);
122
+ pm = pred_full_reg_ptr(s, a->pm);
123
+
124
+ fn(za, zn, zm, pn, pm, tcg_constant_i32(desc));
125
+
126
+ tcg_temp_free_ptr(za);
127
+ tcg_temp_free_ptr(zn);
128
+ tcg_temp_free_ptr(pn);
70
+ tcg_temp_free_ptr(pm);
129
+ tcg_temp_free_ptr(pm);
71
+ return true;
130
+ return true;
72
+}
131
+}
73
+
132
+
74
+static bool trans_VUZP(DisasContext *s, arg_2misc *a)
133
static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
75
+{
134
gen_helper_gvec_5_ptr *fn)
76
+ static ZipFn * const fn[2][4] = {
135
{
77
+ {
136
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
78
+ gen_helper_neon_unzip8,
137
79
+ gen_helper_neon_unzip16,
138
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
80
+ NULL,
139
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
81
+ NULL,
82
+ }, {
83
+ gen_helper_neon_qunzip8,
84
+ gen_helper_neon_qunzip16,
85
+ gen_helper_neon_qunzip32,
86
+ NULL,
87
+ }
88
+ };
89
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
90
+}
91
+
140
+
92
+static bool trans_VZIP(DisasContext *s, arg_2misc *a)
141
+/* TODO: FEAT_EBF16 */
93
+{
142
+TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
94
+ static ZipFn * const fn[2][4] = {
95
+ {
96
+ gen_helper_neon_zip8,
97
+ gen_helper_neon_zip16,
98
+ NULL,
99
+ NULL,
100
+ }, {
101
+ gen_helper_neon_qzip8,
102
+ gen_helper_neon_qzip16,
103
+ gen_helper_neon_qzip32,
104
+ NULL,
105
+ }
106
+ };
107
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
108
+}
109
diff --git a/target/arm/translate.c b/target/arm/translate.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate.c
112
+++ b/target/arm/translate.c
113
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
114
gen_rfe(s, pc, load_cpu_field(spsr));
115
}
116
117
-static int gen_neon_unzip(int rd, int rm, int size, int q)
118
-{
119
- TCGv_ptr pd, pm;
120
-
121
- if (!q && size == 2) {
122
- return 1;
123
- }
124
- pd = vfp_reg_ptr(true, rd);
125
- pm = vfp_reg_ptr(true, rm);
126
- if (q) {
127
- switch (size) {
128
- case 0:
129
- gen_helper_neon_qunzip8(pd, pm);
130
- break;
131
- case 1:
132
- gen_helper_neon_qunzip16(pd, pm);
133
- break;
134
- case 2:
135
- gen_helper_neon_qunzip32(pd, pm);
136
- break;
137
- default:
138
- abort();
139
- }
140
- } else {
141
- switch (size) {
142
- case 0:
143
- gen_helper_neon_unzip8(pd, pm);
144
- break;
145
- case 1:
146
- gen_helper_neon_unzip16(pd, pm);
147
- break;
148
- default:
149
- abort();
150
- }
151
- }
152
- tcg_temp_free_ptr(pd);
153
- tcg_temp_free_ptr(pm);
154
- return 0;
155
-}
156
-
157
-static int gen_neon_zip(int rd, int rm, int size, int q)
158
-{
159
- TCGv_ptr pd, pm;
160
-
161
- if (!q && size == 2) {
162
- return 1;
163
- }
164
- pd = vfp_reg_ptr(true, rd);
165
- pm = vfp_reg_ptr(true, rm);
166
- if (q) {
167
- switch (size) {
168
- case 0:
169
- gen_helper_neon_qzip8(pd, pm);
170
- break;
171
- case 1:
172
- gen_helper_neon_qzip16(pd, pm);
173
- break;
174
- case 2:
175
- gen_helper_neon_qzip32(pd, pm);
176
- break;
177
- default:
178
- abort();
179
- }
180
- } else {
181
- switch (size) {
182
- case 0:
183
- gen_helper_neon_zip8(pd, pm);
184
- break;
185
- case 1:
186
- gen_helper_neon_zip16(pd, pm);
187
- break;
188
- default:
189
- abort();
190
- }
191
- }
192
- tcg_temp_free_ptr(pd);
193
- tcg_temp_free_ptr(pm);
194
- return 0;
195
-}
196
-
197
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
198
{
199
TCGv_i32 rd, tmp;
200
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
case NEON_2RM_VREV64:
202
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
203
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
204
+ case NEON_2RM_VUZP:
205
+ case NEON_2RM_VZIP:
206
/* handled by decodetree */
207
return 1;
208
case NEON_2RM_VTRN:
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
210
goto elementwise;
211
}
212
break;
213
- case NEON_2RM_VUZP:
214
- if (gen_neon_unzip(rd, rm, size, q)) {
215
- return 1;
216
- }
217
- break;
218
- case NEON_2RM_VZIP:
219
- if (gen_neon_zip(rd, rm, size, q)) {
220
- return 1;
221
- }
222
- break;
223
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
224
/* also VQMOVUN; op field and mnemonics don't line up */
225
if (rm & 1) {
226
--
143
--
227
2.20.1
144
2.25.1
228
229
diff view generated by jsdifflib
1
Make gen_swap_half() take a source and destination TCGv_i32 rather
1
From: Richard Henderson <richard.henderson@linaro.org>
2
than modifying the input TCGv_i32; we're going to want to be able to
3
use it with the more flexible function signature, and this also
4
brings it into line with other functions like gen_rev16() and
5
gen_revsh().
6
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20220708151540.18136-27-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200616170844.13318-12-peter.maydell@linaro.org
10
---
7
---
11
target/arm/translate-neon.inc.c | 2 +-
8
target/arm/helper-sme.h | 2 ++
12
target/arm/translate.c | 10 +++++-----
9
target/arm/sme.decode | 1 +
13
2 files changed, 6 insertions(+), 6 deletions(-)
10
target/arm/sme_helper.c | 74 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sme.c | 1 +
12
4 files changed, 78 insertions(+)
14
13
15
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-neon.inc.c
16
--- a/target/arm/helper-sme.h
18
+++ b/target/arm/translate-neon.inc.c
17
+++ b/target/arm/helper-sme.h
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
19
DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
break;
20
DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
22
case 1:
21
23
- gen_swap_half(tmp[half]);
22
+DEF_HELPER_FLAGS_7(sme_fmopa_h, TCG_CALL_NO_RWG,
24
+ gen_swap_half(tmp[half], tmp[half]);
23
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
25
break;
24
DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
26
case 2:
25
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
27
break;
26
DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
29
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.c
29
--- a/target/arm/sme.decode
31
+++ b/target/arm/translate.c
30
+++ b/target/arm/sme.decode
32
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
31
@@ -XXX,XX +XXX,XX @@ FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
32
FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
33
34
BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
35
+FMOPA_h 10000001 101 ..... ... ... ..... . 00 .. @op_32
36
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sme_helper.c
39
+++ b/target/arm/sme_helper.c
40
@@ -XXX,XX +XXX,XX @@ static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t neg)
41
return pair;
33
}
42
}
34
43
35
/* Swap low and high halfwords. */
44
+static float32 f16_dotadd(float32 sum, uint32_t e1, uint32_t e2,
36
-static void gen_swap_half(TCGv_i32 var)
45
+ float_status *s_std, float_status *s_odd)
37
+static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
46
+{
47
+ float64 e1r = float16_to_float64(e1 & 0xffff, true, s_std);
48
+ float64 e1c = float16_to_float64(e1 >> 16, true, s_std);
49
+ float64 e2r = float16_to_float64(e2 & 0xffff, true, s_std);
50
+ float64 e2c = float16_to_float64(e2 >> 16, true, s_std);
51
+ float64 t64;
52
+ float32 t32;
53
+
54
+ /*
55
+ * The ARM pseudocode function FPDot performs both multiplies
56
+ * and the add with a single rounding operation. Emulate this
57
+ * by performing the first multiply in round-to-odd, then doing
58
+ * the second multiply as fused multiply-add, and rounding to
59
+ * float32 all in one step.
60
+ */
61
+ t64 = float64_mul(e1r, e2r, s_odd);
62
+ t64 = float64r32_muladd(e1c, e2c, t64, 0, s_std);
63
+
64
+ /* This conversion is exact, because we've already rounded. */
65
+ t32 = float64_to_float32(t64, s_std);
66
+
67
+ /* The final accumulation step is not fused. */
68
+ return float32_add(sum, t32, s_std);
69
+}
70
+
71
+void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
72
+ void *vpm, void *vst, uint32_t desc)
73
+{
74
+ intptr_t row, col, oprsz = simd_maxsz(desc);
75
+ uint32_t neg = simd_data(desc) * 0x80008000u;
76
+ uint16_t *pn = vpn, *pm = vpm;
77
+ float_status fpst_odd, fpst_std;
78
+
79
+ /*
80
+ * Make a copy of float_status because this operation does not
81
+ * update the cumulative fp exception status. It also produces
82
+ * default nans. Make a second copy with round-to-odd -- see above.
83
+ */
84
+ fpst_std = *(float_status *)vst;
85
+ set_default_nan_mode(true, &fpst_std);
86
+ fpst_odd = fpst_std;
87
+ set_float_rounding_mode(float_round_to_odd, &fpst_odd);
88
+
89
+ for (row = 0; row < oprsz; ) {
90
+ uint16_t prow = pn[H2(row >> 4)];
91
+ do {
92
+ void *vza_row = vza + tile_vslice_offset(row);
93
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row));
94
+
95
+ n = f16mop_adj_pair(n, prow, neg);
96
+
97
+ for (col = 0; col < oprsz; ) {
98
+ uint16_t pcol = pm[H2(col >> 4)];
99
+ do {
100
+ if (prow & pcol & 0b0101) {
101
+ uint32_t *a = vza_row + H1_4(col);
102
+ uint32_t m = *(uint32_t *)(vzm + H1_4(col));
103
+
104
+ m = f16mop_adj_pair(m, pcol, 0);
105
+ *a = f16_dotadd(*a, n, m, &fpst_std, &fpst_odd);
106
+
107
+ col += 4;
108
+ pcol >>= 4;
109
+ }
110
+ } while (col & 15);
111
+ }
112
+ row += 4;
113
+ prow >>= 4;
114
+ } while (row & 15);
115
+ }
116
+}
117
+
118
void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
119
void *vpm, uint32_t desc)
38
{
120
{
39
- tcg_gen_rotri_i32(var, var, 16);
121
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
40
+ tcg_gen_rotri_i32(dest, var, 16);
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/translate-sme.c
124
+++ b/target/arm/translate-sme.c
125
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
126
return true;
41
}
127
}
42
128
43
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
129
+TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_h)
44
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
130
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
45
case NEON_2RM_VREV32:
131
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
46
switch (size) {
47
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
48
- case 1: gen_swap_half(tmp); break;
49
+ case 1: gen_swap_half(tmp, tmp); break;
50
default: abort();
51
}
52
break;
53
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
54
t1 = load_reg(s, a->rn);
55
t2 = load_reg(s, a->rm);
56
if (m_swap) {
57
- gen_swap_half(t2);
58
+ gen_swap_half(t2, t2);
59
}
60
gen_smul_dual(t1, t2);
61
62
@@ -XXX,XX +XXX,XX @@ static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
63
t1 = load_reg(s, a->rn);
64
t2 = load_reg(s, a->rm);
65
if (m_swap) {
66
- gen_swap_half(t2);
67
+ gen_swap_half(t2, t2);
68
}
69
gen_smul_dual(t1, t2);
70
132
71
--
133
--
72
2.20.1
134
2.25.1
73
74
diff view generated by jsdifflib
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This adds support for memory(pc-dimm) hot remove on arm/virt that
3
This is SMOPA, SUMOPA, USMOPA_s, UMOPA, for both Int8 and Int16.
4
uses acpi ged device.
5
4
6
NVDIMM hot removal is not yet supported.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
7
Message-id: 20220708151540.18136-28-richard.henderson@linaro.org
9
Message-id: 20200622124157.20360-1-shameerali.kolothum.thodi@huawei.com
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Eric Auger <eric.auger@redhat.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
hw/acpi/generic_event_device.c | 29 ++++++++++++++++
10
target/arm/helper-sme.h | 16 ++++++++
15
hw/arm/virt.c | 62 ++++++++++++++++++++++++++++++++--
11
target/arm/sme.decode | 10 +++++
16
2 files changed, 89 insertions(+), 2 deletions(-)
12
target/arm/sme_helper.c | 82 ++++++++++++++++++++++++++++++++++++++
13
target/arm/translate-sme.c | 10 +++++
14
4 files changed, 118 insertions(+)
17
15
18
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
16
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/acpi/generic_event_device.c
18
--- a/target/arm/helper-sme.h
21
+++ b/hw/acpi/generic_event_device.c
19
+++ b/target/arm/helper-sme.h
22
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_6(sme_bfmopa, TCG_CALL_NO_RWG,
23
void, ptr, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sme_smopa_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sme_umopa_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_6(sme_sumopa_s, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_6(sme_usmopa_s, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_6(sme_smopa_d, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_6(sme_umopa_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_6(sme_sumopa_d, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sme_usmopa_d, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/sme.decode
43
+++ b/target/arm/sme.decode
44
@@ -XXX,XX +XXX,XX @@ FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
45
46
BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
47
FMOPA_h 10000001 101 ..... ... ... ..... . 00 .. @op_32
48
+
49
+SMOPA_s 1010000 0 10 0 ..... ... ... ..... . 00 .. @op_32
50
+SUMOPA_s 1010000 0 10 1 ..... ... ... ..... . 00 .. @op_32
51
+USMOPA_s 1010000 1 10 0 ..... ... ... ..... . 00 .. @op_32
52
+UMOPA_s 1010000 1 10 1 ..... ... ... ..... . 00 .. @op_32
53
+
54
+SMOPA_d 1010000 0 11 0 ..... ... ... ..... . 0 ... @op_64
55
+SUMOPA_d 1010000 0 11 1 ..... ... ... ..... . 0 ... @op_64
56
+USMOPA_d 1010000 1 11 0 ..... ... ... ..... . 0 ... @op_64
57
+UMOPA_d 1010000 1 11 1 ..... ... ... ..... . 0 ... @op_64
58
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sme_helper.c
61
+++ b/target/arm/sme_helper.c
62
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
63
} while (row & 15);
23
}
64
}
24
}
65
}
25
66
+
26
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
67
+typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
27
+ DeviceState *dev, Error **errp)
68
+
69
+static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
70
+ uint8_t *pn, uint8_t *pm,
71
+ uint32_t desc, IMOPFn *fn)
28
+{
72
+{
29
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
73
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
74
+ bool neg = simd_data(desc);
30
+
75
+
31
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
76
+ for (row = 0; row < oprsz; ++row) {
32
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
77
+ uint8_t pa = pn[H1(row)];
33
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
78
+ uint64_t *za_row = &za[tile_vslice_index(row)];
34
+ } else {
79
+ uint64_t n = zn[row];
35
+ error_setg(errp, "acpi: device unplug request for unsupported device"
80
+
36
+ " type: %s", object_get_typename(OBJECT(dev)));
81
+ for (col = 0; col < oprsz; ++col) {
82
+ uint8_t pb = pm[H1(col)];
83
+ uint64_t *a = &za_row[col];
84
+
85
+ *a = fn(n, zm[col], *a, pa & pb, neg);
86
+ }
37
+ }
87
+ }
38
+}
88
+}
39
+
89
+
40
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
90
+#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
41
+ DeviceState *dev, Error **errp)
91
+static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
42
+{
92
+{ \
43
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
93
+ uint32_t sum0 = 0, sum1 = 0; \
44
+
94
+ /* Apply P to N as a mask, making the inactive elements 0. */ \
45
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
95
+ n &= expand_pred_b(p); \
46
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
96
+ sum0 += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
47
+ } else {
97
+ sum0 += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
48
+ error_setg(errp, "acpi: device unplug for unsupported device"
98
+ sum0 += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
49
+ " type: %s", object_get_typename(OBJECT(dev)));
99
+ sum0 += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
50
+ }
100
+ sum1 += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
101
+ sum1 += (NTYPE)(n >> 40) * (MTYPE)(m >> 40); \
102
+ sum1 += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
103
+ sum1 += (NTYPE)(n >> 56) * (MTYPE)(m >> 56); \
104
+ if (neg) { \
105
+ sum0 = (uint32_t)a - sum0, sum1 = (uint32_t)(a >> 32) - sum1; \
106
+ } else { \
107
+ sum0 = (uint32_t)a + sum0, sum1 = (uint32_t)(a >> 32) + sum1; \
108
+ } \
109
+ return ((uint64_t)sum1 << 32) | sum0; \
51
+}
110
+}
52
+
111
+
53
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
112
+#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
54
{
113
+static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
55
AcpiGedState *s = ACPI_GED(adev);
114
+{ \
56
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
115
+ uint64_t sum = 0; \
57
dc->vmsd = &vmstate_acpi_ged;
116
+ /* Apply P to N as a mask, making the inactive elements 0. */ \
58
117
+ n &= expand_pred_h(p); \
59
hc->plug = acpi_ged_device_plug_cb;
118
+ sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
60
+ hc->unplug_request = acpi_ged_unplug_request_cb;
119
+ sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
61
+ hc->unplug = acpi_ged_unplug_cb;
120
+ sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
62
121
+ sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
63
adevc->send_event = acpi_ged_send_event;
122
+ return neg ? a - sum : a + sum; \
64
}
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/virt.c
68
+++ b/hw/arm/virt.c
69
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
70
}
71
}
72
73
+static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
74
+ DeviceState *dev, Error **errp)
75
+{
76
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
77
+ Error *local_err = NULL;
78
+
79
+ if (!vms->acpi_dev) {
80
+ error_setg(&local_err,
81
+ "memory hotplug is not enabled: missing acpi-ged device");
82
+ goto out;
83
+ }
84
+
85
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
86
+ error_setg(&local_err,
87
+ "nvdimm device hot unplug is not supported yet.");
88
+ goto out;
89
+ }
90
+
91
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
92
+ &local_err);
93
+out:
94
+ error_propagate(errp, local_err);
95
+}
123
+}
96
+
124
+
97
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
125
+DEF_IMOP_32(smopa_s, int8_t, int8_t)
98
+ DeviceState *dev, Error **errp)
126
+DEF_IMOP_32(umopa_s, uint8_t, uint8_t)
99
+{
127
+DEF_IMOP_32(sumopa_s, int8_t, uint8_t)
100
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
128
+DEF_IMOP_32(usmopa_s, uint8_t, int8_t)
101
+ Error *local_err = NULL;
102
+
129
+
103
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
130
+DEF_IMOP_64(smopa_d, int16_t, int16_t)
104
+ if (local_err) {
131
+DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
105
+ goto out;
132
+DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
106
+ }
133
+DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
107
+
134
+
108
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
135
+#define DEF_IMOPH(NAME) \
109
+ qdev_unrealize(dev);
136
+ void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
137
+ void *vpm, uint32_t desc) \
138
+ { do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
110
+
139
+
111
+out:
140
+DEF_IMOPH(smopa_s)
112
+ error_propagate(errp, local_err);
141
+DEF_IMOPH(umopa_s)
113
+}
142
+DEF_IMOPH(sumopa_s)
143
+DEF_IMOPH(usmopa_s)
144
+DEF_IMOPH(smopa_d)
145
+DEF_IMOPH(umopa_d)
146
+DEF_IMOPH(sumopa_d)
147
+DEF_IMOPH(usmopa_d)
148
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/translate-sme.c
151
+++ b/target/arm/translate-sme.c
152
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_f
153
154
/* TODO: FEAT_EBF16 */
155
TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
114
+
156
+
115
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
157
+TRANS_FEAT(SMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_smopa_s)
116
DeviceState *dev, Error **errp)
158
+TRANS_FEAT(UMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_umopa_s)
117
{
159
+TRANS_FEAT(SUMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_sumopa_s)
118
- error_setg(errp, "device unplug request for unsupported device"
160
+TRANS_FEAT(USMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_usmopa_s)
119
- " type: %s", object_get_typename(OBJECT(dev)));
120
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
121
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
122
+ } else {
123
+ error_setg(errp, "device unplug request for unsupported device"
124
+ " type: %s", object_get_typename(OBJECT(dev)));
125
+ }
126
+}
127
+
161
+
128
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
162
+TRANS_FEAT(SMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_smopa_d)
129
+ DeviceState *dev, Error **errp)
163
+TRANS_FEAT(UMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_umopa_d)
130
+{
164
+TRANS_FEAT(SUMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_sumopa_d)
131
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
165
+TRANS_FEAT(USMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_usmopa_d)
132
+ virt_dimm_unplug(hotplug_dev, dev, errp);
133
+ } else {
134
+ error_setg(errp, "virt: device unplug for unsupported device"
135
+ " type: %s", object_get_typename(OBJECT(dev)));
136
+ }
137
}
138
139
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
140
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
141
hc->pre_plug = virt_machine_device_pre_plug_cb;
142
hc->plug = virt_machine_device_plug_cb;
143
hc->unplug_request = virt_machine_device_unplug_request_cb;
144
+ hc->unplug = virt_machine_device_unplug_cb;
145
mc->numa_mem_supported = true;
146
mc->nvdimm_supported = true;
147
mc->auto_enable_numa_with_memhp = true;
148
--
166
--
149
2.20.1
167
2.25.1
150
151
diff view generated by jsdifflib
1
Convert the Neon VSWP insn to decodetree. Since the new implementation
1
From: Richard Henderson <richard.henderson@linaro.org>
2
doesn't have to share a pass-loop with the other 2-reg-misc operations
3
we can implement the swap with 64-bit accesses rather than 32-bits
4
(which brings us into line with the pseudocode and is more efficient).
5
2
3
This is an SVE instruction that operates using the SVE vector
4
length but that it is present only if SME is implemented.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-29-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-20-peter.maydell@linaro.org
9
---
10
---
10
target/arm/neon-dp.decode | 2 ++
11
target/arm/sve.decode | 20 +++++++++++++
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 57 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 5 +---
13
2 files changed, 77 insertions(+)
13
3 files changed, 44 insertions(+), 4 deletions(-)
14
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/sve.decode
18
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/sve.decode
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
@@ -XXX,XX +XXX,XX @@ BFMLALT_zzxw 01100100 11 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
20
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
20
21
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
21
### SVE2 floating-point bfloat16 dot-product (indexed)
22
22
BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
23
+ VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
24
+
23
+
25
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
24
+### SVE broadcast predicate element
26
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
25
+
27
26
+&psel esz pd pn pm rv imm
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
+%psel_rv 16:2 !function=plus_12
28
+%psel_imm_b 22:2 19:2
29
+%psel_imm_h 22:2 20:1
30
+%psel_imm_s 22:2
31
+%psel_imm_d 23:1
32
+@psel ........ .. . ... .. .. pn:4 . pm:4 . pd:4 \
33
+ &psel rv=%psel_rv
34
+
35
+PSEL 00100101 .. 1 ..1 .. 01 .... 0 .... 0 .... \
36
+ @psel esz=0 imm=%psel_imm_b
37
+PSEL 00100101 .. 1 .10 .. 01 .... 0 .... 0 .... \
38
+ @psel esz=1 imm=%psel_imm_h
39
+PSEL 00100101 .. 1 100 .. 01 .... 0 .... 0 .... \
40
+ @psel esz=2 imm=%psel_imm_s
41
+PSEL 00100101 .1 1 000 .. 01 .... 0 .... 0 .... \
42
+ @psel esz=3 imm=%psel_imm_d
43
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-neon.inc.c
45
--- a/target/arm/translate-sve.c
31
+++ b/target/arm/translate-neon.inc.c
46
+++ b/target/arm/translate-sve.c
32
@@ -XXX,XX +XXX,XX @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
47
@@ -XXX,XX +XXX,XX @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
33
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
48
34
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
49
TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)
35
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
50
TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true)
36
+
51
+
37
+static bool trans_VSWP(DisasContext *s, arg_2misc *a)
52
+static bool trans_PSEL(DisasContext *s, arg_psel *a)
38
+{
53
+{
39
+ TCGv_i64 rm, rd;
54
+ int vl = vec_full_reg_size(s);
40
+ int pass;
55
+ int pl = pred_gvec_reg_size(s);
56
+ int elements = vl >> a->esz;
57
+ TCGv_i64 tmp, didx, dbit;
58
+ TCGv_ptr ptr;
41
+
59
+
42
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
60
+ if (!dc_isar_feature(aa64_sme, s)) {
43
+ return false;
61
+ return false;
44
+ }
62
+ }
45
+
63
+ if (!sve_access_check(s)) {
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
48
+ ((a->vd | a->vm) & 0x10)) {
49
+ return false;
50
+ }
51
+
52
+ if (a->size != 0) {
53
+ return false;
54
+ }
55
+
56
+ if ((a->vd | a->vm) & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
64
+ return true;
62
+ }
65
+ }
63
+
66
+
64
+ rm = tcg_temp_new_i64();
67
+ tmp = tcg_temp_new_i64();
65
+ rd = tcg_temp_new_i64();
68
+ dbit = tcg_temp_new_i64();
66
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
69
+ didx = tcg_temp_new_i64();
67
+ neon_load_reg64(rm, a->vm + pass);
70
+ ptr = tcg_temp_new_ptr();
68
+ neon_load_reg64(rd, a->vd + pass);
71
+
69
+ neon_store_reg64(rm, a->vd + pass);
72
+ /* Compute the predicate element. */
70
+ neon_store_reg64(rd, a->vm + pass);
73
+ tcg_gen_addi_i64(tmp, cpu_reg(s, a->rv), a->imm);
74
+ if (is_power_of_2(elements)) {
75
+ tcg_gen_andi_i64(tmp, tmp, elements - 1);
76
+ } else {
77
+ tcg_gen_remu_i64(tmp, tmp, tcg_constant_i64(elements));
71
+ }
78
+ }
72
+ tcg_temp_free_i64(rm);
73
+ tcg_temp_free_i64(rd);
74
+
79
+
80
+ /* Extract the predicate byte and bit indices. */
81
+ tcg_gen_shli_i64(tmp, tmp, a->esz);
82
+ tcg_gen_andi_i64(dbit, tmp, 7);
83
+ tcg_gen_shri_i64(didx, tmp, 3);
84
+ if (HOST_BIG_ENDIAN) {
85
+ tcg_gen_xori_i64(didx, didx, 7);
86
+ }
87
+
88
+ /* Load the predicate word. */
89
+ tcg_gen_trunc_i64_ptr(ptr, didx);
90
+ tcg_gen_add_ptr(ptr, ptr, cpu_env);
91
+ tcg_gen_ld8u_i64(tmp, ptr, pred_full_reg_offset(s, a->pm));
92
+
93
+ /* Extract the predicate bit and replicate to MO_64. */
94
+ tcg_gen_shr_i64(tmp, tmp, dbit);
95
+ tcg_gen_andi_i64(tmp, tmp, 1);
96
+ tcg_gen_neg_i64(tmp, tmp);
97
+
98
+ /* Apply to either copy the source, or write zeros. */
99
+ tcg_gen_gvec_ands(MO_64, pred_full_reg_offset(s, a->pd),
100
+ pred_full_reg_offset(s, a->pn), tmp, pl, pl);
101
+
102
+ tcg_temp_free_i64(tmp);
103
+ tcg_temp_free_i64(dbit);
104
+ tcg_temp_free_i64(didx);
105
+ tcg_temp_free_ptr(ptr);
75
+ return true;
106
+ return true;
76
+}
107
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
82
case NEON_2RM_VCVTPS:
83
case NEON_2RM_VCVTMU:
84
case NEON_2RM_VCVTMS:
85
+ case NEON_2RM_VSWP:
86
/* handled by decodetree */
87
return 1;
88
case NEON_2RM_VTRN:
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
for (pass = 0; pass < (q ? 4 : 2); pass++) {
91
tmp = neon_load_reg(rm, pass);
92
switch (op) {
93
- case NEON_2RM_VSWP:
94
- tmp2 = neon_load_reg(rd, pass);
95
- neon_store_reg(rm, pass, tmp2);
96
- break;
97
case NEON_2RM_VTRN:
98
tmp2 = neon_load_reg(rd, pass);
99
switch (size) {
100
--
108
--
101
2.20.1
109
2.25.1
102
103
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
To differenciate with the CMSDK APB peripheral region,
3
This is an SVE instruction that operates using the SVE vector
4
rename this region 'CMSDK AHB peripheral region'.
4
length but that it is present only if SME is implemented.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200617072539.32686-8-f4bug@amsat.org
8
Message-id: 20220708151540.18136-30-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/mps2.c | 3 ++-
11
target/arm/helper-sve.h | 2 ++
12
1 file changed, 2 insertions(+), 1 deletion(-)
12
target/arm/sve.decode | 1 +
13
target/arm/sve_helper.c | 16 ++++++++++++++++
14
target/arm/translate-sve.c | 2 ++
15
4 files changed, 21 insertions(+)
13
16
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
19
--- a/target/arm/helper-sve.h
17
+++ b/hw/arm/mps2.c
20
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_revh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
*/
22
20
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
23
DEF_HELPER_FLAGS_4(sve_revw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
0x40000000, 0x00010000);
24
22
- create_unimplemented_device("CMSDK peripheral region @0x40010000",
25
+DEF_HELPER_FLAGS_4(sme_revd_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+ create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
24
0x40010000, 0x00010000);
25
create_unimplemented_device("Extra peripheral region @0x40020000",
26
0x40020000, 0x00010000);
27
+
26
+
28
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
27
DEF_HELPER_FLAGS_4(sve_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
28
DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve.decode
33
+++ b/target/arm/sve.decode
34
@@ -XXX,XX +XXX,XX @@ REVB 00000101 .. 1001 00 100 ... ..... ..... @rd_pg_rn
35
REVH 00000101 .. 1001 01 100 ... ..... ..... @rd_pg_rn
36
REVW 00000101 .. 1001 10 100 ... ..... ..... @rd_pg_rn
37
RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
38
+REVD 00000101 00 1011 10 100 ... ..... ..... @rd_pg_rn_e0
39
40
# SVE vector splice (predicated, destructive)
41
SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve_helper.c
45
+++ b/target/arm/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_D(sve_revh_d, uint64_t, hswap64)
47
48
DO_ZPZ_D(sve_revw_d, uint64_t, wswap64)
49
50
+void HELPER(sme_revd_q)(void *vd, void *vn, void *vg, uint32_t desc)
51
+{
52
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
53
+ uint64_t *d = vd, *n = vn;
54
+ uint8_t *pg = vg;
55
+
56
+ for (i = 0; i < opr_sz; i += 2) {
57
+ if (pg[H1(i)] & 1) {
58
+ uint64_t n0 = n[i + 0];
59
+ uint64_t n1 = n[i + 1];
60
+ d[i + 0] = n1;
61
+ d[i + 1] = n0;
62
+ }
63
+ }
64
+}
65
+
66
DO_ZPZ(sve_rbit_b, uint8_t, H1, revbit8)
67
DO_ZPZ(sve_rbit_h, uint16_t, H1_2, revbit16)
68
DO_ZPZ(sve_rbit_s, uint32_t, H1_4, revbit32)
69
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-sve.c
72
+++ b/target/arm/translate-sve.c
73
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(REVH, aa64_sve, gen_gvec_ool_arg_zpz, revh_fns[a->esz], a, 0)
74
TRANS_FEAT(REVW, aa64_sve, gen_gvec_ool_arg_zpz,
75
a->esz == 3 ? gen_helper_sve_revw_d : NULL, a, 0)
76
77
+TRANS_FEAT(REVD, aa64_sme, gen_gvec_ool_arg_zpz, gen_helper_sme_revd_q, a, 0)
78
+
79
TRANS_FEAT(SPLICE, aa64_sve, gen_gvec_ool_arg_zpzz,
80
gen_helper_sve_splice, a, a->esz)
30
81
31
--
82
--
32
2.20.1
83
2.25.1
33
34
diff view generated by jsdifflib
1
Convert the fp-compare-with-zero insns in the Neon 2-reg-misc group to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
3
This is an SVE instruction that operates using the SVE vector
4
length but that it is present only if SME is implemented.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-31-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-17-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 6 ++++
11
target/arm/helper.h | 18 +++++++
9
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++
12
target/arm/sve.decode | 5 ++
10
target/arm/translate.c | 50 ++++-----------------------------
13
target/arm/translate-sve.c | 102 +++++++++++++++++++++++++++++++++++++
11
3 files changed, 39 insertions(+), 45 deletions(-)
14
target/arm/vec_helper.c | 24 +++++++++
15
4 files changed, 149 insertions(+)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/target/arm/helper.h
16
+++ b/target/arm/neon-dp.decode
20
+++ b/target/arm/helper.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
18
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
22
DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
19
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
23
void, ptr, ptr, ptr, ptr, ptr, i32)
20
24
21
+ VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
25
+DEF_HELPER_FLAGS_5(gvec_sclamp_b, TCG_CALL_NO_RWG,
22
+ VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
26
+ void, ptr, ptr, ptr, ptr, i32)
23
+ VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
27
+DEF_HELPER_FLAGS_5(gvec_sclamp_h, TCG_CALL_NO_RWG,
24
+ VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
28
+ void, ptr, ptr, ptr, ptr, i32)
25
+ VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
29
+DEF_HELPER_FLAGS_5(gvec_sclamp_s, TCG_CALL_NO_RWG,
26
+
30
+ void, ptr, ptr, ptr, ptr, i32)
27
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
31
+DEF_HELPER_FLAGS_5(gvec_sclamp_d, TCG_CALL_NO_RWG,
28
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
32
+ void, ptr, ptr, ptr, ptr, i32)
29
33
+
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
+DEF_HELPER_FLAGS_5(gvec_uclamp_b, TCG_CALL_NO_RWG,
31
index XXXXXXX..XXXXXXX 100644
35
+ void, ptr, ptr, ptr, ptr, i32)
32
--- a/target/arm/translate-neon.inc.c
36
+DEF_HELPER_FLAGS_5(gvec_uclamp_h, TCG_CALL_NO_RWG,
33
+++ b/target/arm/translate-neon.inc.c
37
+ void, ptr, ptr, ptr, ptr, i32)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
38
+DEF_HELPER_FLAGS_5(gvec_uclamp_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+
43
#ifdef TARGET_AARCH64
44
#include "helper-a64.h"
45
#include "helper-sve.h"
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ PSEL 00100101 .. 1 100 .. 01 .... 0 .... 0 .... \
51
@psel esz=2 imm=%psel_imm_s
52
PSEL 00100101 .1 1 000 .. 01 .... 0 .... 0 .... \
53
@psel esz=3 imm=%psel_imm_d
54
+
55
+### SVE clamp
56
+
57
+SCLAMP 01000100 .. 0 ..... 110000 ..... ..... @rda_rn_rm
58
+UCLAMP 01000100 .. 0 ..... 110001 ..... ..... @rda_rn_rm
59
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/translate-sve.c
62
+++ b/target/arm/translate-sve.c
63
@@ -XXX,XX +XXX,XX @@ static bool trans_PSEL(DisasContext *s, arg_psel *a)
64
tcg_temp_free_ptr(ptr);
65
return true;
66
}
67
+
68
+static void gen_sclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a)
69
+{
70
+ tcg_gen_smax_i32(d, a, n);
71
+ tcg_gen_smin_i32(d, d, m);
72
+}
73
+
74
+static void gen_sclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a)
75
+{
76
+ tcg_gen_smax_i64(d, a, n);
77
+ tcg_gen_smin_i64(d, d, m);
78
+}
79
+
80
+static void gen_sclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
81
+ TCGv_vec m, TCGv_vec a)
82
+{
83
+ tcg_gen_smax_vec(vece, d, a, n);
84
+ tcg_gen_smin_vec(vece, d, d, m);
85
+}
86
+
87
+static void gen_sclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
88
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
89
+{
90
+ static const TCGOpcode vecop[] = {
91
+ INDEX_op_smin_vec, INDEX_op_smax_vec, 0
92
+ };
93
+ static const GVecGen4 ops[4] = {
94
+ { .fniv = gen_sclamp_vec,
95
+ .fno = gen_helper_gvec_sclamp_b,
96
+ .opt_opc = vecop,
97
+ .vece = MO_8 },
98
+ { .fniv = gen_sclamp_vec,
99
+ .fno = gen_helper_gvec_sclamp_h,
100
+ .opt_opc = vecop,
101
+ .vece = MO_16 },
102
+ { .fni4 = gen_sclamp_i32,
103
+ .fniv = gen_sclamp_vec,
104
+ .fno = gen_helper_gvec_sclamp_s,
105
+ .opt_opc = vecop,
106
+ .vece = MO_32 },
107
+ { .fni8 = gen_sclamp_i64,
108
+ .fniv = gen_sclamp_vec,
109
+ .fno = gen_helper_gvec_sclamp_d,
110
+ .opt_opc = vecop,
111
+ .vece = MO_64,
112
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64 }
113
+ };
114
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]);
115
+}
116
+
117
+TRANS_FEAT(SCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_sclamp, a)
118
+
119
+static void gen_uclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a)
120
+{
121
+ tcg_gen_umax_i32(d, a, n);
122
+ tcg_gen_umin_i32(d, d, m);
123
+}
124
+
125
+static void gen_uclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a)
126
+{
127
+ tcg_gen_umax_i64(d, a, n);
128
+ tcg_gen_umin_i64(d, d, m);
129
+}
130
+
131
+static void gen_uclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
132
+ TCGv_vec m, TCGv_vec a)
133
+{
134
+ tcg_gen_umax_vec(vece, d, a, n);
135
+ tcg_gen_umin_vec(vece, d, d, m);
136
+}
137
+
138
+static void gen_uclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
139
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
140
+{
141
+ static const TCGOpcode vecop[] = {
142
+ INDEX_op_umin_vec, INDEX_op_umax_vec, 0
143
+ };
144
+ static const GVecGen4 ops[4] = {
145
+ { .fniv = gen_uclamp_vec,
146
+ .fno = gen_helper_gvec_uclamp_b,
147
+ .opt_opc = vecop,
148
+ .vece = MO_8 },
149
+ { .fniv = gen_uclamp_vec,
150
+ .fno = gen_helper_gvec_uclamp_h,
151
+ .opt_opc = vecop,
152
+ .vece = MO_16 },
153
+ { .fni4 = gen_uclamp_i32,
154
+ .fniv = gen_uclamp_vec,
155
+ .fno = gen_helper_gvec_uclamp_s,
156
+ .opt_opc = vecop,
157
+ .vece = MO_32 },
158
+ { .fni8 = gen_uclamp_i64,
159
+ .fniv = gen_uclamp_vec,
160
+ .fno = gen_helper_gvec_uclamp_d,
161
+ .opt_opc = vecop,
162
+ .vece = MO_64,
163
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64 }
164
+ };
165
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]);
166
+}
167
+
168
+TRANS_FEAT(UCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_uclamp, a)
169
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/target/arm/vec_helper.c
172
+++ b/target/arm/vec_helper.c
173
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmlal_idx)(void *vd, void *vn, void *vm,
35
}
174
}
36
return do_2misc_fp(s, a, gen_helper_rints_exact);
175
clear_tail(d, opr_sz, simd_maxsz(desc));
37
}
176
}
38
+
177
+
39
+#define WRAP_FP_CMP0_FWD(WRAPNAME, FUNC) \
178
+#define DO_CLAMP(NAME, TYPE) \
40
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
179
+void HELPER(NAME)(void *d, void *n, void *m, void *a, uint32_t desc) \
41
+ { \
180
+{ \
42
+ TCGv_i32 zero = tcg_const_i32(0); \
181
+ intptr_t i, opr_sz = simd_oprsz(desc); \
43
+ FUNC(d, m, zero, fpst); \
182
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
44
+ tcg_temp_free_i32(zero); \
183
+ TYPE aa = *(TYPE *)(a + i); \
45
+ }
184
+ TYPE nn = *(TYPE *)(n + i); \
46
+#define WRAP_FP_CMP0_REV(WRAPNAME, FUNC) \
185
+ TYPE mm = *(TYPE *)(m + i); \
47
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
186
+ TYPE dd = MIN(MAX(aa, nn), mm); \
48
+ { \
187
+ *(TYPE *)(d + i) = dd; \
49
+ TCGv_i32 zero = tcg_const_i32(0); \
188
+ } \
50
+ FUNC(d, zero, m, fpst); \
189
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
51
+ tcg_temp_free_i32(zero); \
190
+}
52
+ }
191
+
53
+
192
+DO_CLAMP(gvec_sclamp_b, int8_t)
54
+#define DO_FP_CMP0(INSN, FUNC, REV) \
193
+DO_CLAMP(gvec_sclamp_h, int16_t)
55
+ WRAP_FP_CMP0_##REV(gen_##INSN, FUNC) \
194
+DO_CLAMP(gvec_sclamp_s, int32_t)
56
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
195
+DO_CLAMP(gvec_sclamp_d, int64_t)
57
+ { \
196
+
58
+ return do_2misc_fp(s, a, gen_##INSN); \
197
+DO_CLAMP(gvec_uclamp_b, uint8_t)
59
+ }
198
+DO_CLAMP(gvec_uclamp_h, uint16_t)
60
+
199
+DO_CLAMP(gvec_uclamp_s, uint32_t)
61
+DO_FP_CMP0(VCGT0_F, gen_helper_neon_cgt_f32, FWD)
200
+DO_CLAMP(gvec_uclamp_d, uint64_t)
62
+DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
63
+DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
64
+DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
65
+DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
case NEON_2RM_VCVT_SF:
72
case NEON_2RM_VCVT_UF:
73
case NEON_2RM_VRINTX:
74
+ case NEON_2RM_VCGT0_F:
75
+ case NEON_2RM_VCGE0_F:
76
+ case NEON_2RM_VCEQ0_F:
77
+ case NEON_2RM_VCLE0_F:
78
+ case NEON_2RM_VCLT0_F:
79
/* handled by decodetree */
80
return 1;
81
case NEON_2RM_VTRN:
82
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
83
for (pass = 0; pass < (q ? 4 : 2); pass++) {
84
tmp = neon_load_reg(rm, pass);
85
switch (op) {
86
- case NEON_2RM_VCGT0_F:
87
- {
88
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
89
- tmp2 = tcg_const_i32(0);
90
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
91
- tcg_temp_free_i32(tmp2);
92
- tcg_temp_free_ptr(fpstatus);
93
- break;
94
- }
95
- case NEON_2RM_VCGE0_F:
96
- {
97
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
98
- tmp2 = tcg_const_i32(0);
99
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
100
- tcg_temp_free_i32(tmp2);
101
- tcg_temp_free_ptr(fpstatus);
102
- break;
103
- }
104
- case NEON_2RM_VCEQ0_F:
105
- {
106
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
107
- tmp2 = tcg_const_i32(0);
108
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
109
- tcg_temp_free_i32(tmp2);
110
- tcg_temp_free_ptr(fpstatus);
111
- break;
112
- }
113
- case NEON_2RM_VCLE0_F:
114
- {
115
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
116
- tmp2 = tcg_const_i32(0);
117
- gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
118
- tcg_temp_free_i32(tmp2);
119
- tcg_temp_free_ptr(fpstatus);
120
- break;
121
- }
122
- case NEON_2RM_VCLT0_F:
123
- {
124
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
125
- tmp2 = tcg_const_i32(0);
126
- gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
127
- tcg_temp_free_i32(tmp2);
128
- tcg_temp_free_ptr(fpstatus);
129
- break;
130
- }
131
case NEON_2RM_VSWP:
132
tmp2 = neon_load_reg(rd, pass);
133
neon_store_reg(rm, pass, tmp2);
134
--
201
--
135
2.20.1
202
2.25.1
136
137
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
We can handle both exception entry and exception return by
4
- quickly find where devices are used with 'git-grep'
4
hooking into aarch64_sve_change_el.
5
- easily rename a device (one-line change).
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200617072539.32686-6-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-32-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/realview.c | 3 ++-
11
target/arm/helper.c | 15 +++++++++++++--
13
hw/arm/versatilepb.c | 3 ++-
12
1 file changed, 13 insertions(+), 2 deletions(-)
14
hw/arm/vexpress.c | 3 ++-
15
3 files changed, 6 insertions(+), 3 deletions(-)
16
13
17
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/realview.c
16
--- a/target/arm/helper.c
20
+++ b/hw/arm/realview.c
17
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
22
#include "hw/cpu/a9mpcore.h"
19
return;
23
#include "hw/intc/realview_gic.h"
24
#include "hw/irq.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
26
27
#define SMP_BOOT_ADDR 0xe0000000
28
#define SMP_BOOTREG_ADDR 0x10000030
29
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
30
}
31
}
20
}
32
21
33
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
22
+ old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
34
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
23
+ new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
35
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
24
+
36
i2c_create_slave(i2c, "ds1338", 0x68);
25
+ /*
37
26
+ * Both AArch64.TakeException and AArch64.ExceptionReturn
38
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
27
+ * invoke ResetSVEState when taking an exception from, or
39
index XXXXXXX..XXXXXXX 100644
28
+ * returning to, AArch32 state when PSTATE.SM is enabled.
40
--- a/hw/arm/versatilepb.c
29
+ */
41
+++ b/hw/arm/versatilepb.c
30
+ if (old_a64 != new_a64 && FIELD_EX64(env->svcr, SVCR, SM)) {
42
@@ -XXX,XX +XXX,XX @@
31
+ arm_reset_sve_state(env);
43
#include "sysemu/sysemu.h"
32
+ return;
44
#include "hw/pci/pci.h"
33
+ }
45
#include "hw/i2c/i2c.h"
34
+
46
+#include "hw/i2c/arm_sbcon_i2c.h"
35
/*
47
#include "hw/irq.h"
36
* DDI0584A.d sec 3.2: "If SVE instructions are disabled or trapped
48
#include "hw/boards.h"
37
* at ELx, or not available because the EL is in AArch32 state, then
49
#include "exec/address-spaces.h"
38
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
50
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
39
* we already have the correct register contents when encountering the
51
/* Add PL031 Real Time Clock. */
40
* vq0->vq0 transition between EL0->EL1.
52
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
41
*/
53
42
- old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
54
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
43
old_len = (old_a64 && !sve_exception_el(env, old_el)
55
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
44
? sve_vqm1_for_el(env, old_el) : 0);
56
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
45
- new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
57
i2c_create_slave(i2c, "ds1338", 0x68);
46
new_len = (new_a64 && !sve_exception_el(env, new_el)
58
47
? sve_vqm1_for_el(env, new_el) : 0);
59
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/vexpress.c
62
+++ b/hw/arm/vexpress.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/char/pl011.h"
65
#include "hw/cpu/a9mpcore.h"
66
#include "hw/cpu/a15mpcore.h"
67
+#include "hw/i2c/arm_sbcon_i2c.h"
68
69
#define VEXPRESS_BOARD_ID 0x8e0
70
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
71
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
72
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
73
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
74
75
- dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
76
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, map[VE_SERIALDVI], NULL);
77
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
78
i2c_create_slave(i2c, "sii9022", 0x39);
79
48
80
--
49
--
81
2.20.1
50
2.25.1
82
83
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: Cornelia Huck <cohuck@redhat.com>
3
Note that SME remains effectively disabled for user-only,
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
because we do not yet set CPACR_EL1.SMEN. This needs to
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
5
wait until the kernel ABI is implemented.
6
Message-id: 20200616140803.25515-1-drjones@redhat.com
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-33-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
hw/arm/virt.c | 1 +
12
docs/system/arm/emulation.rst | 4 ++++
10
1 file changed, 1 insertion(+)
13
target/arm/cpu64.c | 11 +++++++++++
14
2 files changed, 15 insertions(+)
11
15
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
18
--- a/docs/system/arm/emulation.rst
15
+++ b/hw/arm/virt.c
19
+++ b/docs/system/arm/emulation.rst
16
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
17
static void virt_machine_5_0_options(MachineClass *mc)
21
- FEAT_SHA512 (Advanced SIMD SHA512 instructions)
18
{
22
- FEAT_SM3 (Advanced SIMD SM3 instructions)
19
virt_machine_5_1_options(mc);
23
- FEAT_SM4 (Advanced SIMD SM4 instructions)
20
+ compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
24
+- FEAT_SME (Scalable Matrix Extension)
21
}
25
+- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
22
DEFINE_VIRT_MACHINE(5, 0)
26
+- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
27
+- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
28
- FEAT_SPECRES (Speculation restriction instructions)
29
- FEAT_SSBS (Speculative Store Bypass Safe)
30
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
31
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu64.c
34
+++ b/target/arm/cpu64.c
35
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
36
*/
37
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
38
t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
39
+ t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
40
t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
41
cpu->isar.id_aa64pfr1 = t;
42
43
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
44
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
45
cpu->isar.id_aa64dfr0 = t;
46
47
+ t = cpu->isar.id_aa64smfr0;
48
+ t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
49
+ t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */
50
+ t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */
51
+ t = FIELD_DP64(t, ID_AA64SMFR0, I8I32, 0xf); /* FEAT_SME */
52
+ t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */
53
+ t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
54
+ t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
55
+ cpu->isar.id_aa64smfr0 = t;
56
+
57
/* Replicate the same data to the 32-bit id registers. */
58
aa32_max_features(cpu);
23
59
24
--
60
--
25
2.20.1
61
2.25.1
26
27
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
From 'Application Note AN521', chapter 4.7:
4
5
The SMM implements four SBCon serial modules:
6
7
One SBCon module for use by the Color LCD touch interface.
8
One SBCon module to configure the audio controller.
9
Two general purpose SBCon modules, that connect to the
10
Expansion headers J7 and J8, are intended for use with the
11
V2C-Shield1 which provide an I2C interface on the headers.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-15-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-34-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
7
---
18
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
8
linux-user/aarch64/target_cpu.h | 5 ++++-
19
1 file changed, 18 insertions(+), 5 deletions(-)
9
1 file changed, 4 insertions(+), 1 deletion(-)
20
10
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
13
--- a/linux-user/aarch64/target_cpu.h
24
+++ b/hw/arm/mps2-tz.c
14
+++ b/linux-user/aarch64/target_cpu.h
25
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static inline void cpu_clone_regs_parent(CPUARMState *env, unsigned flags)
26
#include "hw/arm/armsse.h"
16
27
#include "hw/dma/pl080.h"
17
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
28
#include "hw/ssi/pl022.h"
18
{
29
+#include "hw/i2c/arm_sbcon_i2c.h"
19
- /* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
30
#include "hw/net/lan9118.h"
20
+ /*
31
#include "net/net.h"
21
+ * Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
32
#include "hw/core/split-irq.h"
22
* different from AArch32 Linux, which uses TPIDRRO.
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
*/
34
TZPPC ppc[5];
24
env->cp15.tpidr_el[0] = newtls;
35
TZMPC ssram_mpc[3];
25
+ /* TPIDR2_EL0 is cleared with CLONE_SETTLS. */
36
PL022State spi[5];
26
+ env->cp15.tpidr2_el0 = 0;
37
- UnimplementedDeviceState i2c[4];
38
+ ArmSbconI2CState i2c[4];
39
UnimplementedDeviceState i2s_audio;
40
UnimplementedDeviceState gpio[4];
41
UnimplementedDeviceState gfx;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
43
return sysbus_mmio_get_region(s, 0);
44
}
27
}
45
28
46
+static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
29
static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
47
+ const char *name, hwaddr size)
48
+{
49
+ ArmSbconI2CState *i2c = opaque;
50
+ SysBusDevice *s;
51
+
52
+ object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
53
+ s = SYS_BUS_DEVICE(i2c);
54
+ sysbus_realize(s, &error_fatal);
55
+ return sysbus_mmio_get_region(s, 0);
56
+}
57
+
58
static void mps2tz_common_init(MachineState *machine)
59
{
60
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
61
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
62
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
63
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
64
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
65
- { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
66
- { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
67
- { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
68
- { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
69
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
70
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
71
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
72
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
73
},
74
}, {
75
.name = "apb_ppcexp2",
76
--
30
--
77
2.20.1
31
2.25.1
78
79
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Message-id: 20200617072539.32686-11-f4bug@amsat.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-35-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/arm/mps2.c | 9 +++++++++
8
linux-user/aarch64/cpu_loop.c | 9 +++++++++
9
1 file changed, 9 insertions(+)
9
1 file changed, 9 insertions(+)
10
10
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
11
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
13
--- a/linux-user/aarch64/cpu_loop.c
14
+++ b/hw/arm/mps2.c
14
+++ b/linux-user/aarch64/cpu_loop.c
15
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
16
#include "hw/timer/cmsdk-apb-timer.h"
16
17
#include "hw/timer/cmsdk-apb-dualtimer.h"
17
switch (trapnr) {
18
#include "hw/misc/mps2-scc.h"
18
case EXCP_SWI:
19
+#include "hw/misc/mps2-fpgaio.h"
19
+ /*
20
#include "hw/net/lan9118.h"
20
+ * On syscall, PSTATE.ZA is preserved, along with the ZA matrix.
21
#include "net/net.h"
21
+ * PSTATE.SM is cleared, per SMSTOP, which does ResetSVEState.
22
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
22
+ */
23
23
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
24
typedef enum MPS2FPGAType {
24
+ env->svcr = FIELD_DP64(env->svcr, SVCR, SM, 0);
25
FPGA_AN385,
25
+ arm_rebuild_hflags(env);
26
@@ -XXX,XX +XXX,XX @@ typedef struct {
26
+ arm_reset_sve_state(env);
27
MemoryRegion sram;
27
+ }
28
/* FPGA APB subsystem */
28
ret = do_syscall(env,
29
MPS2SCC scc;
29
env->xregs[8],
30
+ MPS2FPGAIO fpgaio;
30
env->xregs[0],
31
/* CMSDK APB subsystem */
32
CMSDKAPBDualTimer dualtimer;
33
+ CMSDKAPBWatchdog watchdog;
34
} MPS2MachineState;
35
36
#define TYPE_MPS2_MACHINE "mps2"
37
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
38
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
39
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
40
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
41
+ object_initialize_child(OBJECT(mms), "fpgaio",
42
+ &mms->fpgaio, TYPE_MPS2_FPGAIO);
43
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
44
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
45
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
46
47
/* In hardware this is a LAN9220; the LAN9118 is software compatible
48
* except that it doesn't support the checksum-offload feature.
49
--
31
--
50
2.20.1
32
2.25.1
51
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Register the GPIO peripherals as unimplemented to better
3
Make sure to zero the currently reserved fields.
4
follow their accesses, for example booting Zephyr:
5
6
----------------
7
IN: arm_mps2_pinmux_init
8
0x00001160: f64f 0231 movw r2, #0xf831
9
0x00001164: 4b06 ldr r3, [pc, #0x18]
10
0x00001166: 2000 movs r0, #0
11
0x00001168: 619a str r2, [r3, #0x18]
12
0x0000116a: f24c 426f movw r2, #0xc46f
13
0x0000116e: f503 5380 add.w r3, r3, #0x1000
14
0x00001172: 619a str r2, [r3, #0x18]
15
0x00001174: f44f 529e mov.w r2, #0x13c0
16
0x00001178: f503 5380 add.w r3, r3, #0x1000
17
0x0000117c: 619a str r2, [r3, #0x18]
18
0x0000117e: 4770 bx lr
19
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xf831, offset 0x18)
20
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xc46f, offset 0x18)
21
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0x13c0, offset 0x18)
22
4
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20200617072539.32686-10-f4bug@amsat.org
7
Message-id: 20220708151540.18136-36-richard.henderson@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
9
---
28
hw/arm/mps2.c | 8 ++++++--
10
linux-user/aarch64/signal.c | 9 ++++++++-
29
1 file changed, 6 insertions(+), 2 deletions(-)
11
1 file changed, 8 insertions(+), 1 deletion(-)
30
12
31
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
32
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/mps2.c
15
--- a/linux-user/aarch64/signal.c
34
+++ b/hw/arm/mps2.c
16
+++ b/linux-user/aarch64/signal.c
35
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
17
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
36
MemoryRegion *system_memory = get_system_memory();
18
struct target_sve_context {
37
MachineClass *mc = MACHINE_GET_CLASS(machine);
19
struct target_aarch64_ctx head;
38
DeviceState *armv7m, *sccdev;
20
uint16_t vl;
39
+ int i;
21
- uint16_t reserved[3];
40
22
+ uint16_t flags;
41
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
23
+ uint16_t reserved[2];
42
error_report("This board can only be used with CPU %s",
24
/* The actual SVE data immediately follows. It is laid out
43
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
25
* according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
44
*/
26
* the original struct pointer.
45
Object *orgate;
27
@@ -XXX,XX +XXX,XX @@ struct target_sve_context {
46
DeviceState *orgate_dev;
28
#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
47
- int i;
29
(TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
48
30
49
orgate = object_new(TYPE_OR_IRQ);
31
+#define TARGET_SVE_SIG_FLAG_SM 1
50
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
32
+
51
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
33
struct target_rt_sigframe {
52
*/
34
struct target_siginfo info;
53
Object *orgate;
35
struct target_ucontext uc;
54
DeviceState *orgate_dev;
36
@@ -XXX,XX +XXX,XX @@ static void target_setup_sve_record(struct target_sve_context *sve,
55
- int i;
37
{
56
38
int i, j;
57
orgate = object_new(TYPE_OR_IRQ);
39
58
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
40
+ memset(sve, 0, sizeof(*sve));
59
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
41
__put_user(TARGET_SVE_MAGIC, &sve->head.magic);
60
default:
42
__put_user(size, &sve->head.size);
61
g_assert_not_reached();
43
__put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
62
}
44
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
63
+ for (i = 0; i < 4; i++) {
45
+ __put_user(TARGET_SVE_SIG_FLAG_SM, &sve->flags);
64
+ static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
65
+ 0x40012000, 0x40013000};
66
+ create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
67
+ }
46
+ }
68
47
69
/* CMSDK APB subsystem */
48
/* Note that SVE regs are stored as a byte stream, with each byte element
70
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
49
* at a subsequent address. This corresponds to a little-endian store
71
--
50
--
72
2.20.1
51
2.25.1
73
74
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use self-explicit definitions instead of magic values.
3
Fold the return value setting into the goto, so each
4
point of failure need not do both.
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200617072539.32686-4-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-37-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/i2c/versatile_i2c.c | 7 +++++--
11
linux-user/aarch64/signal.c | 26 +++++++++++---------------
11
1 file changed, 5 insertions(+), 2 deletions(-)
12
1 file changed, 11 insertions(+), 15 deletions(-)
12
13
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
14
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
16
--- a/linux-user/aarch64/signal.c
16
+++ b/hw/i2c/versatile_i2c.c
17
+++ b/linux-user/aarch64/signal.c
17
@@ -XXX,XX +XXX,XX @@ REG32(CONTROL_GET, 0)
18
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
18
REG32(CONTROL_SET, 0)
19
struct target_sve_context *sve = NULL;
19
REG32(CONTROL_CLR, 4)
20
uint64_t extra_datap = 0;
20
21
bool used_extra = false;
21
+#define SCL BIT(0)
22
- bool err = false;
22
+#define SDA BIT(1)
23
int vq = 0, sve_size = 0;
24
25
target_restore_general_frame(env, sf);
26
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
27
switch (magic) {
28
case 0:
29
if (size != 0) {
30
- err = true;
31
- goto exit;
32
+ goto err;
33
}
34
if (used_extra) {
35
ctx = NULL;
36
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
37
38
case TARGET_FPSIMD_MAGIC:
39
if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
40
- err = true;
41
- goto exit;
42
+ goto err;
43
}
44
fpsimd = (struct target_fpsimd_context *)ctx;
45
break;
46
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
47
break;
48
}
49
}
50
- err = true;
51
- goto exit;
52
+ goto err;
53
54
case TARGET_EXTRA_MAGIC:
55
if (extra || size != sizeof(struct target_extra_context)) {
56
- err = true;
57
- goto exit;
58
+ goto err;
59
}
60
__get_user(extra_datap,
61
&((struct target_extra_context *)ctx)->datap);
62
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
63
/* Unknown record -- we certainly didn't generate it.
64
* Did we in fact get out of sync?
65
*/
66
- err = true;
67
- goto exit;
68
+ goto err;
69
}
70
ctx = (void *)ctx + size;
71
}
72
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
73
if (fpsimd) {
74
target_restore_fpsimd_record(env, fpsimd);
75
} else {
76
- err = true;
77
+ goto err;
78
}
79
80
/* SVE data, if present, overwrites FPSIMD data. */
81
if (sve) {
82
target_restore_sve_record(env, sve, vq);
83
}
84
-
85
- exit:
86
unlock_user(extra, extra_datap, 0);
87
- return err;
88
+ return 0;
23
+
89
+
24
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
90
+ err:
25
unsigned size)
91
+ unlock_user(extra, extra_datap, 0);
26
{
92
+ return 1;
27
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
28
qemu_log_mask(LOG_GUEST_ERROR,
29
"%s: Bad offset 0x%x\n", __func__, (int)offset);
30
}
31
- bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
32
- s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
33
+ bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
34
+ s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
35
}
93
}
36
94
37
static const MemoryRegionOps versatile_i2c_ops = {
95
static abi_ulong get_sigframe(struct target_sigaction *ka,
38
--
96
--
39
2.20.1
97
2.25.1
40
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
In parse_user_sigframe, the kernel rejects duplicate sve records,
4
Message-id: 20200617072539.32686-7-f4bug@amsat.org
4
or records that are smaller than the header. We were silently
5
allowing these cases to pass, dropping the record.
6
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-38-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/arm/mps2.c | 5 ++++-
12
linux-user/aarch64/signal.c | 5 ++++-
9
1 file changed, 4 insertions(+), 1 deletion(-)
13
1 file changed, 4 insertions(+), 1 deletion(-)
10
14
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
17
--- a/linux-user/aarch64/signal.c
14
+++ b/hw/arm/mps2.c
18
+++ b/linux-user/aarch64/signal.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
16
MemoryRegion blockram_m2;
20
break;
17
MemoryRegion blockram_m3;
21
18
MemoryRegion sram;
22
case TARGET_SVE_MAGIC:
19
+ /* FPGA APB subsystem */
23
+ if (sve || size < sizeof(struct target_sve_context)) {
20
MPS2SCC scc;
24
+ goto err;
21
+ /* CMSDK APB subsystem */
25
+ }
22
CMSDKAPBDualTimer dualtimer;
26
if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
23
} MPS2MachineState;
27
vq = sve_vq(env);
24
28
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
25
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
29
- if (!sve && size == sve_size) {
26
g_assert_not_reached();
30
+ if (size == sve_size) {
27
}
31
sve = (struct target_sve_context *)ctx;
28
32
break;
29
+ /* CMSDK APB subsystem */
33
}
30
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
31
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
32
-
33
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
34
TYPE_CMSDK_APB_DUALTIMER);
35
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
36
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
37
qdev_get_gpio_in(armv7m, 10));
38
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
39
40
+ /* FPGA APB subsystem */
41
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
42
sccdev = DEVICE(&mms->scc);
43
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
44
--
34
--
45
2.20.1
35
2.25.1
46
47
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use self-explicit definitions instead of magic values.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200617072539.32686-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-39-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
hw/i2c/versatile_i2c.c | 14 ++++++++++----
8
linux-user/aarch64/signal.c | 3 +++
11
1 file changed, 10 insertions(+), 4 deletions(-)
9
1 file changed, 3 insertions(+)
12
10
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
11
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
13
--- a/linux-user/aarch64/signal.c
16
+++ b/hw/i2c/versatile_i2c.c
14
+++ b/linux-user/aarch64/signal.c
17
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
18
#include "qemu/osdep.h"
16
__get_user(extra_size,
19
#include "hw/sysbus.h"
17
&((struct target_extra_context *)ctx)->size);
20
#include "hw/i2c/bitbang_i2c.h"
18
extra = lock_user(VERIFY_READ, extra_datap, extra_size, 0);
21
+#include "hw/registerfields.h"
19
+ if (!extra) {
22
#include "qemu/log.h"
20
+ return 1;
23
#include "qemu/module.h"
21
+ }
24
22
break;
25
@@ -XXX,XX +XXX,XX @@ typedef struct VersatileI2CState {
23
26
int in;
24
default:
27
} VersatileI2CState;
28
29
+REG32(CONTROL_GET, 0)
30
+REG32(CONTROL_SET, 0)
31
+REG32(CONTROL_CLR, 4)
32
+
33
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
34
unsigned size)
35
{
36
VersatileI2CState *s = (VersatileI2CState *)opaque;
37
38
- if (offset == 0) {
39
+ switch (offset) {
40
+ case A_CONTROL_SET:
41
return (s->out & 1) | (s->in << 1);
42
- } else {
43
+ default:
44
qemu_log_mask(LOG_GUEST_ERROR,
45
"%s: Bad offset 0x%x\n", __func__, (int)offset);
46
return -1;
47
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
48
VersatileI2CState *s = (VersatileI2CState *)opaque;
49
50
switch (offset) {
51
- case 0:
52
+ case A_CONTROL_SET:
53
s->out |= value & 3;
54
break;
55
- case 4:
56
+ case A_CONTROL_CLR:
57
s->out &= ~value;
58
break;
59
default:
60
--
25
--
61
2.20.1
26
2.25.1
62
63
diff view generated by jsdifflib
1
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move the checks out of the parsing loop and into the
4
restore function. This more closely mirrors the code
5
structure in the kernel, and is slightly clearer.
6
7
Reject rather than silently skip incorrect VL and SVE record sizes,
8
bringing our checks in to line with those the kernel does.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220708151540.18136-40-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200616170844.13318-6-peter.maydell@linaro.org
6
---
14
---
7
target/arm/neon-dp.decode | 2 ++
15
linux-user/aarch64/signal.c | 51 +++++++++++++++++++++++++------------
8
target/arm/translate-neon.inc.c | 52 +++++++++++++++++++++++++++++++++
16
1 file changed, 35 insertions(+), 16 deletions(-)
9
target/arm/translate.c | 35 +---------------------
10
3 files changed, 55 insertions(+), 34 deletions(-)
11
17
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
20
--- a/linux-user/aarch64/signal.c
15
+++ b/target/arm/neon-dp.decode
21
+++ b/linux-user/aarch64/signal.c
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
17
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
23
}
18
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
24
}
19
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
25
20
+
26
-static void target_restore_sve_record(CPUARMState *env,
21
+ VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
27
- struct target_sve_context *sve, int vq)
22
]
28
+static bool target_restore_sve_record(CPUARMState *env,
23
29
+ struct target_sve_context *sve,
24
# Subgroup for size != 0b11
30
+ int size)
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
{
26
index XXXXXXX..XXXXXXX 100644
32
- int i, j;
27
--- a/target/arm/translate-neon.inc.c
33
+ int i, j, vl, vq;
28
+++ b/target/arm/translate-neon.inc.c
34
29
@@ -XXX,XX +XXX,XX @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
35
- /* Note that SVE regs are stored as a byte stream, with each byte element
30
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
36
+ if (!cpu_isar_feature(aa64_sve, env_archcpu(env))) {
31
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
32
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
33
+
34
+static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
35
+{
36
+ TCGv_i32 rm0, rm1;
37
+ TCGv_i64 rd;
38
+ static NeonGenWidenFn * const widenfns[] = {
39
+ gen_helper_neon_widen_u8,
40
+ gen_helper_neon_widen_u16,
41
+ tcg_gen_extu_i32_i64,
42
+ NULL,
43
+ };
44
+ NeonGenWidenFn *widenfn = widenfns[a->size];
45
+
46
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
+ return false;
37
+ return false;
48
+ }
38
+ }
49
+
39
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
40
+ __get_user(vl, &sve->vl);
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
41
+ vq = sve_vq(env);
52
+ ((a->vd | a->vm) & 0x10)) {
42
+
43
+ /* Reject mismatched VL. */
44
+ if (vl != vq * TARGET_SVE_VQ_BYTES) {
53
+ return false;
45
+ return false;
54
+ }
46
+ }
55
+
47
+
56
+ if (a->vd & 1) {
48
+ /* Accept empty record -- used to clear PSTATE.SM. */
49
+ if (size <= sizeof(*sve)) {
50
+ return true;
51
+ }
52
+
53
+ /* Reject non-empty but incomplete record. */
54
+ if (size < TARGET_SVE_SIG_CONTEXT_SIZE(vq)) {
57
+ return false;
55
+ return false;
58
+ }
56
+ }
59
+
57
+
60
+ if (!widenfn) {
58
+ /*
61
+ return false;
59
+ * Note that SVE regs are stored as a byte stream, with each byte element
62
+ }
60
* at a subsequent address. This corresponds to a little-endian load
63
+
61
* of our 64-bit hunks.
64
+ if (!vfp_access_check(s)) {
62
*/
65
+ return true;
63
@@ -XXX,XX +XXX,XX @@ static void target_restore_sve_record(CPUARMState *env,
66
+ }
64
}
67
+
65
}
68
+ rd = tcg_temp_new_i64();
66
}
69
+
70
+ rm0 = neon_load_reg(a->vm, 0);
71
+ rm1 = neon_load_reg(a->vm, 1);
72
+
73
+ widenfn(rd, rm0);
74
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
75
+ neon_store_reg64(rd, a->vd);
76
+ widenfn(rd, rm1);
77
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
78
+ neon_store_reg64(rd, a->vd + 1);
79
+
80
+ tcg_temp_free_i64(rd);
81
+ tcg_temp_free_i32(rm0);
82
+ tcg_temp_free_i32(rm1);
83
+ return true;
67
+ return true;
84
+}
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
90
tcg_temp_free_i32(rd);
91
}
68
}
92
69
93
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
70
static int target_restore_sigframe(CPUARMState *env,
94
-{
71
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
95
- if (u) {
72
struct target_sve_context *sve = NULL;
96
- switch (size) {
73
uint64_t extra_datap = 0;
97
- case 0: gen_helper_neon_widen_u8(dest, src); break;
74
bool used_extra = false;
98
- case 1: gen_helper_neon_widen_u16(dest, src); break;
75
- int vq = 0, sve_size = 0;
99
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
76
+ int sve_size = 0;
100
- default: abort();
77
101
- }
78
target_restore_general_frame(env, sf);
102
- } else {
79
103
- switch (size) {
80
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
104
- case 0: gen_helper_neon_widen_s8(dest, src); break;
81
if (sve || size < sizeof(struct target_sve_context)) {
105
- case 1: gen_helper_neon_widen_s16(dest, src); break;
82
goto err;
106
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
83
}
107
- default: abort();
84
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
108
- }
85
- vq = sve_vq(env);
109
- }
86
- sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
110
- tcg_temp_free_i32(src);
87
- if (size == sve_size) {
111
-}
88
- sve = (struct target_sve_context *)ctx;
112
-
113
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
114
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
115
* table A7-13.
116
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
case NEON_2RM_VUZP:
118
case NEON_2RM_VZIP:
119
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
120
+ case NEON_2RM_VSHLL:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
goto elementwise;
126
}
127
break;
128
- case NEON_2RM_VSHLL:
129
- if (q || (rd & 1)) {
130
- return 1;
131
- }
132
- tmp = neon_load_reg(rm, 0);
133
- tmp2 = neon_load_reg(rm, 1);
134
- for (pass = 0; pass < 2; pass++) {
135
- if (pass == 1)
136
- tmp = tmp2;
137
- gen_neon_widen(cpu_V0, tmp, size, 1);
138
- tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
139
- neon_store_reg64(cpu_V0, rd + pass);
140
- }
141
- break;
89
- break;
142
case NEON_2RM_VCVT_F16_F32:
90
- }
143
{
91
- }
144
TCGv_ptr fpst;
92
- goto err;
93
+ sve = (struct target_sve_context *)ctx;
94
+ sve_size = size;
95
+ break;
96
97
case TARGET_EXTRA_MAGIC:
98
if (extra || size != sizeof(struct target_extra_context)) {
99
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
100
}
101
102
/* SVE data, if present, overwrites FPSIMD data. */
103
- if (sve) {
104
- target_restore_sve_record(env, sve, vq);
105
+ if (sve && !target_restore_sve_record(env, sve, sve_size)) {
106
+ goto err;
107
}
108
unlock_user(extra, extra_datap, 0);
109
return 0;
145
--
110
--
146
2.20.1
111
2.25.1
147
148
diff view generated by jsdifflib
1
Convert the Neon VTRN insn to decodetree. This is the last insn in the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Neon data-processing group, so we can remove all the now-unused old
3
decoder framework.
4
2
5
It's possible that there's a more efficient implementation of
3
Set the SM bit in the SVE record on signal delivery, create the ZA record.
6
VTRN, but for this conversion we just copy the existing approach.
4
Restore SM and ZA state according to the records present on return.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-41-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org
11
---
10
---
12
target/arm/neon-dp.decode | 2 +-
11
linux-user/aarch64/signal.c | 167 +++++++++++++++++++++++++++++++++---
13
target/arm/translate-neon.inc.c | 90 ++++++++
12
1 file changed, 154 insertions(+), 13 deletions(-)
14
target/arm/translate.c | 363 +-------------------------------
15
3 files changed, 93 insertions(+), 362 deletions(-)
16
13
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
16
--- a/linux-user/aarch64/signal.c
20
+++ b/target/arm/neon-dp.decode
17
+++ b/linux-user/aarch64/signal.c
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
@@ -XXX,XX +XXX,XX @@ struct target_sve_context {
22
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
19
23
20
#define TARGET_SVE_SIG_FLAG_SM 1
24
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
21
25
-
22
+#define TARGET_ZA_MAGIC 0x54366345
26
+ VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
23
+
27
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
24
+struct target_za_context {
28
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
25
+ struct target_aarch64_ctx head;
29
26
+ uint16_t vl;
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
+ uint16_t reserved[3];
31
index XXXXXXX..XXXXXXX 100644
28
+ /* The actual ZA data immediately follows. */
32
--- a/target/arm/translate-neon.inc.c
29
+};
33
+++ b/target/arm/translate-neon.inc.c
30
+
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
31
+#define TARGET_ZA_SIG_REGS_OFFSET \
35
32
+ QEMU_ALIGN_UP(sizeof(struct target_za_context), TARGET_SVE_VQ_BYTES)
33
+#define TARGET_ZA_SIG_ZAV_OFFSET(VQ, N) \
34
+ (TARGET_ZA_SIG_REGS_OFFSET + (VQ) * TARGET_SVE_VQ_BYTES * (N))
35
+#define TARGET_ZA_SIG_CONTEXT_SIZE(VQ) \
36
+ TARGET_ZA_SIG_ZAV_OFFSET(VQ, VQ * TARGET_SVE_VQ_BYTES)
37
+
38
struct target_rt_sigframe {
39
struct target_siginfo info;
40
struct target_ucontext uc;
41
@@ -XXX,XX +XXX,XX @@ static void target_setup_end_record(struct target_aarch64_ctx *end)
42
}
43
44
static void target_setup_sve_record(struct target_sve_context *sve,
45
- CPUARMState *env, int vq, int size)
46
+ CPUARMState *env, int size)
47
{
48
- int i, j;
49
+ int i, j, vq = sve_vq(env);
50
51
memset(sve, 0, sizeof(*sve));
52
__put_user(TARGET_SVE_MAGIC, &sve->head.magic);
53
@@ -XXX,XX +XXX,XX @@ static void target_setup_sve_record(struct target_sve_context *sve,
54
}
55
}
56
57
+static void target_setup_za_record(struct target_za_context *za,
58
+ CPUARMState *env, int size)
59
+{
60
+ int vq = sme_vq(env);
61
+ int vl = vq * TARGET_SVE_VQ_BYTES;
62
+ int i, j;
63
+
64
+ memset(za, 0, sizeof(*za));
65
+ __put_user(TARGET_ZA_MAGIC, &za->head.magic);
66
+ __put_user(size, &za->head.size);
67
+ __put_user(vl, &za->vl);
68
+
69
+ if (size == TARGET_ZA_SIG_CONTEXT_SIZE(0)) {
70
+ return;
71
+ }
72
+ assert(size == TARGET_ZA_SIG_CONTEXT_SIZE(vq));
73
+
74
+ /*
75
+ * Note that ZA vectors are stored as a byte stream,
76
+ * with each byte element at a subsequent address.
77
+ */
78
+ for (i = 0; i < vl; ++i) {
79
+ uint64_t *z = (void *)za + TARGET_ZA_SIG_ZAV_OFFSET(vq, i);
80
+ for (j = 0; j < vq * 2; ++j) {
81
+ __put_user_e(env->zarray[i].d[j], z + j, le);
82
+ }
83
+ }
84
+}
85
+
86
static void target_restore_general_frame(CPUARMState *env,
87
struct target_rt_sigframe *sf)
88
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
90
91
static bool target_restore_sve_record(CPUARMState *env,
92
struct target_sve_context *sve,
93
- int size)
94
+ int size, int *svcr)
95
{
96
- int i, j, vl, vq;
97
+ int i, j, vl, vq, flags;
98
+ bool sm;
99
100
- if (!cpu_isar_feature(aa64_sve, env_archcpu(env))) {
101
+ __get_user(vl, &sve->vl);
102
+ __get_user(flags, &sve->flags);
103
+
104
+ sm = flags & TARGET_SVE_SIG_FLAG_SM;
105
+
106
+ /* The cpu must support Streaming or Non-streaming SVE. */
107
+ if (sm
108
+ ? !cpu_isar_feature(aa64_sme, env_archcpu(env))
109
+ : !cpu_isar_feature(aa64_sve, env_archcpu(env))) {
110
return false;
111
}
112
113
- __get_user(vl, &sve->vl);
114
- vq = sve_vq(env);
115
+ /*
116
+ * Note that we cannot use sve_vq() because that depends on the
117
+ * current setting of PSTATE.SM, not the state to be restored.
118
+ */
119
+ vq = sve_vqm1_for_el_sm(env, 0, sm) + 1;
120
121
/* Reject mismatched VL. */
122
if (vl != vq * TARGET_SVE_VQ_BYTES) {
123
@@ -XXX,XX +XXX,XX @@ static bool target_restore_sve_record(CPUARMState *env,
124
return false;
125
}
126
127
+ *svcr = FIELD_DP64(*svcr, SVCR, SM, sm);
128
+
129
/*
130
* Note that SVE regs are stored as a byte stream, with each byte element
131
* at a subsequent address. This corresponds to a little-endian load
132
@@ -XXX,XX +XXX,XX @@ static bool target_restore_sve_record(CPUARMState *env,
36
return true;
133
return true;
37
}
134
}
38
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
135
136
+static bool target_restore_za_record(CPUARMState *env,
137
+ struct target_za_context *za,
138
+ int size, int *svcr)
39
+{
139
+{
40
+ TCGv_i32 rd, tmp;
140
+ int i, j, vl, vq;
41
+
141
+
42
+ rd = tcg_temp_new_i32();
142
+ if (!cpu_isar_feature(aa64_sme, env_archcpu(env))) {
43
+ tmp = tcg_temp_new_i32();
44
+
45
+ tcg_gen_shli_i32(rd, t0, 8);
46
+ tcg_gen_andi_i32(rd, rd, 0xff00ff00);
47
+ tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
48
+ tcg_gen_or_i32(rd, rd, tmp);
49
+
50
+ tcg_gen_shri_i32(t1, t1, 8);
51
+ tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
52
+ tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
53
+ tcg_gen_or_i32(t1, t1, tmp);
54
+ tcg_gen_mov_i32(t0, rd);
55
+
56
+ tcg_temp_free_i32(tmp);
57
+ tcg_temp_free_i32(rd);
58
+}
59
+
60
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
61
+{
62
+ TCGv_i32 rd, tmp;
63
+
64
+ rd = tcg_temp_new_i32();
65
+ tmp = tcg_temp_new_i32();
66
+
67
+ tcg_gen_shli_i32(rd, t0, 16);
68
+ tcg_gen_andi_i32(tmp, t1, 0xffff);
69
+ tcg_gen_or_i32(rd, rd, tmp);
70
+ tcg_gen_shri_i32(t1, t1, 16);
71
+ tcg_gen_andi_i32(tmp, t0, 0xffff0000);
72
+ tcg_gen_or_i32(t1, t1, tmp);
73
+ tcg_gen_mov_i32(t0, rd);
74
+
75
+ tcg_temp_free_i32(tmp);
76
+ tcg_temp_free_i32(rd);
77
+}
78
+
79
+static bool trans_VTRN(DisasContext *s, arg_2misc *a)
80
+{
81
+ TCGv_i32 tmp, tmp2;
82
+ int pass;
83
+
84
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
85
+ return false;
143
+ return false;
86
+ }
144
+ }
87
+
145
+
88
+ /* UNDEF accesses to D16-D31 if they don't exist. */
146
+ __get_user(vl, &za->vl);
89
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
147
+ vq = sme_vq(env);
90
+ ((a->vd | a->vm) & 0x10)) {
148
+
149
+ /* Reject mismatched VL. */
150
+ if (vl != vq * TARGET_SVE_VQ_BYTES) {
91
+ return false;
151
+ return false;
92
+ }
152
+ }
93
+
153
+
94
+ if ((a->vd | a->vm) & a->q) {
154
+ /* Accept empty record -- used to clear PSTATE.ZA. */
155
+ if (size <= TARGET_ZA_SIG_CONTEXT_SIZE(0)) {
156
+ return true;
157
+ }
158
+
159
+ /* Reject non-empty but incomplete record. */
160
+ if (size < TARGET_ZA_SIG_CONTEXT_SIZE(vq)) {
95
+ return false;
161
+ return false;
96
+ }
162
+ }
97
+
163
+
98
+ if (a->size == 3) {
164
+ *svcr = FIELD_DP64(*svcr, SVCR, ZA, 1);
99
+ return false;
165
+
100
+ }
166
+ for (i = 0; i < vl; ++i) {
101
+
167
+ uint64_t *z = (void *)za + TARGET_ZA_SIG_ZAV_OFFSET(vq, i);
102
+ if (!vfp_access_check(s)) {
168
+ for (j = 0; j < vq * 2; ++j) {
103
+ return true;
169
+ __get_user_e(env->zarray[i].d[j], z + j, le);
104
+ }
105
+
106
+ if (a->size == 2) {
107
+ for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
108
+ tmp = neon_load_reg(a->vm, pass);
109
+ tmp2 = neon_load_reg(a->vd, pass + 1);
110
+ neon_store_reg(a->vm, pass, tmp2);
111
+ neon_store_reg(a->vd, pass + 1, tmp);
112
+ }
113
+ } else {
114
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
115
+ tmp = neon_load_reg(a->vm, pass);
116
+ tmp2 = neon_load_reg(a->vd, pass);
117
+ if (a->size == 0) {
118
+ gen_neon_trn_u8(tmp, tmp2);
119
+ } else {
120
+ gen_neon_trn_u16(tmp, tmp2);
121
+ }
122
+ neon_store_reg(a->vm, pass, tmp2);
123
+ neon_store_reg(a->vd, pass, tmp);
124
+ }
170
+ }
125
+ }
171
+ }
126
+ return true;
172
+ return true;
127
+}
173
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
174
+
129
index XXXXXXX..XXXXXXX 100644
175
static int target_restore_sigframe(CPUARMState *env,
130
--- a/target/arm/translate.c
176
struct target_rt_sigframe *sf)
131
+++ b/target/arm/translate.c
177
{
132
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
178
struct target_aarch64_ctx *ctx, *extra = NULL;
133
gen_rfe(s, pc, load_cpu_field(spsr));
179
struct target_fpsimd_context *fpsimd = NULL;
134
}
180
struct target_sve_context *sve = NULL;
135
181
+ struct target_za_context *za = NULL;
136
-static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
182
uint64_t extra_datap = 0;
137
-{
183
bool used_extra = false;
138
- TCGv_i32 rd, tmp;
184
int sve_size = 0;
139
-
185
+ int za_size = 0;
140
- rd = tcg_temp_new_i32();
186
+ int svcr = 0;
141
- tmp = tcg_temp_new_i32();
187
142
-
188
target_restore_general_frame(env, sf);
143
- tcg_gen_shli_i32(rd, t0, 8);
189
144
- tcg_gen_andi_i32(rd, rd, 0xff00ff00);
190
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
145
- tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
191
sve_size = size;
146
- tcg_gen_or_i32(rd, rd, tmp);
147
-
148
- tcg_gen_shri_i32(t1, t1, 8);
149
- tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
150
- tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
151
- tcg_gen_or_i32(t1, t1, tmp);
152
- tcg_gen_mov_i32(t0, rd);
153
-
154
- tcg_temp_free_i32(tmp);
155
- tcg_temp_free_i32(rd);
156
-}
157
-
158
-static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
159
-{
160
- TCGv_i32 rd, tmp;
161
-
162
- rd = tcg_temp_new_i32();
163
- tmp = tcg_temp_new_i32();
164
-
165
- tcg_gen_shli_i32(rd, t0, 16);
166
- tcg_gen_andi_i32(tmp, t1, 0xffff);
167
- tcg_gen_or_i32(rd, rd, tmp);
168
- tcg_gen_shri_i32(t1, t1, 16);
169
- tcg_gen_andi_i32(tmp, t0, 0xffff0000);
170
- tcg_gen_or_i32(t1, t1, tmp);
171
- tcg_gen_mov_i32(t0, rd);
172
-
173
- tcg_temp_free_i32(tmp);
174
- tcg_temp_free_i32(rd);
175
-}
176
-
177
-/* Symbolic constants for op fields for Neon 2-register miscellaneous.
178
- * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
179
- * table A7-13.
180
- */
181
-#define NEON_2RM_VREV64 0
182
-#define NEON_2RM_VREV32 1
183
-#define NEON_2RM_VREV16 2
184
-#define NEON_2RM_VPADDL 4
185
-#define NEON_2RM_VPADDL_U 5
186
-#define NEON_2RM_AESE 6 /* Includes AESD */
187
-#define NEON_2RM_AESMC 7 /* Includes AESIMC */
188
-#define NEON_2RM_VCLS 8
189
-#define NEON_2RM_VCLZ 9
190
-#define NEON_2RM_VCNT 10
191
-#define NEON_2RM_VMVN 11
192
-#define NEON_2RM_VPADAL 12
193
-#define NEON_2RM_VPADAL_U 13
194
-#define NEON_2RM_VQABS 14
195
-#define NEON_2RM_VQNEG 15
196
-#define NEON_2RM_VCGT0 16
197
-#define NEON_2RM_VCGE0 17
198
-#define NEON_2RM_VCEQ0 18
199
-#define NEON_2RM_VCLE0 19
200
-#define NEON_2RM_VCLT0 20
201
-#define NEON_2RM_SHA1H 21
202
-#define NEON_2RM_VABS 22
203
-#define NEON_2RM_VNEG 23
204
-#define NEON_2RM_VCGT0_F 24
205
-#define NEON_2RM_VCGE0_F 25
206
-#define NEON_2RM_VCEQ0_F 26
207
-#define NEON_2RM_VCLE0_F 27
208
-#define NEON_2RM_VCLT0_F 28
209
-#define NEON_2RM_VABS_F 30
210
-#define NEON_2RM_VNEG_F 31
211
-#define NEON_2RM_VSWP 32
212
-#define NEON_2RM_VTRN 33
213
-#define NEON_2RM_VUZP 34
214
-#define NEON_2RM_VZIP 35
215
-#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
216
-#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
217
-#define NEON_2RM_VSHLL 38
218
-#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
219
-#define NEON_2RM_VRINTN 40
220
-#define NEON_2RM_VRINTX 41
221
-#define NEON_2RM_VRINTA 42
222
-#define NEON_2RM_VRINTZ 43
223
-#define NEON_2RM_VCVT_F16_F32 44
224
-#define NEON_2RM_VRINTM 45
225
-#define NEON_2RM_VCVT_F32_F16 46
226
-#define NEON_2RM_VRINTP 47
227
-#define NEON_2RM_VCVTAU 48
228
-#define NEON_2RM_VCVTAS 49
229
-#define NEON_2RM_VCVTNU 50
230
-#define NEON_2RM_VCVTNS 51
231
-#define NEON_2RM_VCVTPU 52
232
-#define NEON_2RM_VCVTPS 53
233
-#define NEON_2RM_VCVTMU 54
234
-#define NEON_2RM_VCVTMS 55
235
-#define NEON_2RM_VRECPE 56
236
-#define NEON_2RM_VRSQRTE 57
237
-#define NEON_2RM_VRECPE_F 58
238
-#define NEON_2RM_VRSQRTE_F 59
239
-#define NEON_2RM_VCVT_FS 60
240
-#define NEON_2RM_VCVT_FU 61
241
-#define NEON_2RM_VCVT_SF 62
242
-#define NEON_2RM_VCVT_UF 63
243
-
244
-/* Each entry in this array has bit n set if the insn allows
245
- * size value n (otherwise it will UNDEF). Since unallocated
246
- * op values will have no bits set they always UNDEF.
247
- */
248
-static const uint8_t neon_2rm_sizes[] = {
249
- [NEON_2RM_VREV64] = 0x7,
250
- [NEON_2RM_VREV32] = 0x3,
251
- [NEON_2RM_VREV16] = 0x1,
252
- [NEON_2RM_VPADDL] = 0x7,
253
- [NEON_2RM_VPADDL_U] = 0x7,
254
- [NEON_2RM_AESE] = 0x1,
255
- [NEON_2RM_AESMC] = 0x1,
256
- [NEON_2RM_VCLS] = 0x7,
257
- [NEON_2RM_VCLZ] = 0x7,
258
- [NEON_2RM_VCNT] = 0x1,
259
- [NEON_2RM_VMVN] = 0x1,
260
- [NEON_2RM_VPADAL] = 0x7,
261
- [NEON_2RM_VPADAL_U] = 0x7,
262
- [NEON_2RM_VQABS] = 0x7,
263
- [NEON_2RM_VQNEG] = 0x7,
264
- [NEON_2RM_VCGT0] = 0x7,
265
- [NEON_2RM_VCGE0] = 0x7,
266
- [NEON_2RM_VCEQ0] = 0x7,
267
- [NEON_2RM_VCLE0] = 0x7,
268
- [NEON_2RM_VCLT0] = 0x7,
269
- [NEON_2RM_SHA1H] = 0x4,
270
- [NEON_2RM_VABS] = 0x7,
271
- [NEON_2RM_VNEG] = 0x7,
272
- [NEON_2RM_VCGT0_F] = 0x4,
273
- [NEON_2RM_VCGE0_F] = 0x4,
274
- [NEON_2RM_VCEQ0_F] = 0x4,
275
- [NEON_2RM_VCLE0_F] = 0x4,
276
- [NEON_2RM_VCLT0_F] = 0x4,
277
- [NEON_2RM_VABS_F] = 0x4,
278
- [NEON_2RM_VNEG_F] = 0x4,
279
- [NEON_2RM_VSWP] = 0x1,
280
- [NEON_2RM_VTRN] = 0x7,
281
- [NEON_2RM_VUZP] = 0x7,
282
- [NEON_2RM_VZIP] = 0x7,
283
- [NEON_2RM_VMOVN] = 0x7,
284
- [NEON_2RM_VQMOVN] = 0x7,
285
- [NEON_2RM_VSHLL] = 0x7,
286
- [NEON_2RM_SHA1SU1] = 0x4,
287
- [NEON_2RM_VRINTN] = 0x4,
288
- [NEON_2RM_VRINTX] = 0x4,
289
- [NEON_2RM_VRINTA] = 0x4,
290
- [NEON_2RM_VRINTZ] = 0x4,
291
- [NEON_2RM_VCVT_F16_F32] = 0x2,
292
- [NEON_2RM_VRINTM] = 0x4,
293
- [NEON_2RM_VCVT_F32_F16] = 0x2,
294
- [NEON_2RM_VRINTP] = 0x4,
295
- [NEON_2RM_VCVTAU] = 0x4,
296
- [NEON_2RM_VCVTAS] = 0x4,
297
- [NEON_2RM_VCVTNU] = 0x4,
298
- [NEON_2RM_VCVTNS] = 0x4,
299
- [NEON_2RM_VCVTPU] = 0x4,
300
- [NEON_2RM_VCVTPS] = 0x4,
301
- [NEON_2RM_VCVTMU] = 0x4,
302
- [NEON_2RM_VCVTMS] = 0x4,
303
- [NEON_2RM_VRECPE] = 0x4,
304
- [NEON_2RM_VRSQRTE] = 0x4,
305
- [NEON_2RM_VRECPE_F] = 0x4,
306
- [NEON_2RM_VRSQRTE_F] = 0x4,
307
- [NEON_2RM_VCVT_FS] = 0x4,
308
- [NEON_2RM_VCVT_FU] = 0x4,
309
- [NEON_2RM_VCVT_SF] = 0x4,
310
- [NEON_2RM_VCVT_UF] = 0x4,
311
-};
312
-
313
static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
314
uint32_t opr_sz, uint32_t max_sz,
315
gen_helper_gvec_3_ptr *fn)
316
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
317
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
318
}
319
320
-/* Translate a NEON data processing instruction. Return nonzero if the
321
- instruction is invalid.
322
- We process data in a mixture of 32-bit and 64-bit chunks.
323
- Mostly we use 32-bit chunks so we can use normal scalar instructions. */
324
-
325
-static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
326
-{
327
- int op;
328
- int q;
329
- int rd, rm;
330
- int size;
331
- int pass;
332
- int u;
333
- TCGv_i32 tmp, tmp2;
334
-
335
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
336
- return 1;
337
- }
338
-
339
- /* FIXME: this access check should not take precedence over UNDEF
340
- * for invalid encodings; we will generate incorrect syndrome information
341
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
342
- */
343
- if (s->fp_excp_el) {
344
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
345
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
346
- return 0;
347
- }
348
-
349
- if (!s->vfp_enabled)
350
- return 1;
351
- q = (insn & (1 << 6)) != 0;
352
- u = (insn >> 24) & 1;
353
- VFP_DREG_D(rd, insn);
354
- VFP_DREG_M(rm, insn);
355
- size = (insn >> 20) & 3;
356
-
357
- if ((insn & (1 << 23)) == 0) {
358
- /* Three register same length: handled by decodetree */
359
- return 1;
360
- } else if (insn & (1 << 4)) {
361
- /* Two registers and shift or reg and imm: handled by decodetree */
362
- return 1;
363
- } else { /* (insn & 0x00800010 == 0x00800000) */
364
- if (size != 3) {
365
- /*
366
- * Three registers of different lengths, or two registers and
367
- * a scalar: handled by decodetree
368
- */
369
- return 1;
370
- } else { /* size == 3 */
371
- if (!u) {
372
- /* Extract: handled by decodetree */
373
- return 1;
374
- } else if ((insn & (1 << 11)) == 0) {
375
- /* Two register misc. */
376
- op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
377
- size = (insn >> 18) & 3;
378
- /* UNDEF for unknown op values and bad op-size combinations */
379
- if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
380
- return 1;
381
- }
382
- if (q && ((rm | rd) & 1)) {
383
- return 1;
384
- }
385
- switch (op) {
386
- case NEON_2RM_VREV64:
387
- case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
388
- case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
389
- case NEON_2RM_VUZP:
390
- case NEON_2RM_VZIP:
391
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
392
- case NEON_2RM_VSHLL:
393
- case NEON_2RM_VCVT_F16_F32:
394
- case NEON_2RM_VCVT_F32_F16:
395
- case NEON_2RM_VMVN:
396
- case NEON_2RM_VNEG:
397
- case NEON_2RM_VABS:
398
- case NEON_2RM_VCEQ0:
399
- case NEON_2RM_VCGT0:
400
- case NEON_2RM_VCLE0:
401
- case NEON_2RM_VCGE0:
402
- case NEON_2RM_VCLT0:
403
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
404
- case NEON_2RM_SHA1H:
405
- case NEON_2RM_SHA1SU1:
406
- case NEON_2RM_VREV32:
407
- case NEON_2RM_VREV16:
408
- case NEON_2RM_VCLS:
409
- case NEON_2RM_VCLZ:
410
- case NEON_2RM_VCNT:
411
- case NEON_2RM_VABS_F:
412
- case NEON_2RM_VNEG_F:
413
- case NEON_2RM_VRECPE:
414
- case NEON_2RM_VRSQRTE:
415
- case NEON_2RM_VQABS:
416
- case NEON_2RM_VQNEG:
417
- case NEON_2RM_VRECPE_F:
418
- case NEON_2RM_VRSQRTE_F:
419
- case NEON_2RM_VCVT_FS:
420
- case NEON_2RM_VCVT_FU:
421
- case NEON_2RM_VCVT_SF:
422
- case NEON_2RM_VCVT_UF:
423
- case NEON_2RM_VRINTX:
424
- case NEON_2RM_VCGT0_F:
425
- case NEON_2RM_VCGE0_F:
426
- case NEON_2RM_VCEQ0_F:
427
- case NEON_2RM_VCLE0_F:
428
- case NEON_2RM_VCLT0_F:
429
- case NEON_2RM_VRINTN:
430
- case NEON_2RM_VRINTA:
431
- case NEON_2RM_VRINTM:
432
- case NEON_2RM_VRINTP:
433
- case NEON_2RM_VRINTZ:
434
- case NEON_2RM_VCVTAU:
435
- case NEON_2RM_VCVTAS:
436
- case NEON_2RM_VCVTNU:
437
- case NEON_2RM_VCVTNS:
438
- case NEON_2RM_VCVTPU:
439
- case NEON_2RM_VCVTPS:
440
- case NEON_2RM_VCVTMU:
441
- case NEON_2RM_VCVTMS:
442
- case NEON_2RM_VSWP:
443
- /* handled by decodetree */
444
- return 1;
445
- case NEON_2RM_VTRN:
446
- if (size == 2) {
447
- int n;
448
- for (n = 0; n < (q ? 4 : 2); n += 2) {
449
- tmp = neon_load_reg(rm, n);
450
- tmp2 = neon_load_reg(rd, n + 1);
451
- neon_store_reg(rm, n, tmp2);
452
- neon_store_reg(rd, n + 1, tmp);
453
- }
454
- } else {
455
- goto elementwise;
456
- }
457
- break;
458
-
459
- default:
460
- elementwise:
461
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
462
- tmp = neon_load_reg(rm, pass);
463
- switch (op) {
464
- case NEON_2RM_VTRN:
465
- tmp2 = neon_load_reg(rd, pass);
466
- switch (size) {
467
- case 0: gen_neon_trn_u8(tmp, tmp2); break;
468
- case 1: gen_neon_trn_u16(tmp, tmp2); break;
469
- default: abort();
470
- }
471
- neon_store_reg(rm, pass, tmp2);
472
- break;
473
- default:
474
- /* Reserved op values were caught by the
475
- * neon_2rm_sizes[] check earlier.
476
- */
477
- abort();
478
- }
479
- neon_store_reg(rd, pass, tmp);
480
- }
481
- break;
482
- }
483
- } else {
484
- /* VTBL, VTBX, VDUP: handled by decodetree */
485
- return 1;
486
- }
487
- }
488
- }
489
- return 0;
490
-}
491
-
492
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
493
{
494
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
495
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
496
}
497
/* fall back to legacy decoder */
498
499
- if (((insn >> 25) & 7) == 1) {
500
- /* NEON Data processing. */
501
- if (disas_neon_data_insn(s, insn)) {
502
- goto illegal_op;
503
- }
504
- return;
505
- }
506
if ((insn & 0x0e000f00) == 0x0c000100) {
507
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
508
/* iWMMXt register transfer. */
509
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
510
break;
192
break;
511
}
193
512
if (((insn >> 24) & 3) == 3) {
194
+ case TARGET_ZA_MAGIC:
513
- /* Translate into the equivalent ARM encoding. */
195
+ if (za || size < sizeof(struct target_za_context)) {
514
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
196
+ goto err;
515
- if (disas_neon_data_insn(s, insn)) {
197
+ }
516
- goto illegal_op;
198
+ za = (struct target_za_context *)ctx;
517
- }
199
+ za_size = size;
518
+ /* Neon DP, but failed disas_neon_dp() */
200
+ break;
519
+ goto illegal_op;
201
+
520
} else if (((insn >> 8) & 0xe) == 10) {
202
case TARGET_EXTRA_MAGIC:
521
/* VFP, but failed disas_vfp. */
203
if (extra || size != sizeof(struct target_extra_context)) {
522
goto illegal_op;
204
goto err;
205
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
206
}
207
208
/* SVE data, if present, overwrites FPSIMD data. */
209
- if (sve && !target_restore_sve_record(env, sve, sve_size)) {
210
+ if (sve && !target_restore_sve_record(env, sve, sve_size, &svcr)) {
211
goto err;
212
}
213
+ if (za && !target_restore_za_record(env, za, za_size, &svcr)) {
214
+ goto err;
215
+ }
216
+ if (env->svcr != svcr) {
217
+ env->svcr = svcr;
218
+ arm_rebuild_hflags(env);
219
+ }
220
unlock_user(extra, extra_datap, 0);
221
return 0;
222
223
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
224
.total_size = offsetof(struct target_rt_sigframe,
225
uc.tuc_mcontext.__reserved),
226
};
227
- int fpsimd_ofs, fr_ofs, sve_ofs = 0, vq = 0, sve_size = 0;
228
+ int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0;
229
+ int sve_size = 0, za_size = 0;
230
struct target_rt_sigframe *frame;
231
struct target_rt_frame_record *fr;
232
abi_ulong frame_addr, return_addr;
233
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
234
&layout);
235
236
/* SVE state needs saving only if it exists. */
237
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
238
- vq = sve_vq(env);
239
- sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
240
+ if (cpu_isar_feature(aa64_sve, env_archcpu(env)) ||
241
+ cpu_isar_feature(aa64_sme, env_archcpu(env))) {
242
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(sve_vq(env)), 16);
243
sve_ofs = alloc_sigframe_space(sve_size, &layout);
244
}
245
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
246
+ /* ZA state needs saving only if it is enabled. */
247
+ if (FIELD_EX64(env->svcr, SVCR, ZA)) {
248
+ za_size = TARGET_ZA_SIG_CONTEXT_SIZE(sme_vq(env));
249
+ } else {
250
+ za_size = TARGET_ZA_SIG_CONTEXT_SIZE(0);
251
+ }
252
+ za_ofs = alloc_sigframe_space(za_size, &layout);
253
+ }
254
255
if (layout.extra_ofs) {
256
/* Reserve space for the extra end marker. The standard end marker
257
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
258
target_setup_end_record((void *)frame + layout.extra_end_ofs);
259
}
260
if (sve_ofs) {
261
- target_setup_sve_record((void *)frame + sve_ofs, env, vq, sve_size);
262
+ target_setup_sve_record((void *)frame + sve_ofs, env, sve_size);
263
+ }
264
+ if (za_ofs) {
265
+ target_setup_za_record((void *)frame + za_ofs, env, za_size);
266
}
267
268
/* Set up the stack frame for unwinding. */
269
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
270
env->btype = 2;
271
}
272
273
+ /*
274
+ * Invoke the signal handler with both SM and ZA disabled.
275
+ * When clearing SM, ResetSVEState, per SMSTOP.
276
+ */
277
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
278
+ arm_reset_sve_state(env);
279
+ }
280
+ if (env->svcr) {
281
+ env->svcr = 0;
282
+ arm_rebuild_hflags(env);
283
+ }
284
+
285
if (info) {
286
tswap_siginfo(&frame->info, info);
287
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
523
--
288
--
524
2.20.1
289
2.25.1
525
526
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add a trace event to see when a guest disable/enable the watchdog.
3
Add "sve" to the sve prctl functions, to distinguish
4
them from the coming "sme" prctls with similar names.
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200617072539.32686-2-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-42-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
11
linux-user/aarch64/target_prctl.h | 8 ++++----
11
hw/watchdog/trace-events | 1 +
12
linux-user/syscall.c | 12 ++++++------
12
2 files changed, 2 insertions(+)
13
2 files changed, 10 insertions(+), 10 deletions(-)
13
14
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
15
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
17
--- a/linux-user/aarch64/target_prctl.h
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
18
+++ b/linux-user/aarch64/target_prctl.h
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
19
@@ -XXX,XX +XXX,XX @@
19
break;
20
#ifndef AARCH64_TARGET_PRCTL_H
20
case A_WDOGLOCK:
21
#define AARCH64_TARGET_PRCTL_H
21
s->lock = (value != WDOG_UNLOCK_VALUE);
22
22
+ trace_cmsdk_apb_watchdog_lock(s->lock);
23
-static abi_long do_prctl_get_vl(CPUArchState *env)
23
break;
24
+static abi_long do_prctl_sve_get_vl(CPUArchState *env)
24
case A_WDOGITCR:
25
{
25
if (s->is_luminary) {
26
ARMCPU *cpu = env_archcpu(env);
26
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
27
if (cpu_isar_feature(aa64_sve, cpu)) {
28
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_get_vl(CPUArchState *env)
29
}
30
return -TARGET_EINVAL;
31
}
32
-#define do_prctl_get_vl do_prctl_get_vl
33
+#define do_prctl_sve_get_vl do_prctl_sve_get_vl
34
35
-static abi_long do_prctl_set_vl(CPUArchState *env, abi_long arg2)
36
+static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
37
{
38
/*
39
* We cannot support either PR_SVE_SET_VL_ONEXEC or PR_SVE_VL_INHERIT.
40
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_vl(CPUArchState *env, abi_long arg2)
41
}
42
return -TARGET_EINVAL;
43
}
44
-#define do_prctl_set_vl do_prctl_set_vl
45
+#define do_prctl_sve_set_vl do_prctl_sve_set_vl
46
47
static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
48
{
49
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
27
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/watchdog/trace-events
51
--- a/linux-user/syscall.c
29
+++ b/hw/watchdog/trace-events
52
+++ b/linux-user/syscall.c
30
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2)
31
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
54
#ifndef do_prctl_set_fp_mode
32
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
55
#define do_prctl_set_fp_mode do_prctl_inval1
33
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
56
#endif
34
+cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
57
-#ifndef do_prctl_get_vl
58
-#define do_prctl_get_vl do_prctl_inval0
59
+#ifndef do_prctl_sve_get_vl
60
+#define do_prctl_sve_get_vl do_prctl_inval0
61
#endif
62
-#ifndef do_prctl_set_vl
63
-#define do_prctl_set_vl do_prctl_inval1
64
+#ifndef do_prctl_sve_set_vl
65
+#define do_prctl_sve_set_vl do_prctl_inval1
66
#endif
67
#ifndef do_prctl_reset_keys
68
#define do_prctl_reset_keys do_prctl_inval1
69
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
70
case PR_SET_FP_MODE:
71
return do_prctl_set_fp_mode(env, arg2);
72
case PR_SVE_GET_VL:
73
- return do_prctl_get_vl(env);
74
+ return do_prctl_sve_get_vl(env);
75
case PR_SVE_SET_VL:
76
- return do_prctl_set_vl(env, arg2);
77
+ return do_prctl_sve_set_vl(env, arg2);
78
case PR_PAC_RESET_KEYS:
79
if (arg3 || arg4 || arg5) {
80
return -TARGET_EINVAL;
35
--
81
--
36
2.20.1
82
2.25.1
37
38
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc VRINT insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Giving these insns their own do_vrint() function allows us
3
to change the rounding mode just once at the start and end
4
rather than doing it for every element in the vector.
5
2
3
These prctl set the Streaming SVE vector length, which may
4
be completely different from the Normal SVE vector length.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-43-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-18-peter.maydell@linaro.org
9
---
10
---
10
target/arm/neon-dp.decode | 8 +++++
11
linux-user/aarch64/target_prctl.h | 54 +++++++++++++++++++++++++++++++
11
target/arm/translate-neon.inc.c | 61 +++++++++++++++++++++++++++++++++
12
linux-user/syscall.c | 16 +++++++++
12
target/arm/translate.c | 31 +++--------------
13
2 files changed, 70 insertions(+)
13
3 files changed, 74 insertions(+), 26 deletions(-)
14
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
17
--- a/linux-user/aarch64/target_prctl.h
18
+++ b/target/arm/neon-dp.decode
18
+++ b/linux-user/aarch64/target_prctl.h
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_get_vl(CPUArchState *env)
20
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
20
{
21
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
21
ARMCPU *cpu = env_archcpu(env);
22
22
if (cpu_isar_feature(aa64_sve, cpu)) {
23
+ VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
23
+ /* PSTATE.SM is always unset on syscall entry. */
24
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
24
return sve_vq(env) * 16;
25
+ VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
25
}
26
+ VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
26
return -TARGET_EINVAL;
27
27
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
28
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
28
&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
29
uint32_t vq, old_vq;
30
31
+ /* PSTATE.SM is always unset on syscall entry. */
32
old_vq = sve_vq(env);
33
34
/*
35
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
36
}
37
#define do_prctl_sve_set_vl do_prctl_sve_set_vl
38
39
+static abi_long do_prctl_sme_get_vl(CPUArchState *env)
40
+{
41
+ ARMCPU *cpu = env_archcpu(env);
42
+ if (cpu_isar_feature(aa64_sme, cpu)) {
43
+ return sme_vq(env) * 16;
44
+ }
45
+ return -TARGET_EINVAL;
46
+}
47
+#define do_prctl_sme_get_vl do_prctl_sme_get_vl
29
+
48
+
30
+ VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
49
+static abi_long do_prctl_sme_set_vl(CPUArchState *env, abi_long arg2)
31
+
32
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
33
34
+ VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
35
+
36
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
37
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
38
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-neon.inc.c
42
+++ b/target/arm/translate-neon.inc.c
43
@@ -XXX,XX +XXX,XX @@ DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
44
DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
45
DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
46
DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
47
+
48
+static bool do_vrint(DisasContext *s, arg_2misc *a, int rmode)
49
+{
50
+{
50
+ /*
51
+ /*
51
+ * Handle a VRINT* operation by iterating 32 bits at a time,
52
+ * We cannot support either PR_SME_SET_VL_ONEXEC or PR_SME_VL_INHERIT.
52
+ * with a specified rounding mode in operation.
53
+ * Note the kernel definition of sve_vl_valid allows for VQ=512,
54
+ * i.e. VL=8192, even though the architectural maximum is VQ=16.
53
+ */
55
+ */
54
+ int pass;
56
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))
55
+ TCGv_ptr fpst;
57
+ && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
56
+ TCGv_i32 tcg_rmode;
58
+ int vq, old_vq;
57
+
59
+
58
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
60
+ old_vq = sme_vq(env);
59
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
61
+
60
+ return false;
62
+ /*
63
+ * Bound the value of vq, so that we know that it fits into
64
+ * the 4-bit field in SMCR_EL1. Because PSTATE.SM is cleared
65
+ * on syscall entry, we are not modifying the current SVE
66
+ * vector length.
67
+ */
68
+ vq = MAX(arg2 / 16, 1);
69
+ vq = MIN(vq, 16);
70
+ env->vfp.smcr_el[1] =
71
+ FIELD_DP64(env->vfp.smcr_el[1], SMCR, LEN, vq - 1);
72
+
73
+ /* Delay rebuilding hflags until we know if ZA must change. */
74
+ vq = sve_vqm1_for_el_sm(env, 0, true) + 1;
75
+
76
+ if (vq != old_vq) {
77
+ /*
78
+ * PSTATE.ZA state is cleared on any change to SVL.
79
+ * We need not call arm_rebuild_hflags because PSTATE.SM was
80
+ * cleared on syscall entry, so this hasn't changed VL.
81
+ */
82
+ env->svcr = FIELD_DP64(env->svcr, SVCR, ZA, 0);
83
+ arm_rebuild_hflags(env);
84
+ }
85
+ return vq * 16;
61
+ }
86
+ }
87
+ return -TARGET_EINVAL;
88
+}
89
+#define do_prctl_sme_set_vl do_prctl_sme_set_vl
62
+
90
+
63
+ /* UNDEF accesses to D16-D31 if they don't exist. */
91
static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
64
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
92
{
65
+ ((a->vd | a->vm) & 0x10)) {
93
ARMCPU *cpu = env_archcpu(env);
66
+ return false;
94
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
67
+ }
68
+
69
+ if (a->size != 2) {
70
+ /* TODO: FP16 will be the size == 1 case */
71
+ return false;
72
+ }
73
+
74
+ if ((a->vd | a->vm) & a->q) {
75
+ return false;
76
+ }
77
+
78
+ if (!vfp_access_check(s)) {
79
+ return true;
80
+ }
81
+
82
+ fpst = get_fpstatus_ptr(1);
83
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
84
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
85
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
86
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
87
+ gen_helper_rints(tmp, tmp, fpst);
88
+ neon_store_reg(a->vd, pass, tmp);
89
+ }
90
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ tcg_temp_free_i32(tcg_rmode);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
95
+}
96
+
97
+#define DO_VRINT(INSN, RMODE) \
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
99
+ { \
100
+ return do_vrint(s, a, RMODE); \
101
+ }
102
+
103
+DO_VRINT(VRINTN, FPROUNDING_TIEEVEN)
104
+DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
105
+DO_VRINT(VRINTZ, FPROUNDING_ZERO)
106
+DO_VRINT(VRINTM, FPROUNDING_NEGINF)
107
+DO_VRINT(VRINTP, FPROUNDING_POSINF)
108
diff --git a/target/arm/translate.c b/target/arm/translate.c
109
index XXXXXXX..XXXXXXX 100644
95
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/translate.c
96
--- a/linux-user/syscall.c
111
+++ b/target/arm/translate.c
97
+++ b/linux-user/syscall.c
112
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
@@ -XXX,XX +XXX,XX @@ abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
113
case NEON_2RM_VCEQ0_F:
99
#ifndef PR_SET_SYSCALL_USER_DISPATCH
114
case NEON_2RM_VCLE0_F:
100
# define PR_SET_SYSCALL_USER_DISPATCH 59
115
case NEON_2RM_VCLT0_F:
101
#endif
116
+ case NEON_2RM_VRINTN:
102
+#ifndef PR_SME_SET_VL
117
+ case NEON_2RM_VRINTA:
103
+# define PR_SME_SET_VL 63
118
+ case NEON_2RM_VRINTM:
104
+# define PR_SME_GET_VL 64
119
+ case NEON_2RM_VRINTP:
105
+# define PR_SME_VL_LEN_MASK 0xffff
120
+ case NEON_2RM_VRINTZ:
106
+# define PR_SME_VL_INHERIT (1 << 17)
121
/* handled by decodetree */
107
+#endif
122
return 1;
108
123
case NEON_2RM_VTRN:
109
#include "target_prctl.h"
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
110
125
}
111
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2)
126
neon_store_reg(rm, pass, tmp2);
112
#ifndef do_prctl_set_unalign
127
break;
113
#define do_prctl_set_unalign do_prctl_inval1
128
- case NEON_2RM_VRINTN:
114
#endif
129
- case NEON_2RM_VRINTA:
115
+#ifndef do_prctl_sme_get_vl
130
- case NEON_2RM_VRINTM:
116
+#define do_prctl_sme_get_vl do_prctl_inval0
131
- case NEON_2RM_VRINTP:
117
+#endif
132
- case NEON_2RM_VRINTZ:
118
+#ifndef do_prctl_sme_set_vl
133
- {
119
+#define do_prctl_sme_set_vl do_prctl_inval1
134
- TCGv_i32 tcg_rmode;
120
+#endif
135
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
121
136
- int rmode;
122
static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
137
-
123
abi_long arg3, abi_long arg4, abi_long arg5)
138
- if (op == NEON_2RM_VRINTZ) {
124
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
139
- rmode = FPROUNDING_ZERO;
125
return do_prctl_sve_get_vl(env);
140
- } else {
126
case PR_SVE_SET_VL:
141
- rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
127
return do_prctl_sve_set_vl(env, arg2);
142
- }
128
+ case PR_SME_GET_VL:
143
-
129
+ return do_prctl_sme_get_vl(env);
144
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
130
+ case PR_SME_SET_VL:
145
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
131
+ return do_prctl_sme_set_vl(env, arg2);
146
- cpu_env);
132
case PR_PAC_RESET_KEYS:
147
- gen_helper_rints(tmp, tmp, fpstatus);
133
if (arg3 || arg4 || arg5) {
148
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
134
return -TARGET_EINVAL;
149
- cpu_env);
150
- tcg_temp_free_ptr(fpstatus);
151
- tcg_temp_free_i32(tcg_rmode);
152
- break;
153
- }
154
case NEON_2RM_VCVTAU:
155
case NEON_2RM_VCVTAS:
156
case NEON_2RM_VCVTNU:
157
--
135
--
158
2.20.1
136
2.25.1
159
160
diff view generated by jsdifflib
1
Since commit ba3e7926691ed3 it has been unnecessary for target code
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to call gen_io_end() after an IO instruction in icount mode; it is
3
sufficient to call gen_io_start() before it and to force the end of
4
the TB.
5
2
6
Many now-unnecessary calls to gen_io_end() were removed in commit
3
There's no reason to set CPACR_EL1.ZEN if SVE disabled.
7
9e9b10c6491153b, but some were missed or accidentally added later.
8
Remove unneeded calls from the arm target:
9
4
10
* the call in the handling of exception-return-via-LDM is
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
unnecessary, and the code is already forcing end-of-TB
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
* the call in the VFP access check code is more complicated:
7
Message-id: 20220708151540.18136-44-richard.henderson@linaro.org
13
we weren't ending the TB, so we need to add the code to
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
force that by setting DISAS_UPDATE
9
---
15
* the doc comment for ARM_CP_IO doesn't need to mention
10
target/arm/cpu.c | 7 +++----
16
gen_io_end() any more
11
1 file changed, 3 insertions(+), 4 deletions(-)
17
12
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
22
Message-id: 20200619170324.12093-1-peter.maydell@linaro.org
23
---
24
target/arm/cpu.h | 2 +-
25
target/arm/translate-vfp.inc.c | 7 +++----
26
target/arm/translate.c | 3 ---
27
3 files changed, 4 insertions(+), 8 deletions(-)
28
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.c
32
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
34
* migration or KVM state synchronization. (Typically this is for "registers"
18
/* and to the FP/Neon instructions */
35
* which are actually used as instructions for cache maintenance and so on.)
19
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
36
* IO indicates that this register does I/O and therefore its accesses
20
CPACR_EL1, FPEN, 3);
37
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
21
- /* and to the SVE instructions */
38
+ * need to be marked with gen_io_start() and also end the TB. In particular,
22
- env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
39
* registers which implement clocks or timers require this.
23
- CPACR_EL1, ZEN, 3);
40
* RAISES_EXC is for when the read or write hook might raise an exception;
24
- /* with reasonable vector length */
41
* the generated code will synchronize the CPU state before calling the hook
25
+ /* and to the SVE instructions, with default vector length */
42
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
26
if (cpu_isar_feature(aa64_sve, cpu)) {
43
index XXXXXXX..XXXXXXX 100644
27
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
44
--- a/target/arm/translate-vfp.inc.c
28
+ CPACR_EL1, ZEN, 3);
45
+++ b/target/arm/translate-vfp.inc.c
29
env->vfp.zcr_el[1] = cpu->sve_default_vq - 1;
46
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
47
if (s->v7m_lspact) {
48
/*
49
* Lazy state saving affects external memory and also the NVIC,
50
- * so we must mark it as an IO operation for icount.
51
+ * so we must mark it as an IO operation for icount (and cause
52
+ * this to be the last insn in the TB).
53
*/
54
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
55
+ s->base.is_jmp = DISAS_UPDATE;
56
gen_io_start();
57
}
58
gen_helper_v7m_preserve_fp_state(cpu_env);
59
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
60
- gen_io_end();
61
- }
62
/*
63
* If the preserve_fp_state helper doesn't throw an exception
64
* then it will clear LSPACT; we don't need to repeat this for
65
diff --git a/target/arm/translate.c b/target/arm/translate.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/translate.c
68
+++ b/target/arm/translate.c
69
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
70
gen_io_start();
71
}
30
}
72
gen_helper_cpsr_write_eret(cpu_env, tmp);
31
/*
73
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
74
- gen_io_end();
75
- }
76
tcg_temp_free_i32(tmp);
77
/* Must exit loop to check un-masked IRQs */
78
s->base.is_jmp = DISAS_EXIT;
79
--
32
--
80
2.20.1
33
2.25.1
81
82
diff view generated by jsdifflib
1
From: David CARLIER <devnexen@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
From 3025a0ce3fdf7d3559fc35a52c659f635f5c750c Mon Sep 17 00:00:00 2001
3
Enable SME, TPIDR2_EL0, and FA64 if supported by the cpu.
4
From: David Carlier <devnexen@gmail.com>
5
Date: Tue, 26 May 2020 21:35:27 +0100
6
Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
7
4
8
Using dyld API to get the full path of the current process.
9
10
Signed-off-by: David Carlier <devnexen@gmail.com>
11
Message-id: CA+XhMqxwC10XHVs4Z-JfE0-WLAU3ztDuU9QKVi31mjr59HWCxg@mail.gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220708151540.18136-45-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
util/oslib-posix.c | 15 +++++++++++++++
10
target/arm/cpu.c | 11 +++++++++++
16
1 file changed, 15 insertions(+)
11
1 file changed, 11 insertions(+)
17
12
18
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/util/oslib-posix.c
15
--- a/target/arm/cpu.c
21
+++ b/util/oslib-posix.c
16
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
23
#include <lwp.h>
18
CPACR_EL1, ZEN, 3);
24
#endif
19
env->vfp.zcr_el[1] = cpu->sve_default_vq - 1;
25
26
+#ifdef __APPLE__
27
+#include <mach-o/dyld.h>
28
+#endif
29
+
30
#include "qemu/mmap-alloc.h"
31
32
#ifdef CONFIG_DEBUG_STACK_USAGE
33
@@ -XXX,XX +XXX,XX @@ void qemu_init_exec_dir(const char *argv0)
34
p = buf;
35
}
20
}
36
}
21
+ /* and for SME instructions, with default vector length, and TPIDR2 */
37
+#elif defined(__APPLE__)
22
+ if (cpu_isar_feature(aa64_sme, cpu)) {
38
+ {
23
+ env->cp15.sctlr_el[1] |= SCTLR_EnTP2;
39
+ char fpath[PATH_MAX];
24
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
40
+ uint32_t len = sizeof(fpath);
25
+ CPACR_EL1, SMEN, 3);
41
+ if (_NSGetExecutablePath(fpath, &len) == 0) {
26
+ env->vfp.smcr_el[1] = cpu->sme_default_vq - 1;
42
+ p = realpath(fpath, buf);
27
+ if (cpu_isar_feature(aa64_sme_fa64, cpu)) {
43
+ if (!p) {
28
+ env->vfp.smcr_el[1] = FIELD_DP64(env->vfp.smcr_el[1],
44
+ return;
29
+ SMCR, FA64, 1);
45
+ }
30
+ }
46
+ }
31
+ }
47
+ }
32
/*
48
#endif
33
* Enable 48-bit address space (TODO: take reserved_va into account).
49
/* If we don't have any way of figuring out the actual executable
34
* Enable TBI0 but not TBI1.
50
location then try argv[0]. */
51
--
35
--
52
2.20.1
36
2.25.1
53
54
diff view generated by jsdifflib
1
Convert the Neon-2-reg misc crypto ops (AESE, AESMC, SHA1H, SHA1SU1)
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree.
3
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-46-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-9-peter.maydell@linaro.org
7
---
7
---
8
target/arm/neon-dp.decode | 12 ++++++++
8
linux-user/elfload.c | 20 ++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 42 ++++++++++++++++++++++++++
9
1 file changed, 20 insertions(+)
10
target/arm/translate.c | 52 +++------------------------------
11
3 files changed, 58 insertions(+), 48 deletions(-)
12
10
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
13
--- a/linux-user/elfload.c
16
+++ b/target/arm/neon-dp.decode
14
+++ b/linux-user/elfload.c
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
15
@@ -XXX,XX +XXX,XX @@ enum {
18
&2misc vm=%vm_dp vd=%vd_dp
16
ARM_HWCAP2_A64_RNG = 1 << 16,
19
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
17
ARM_HWCAP2_A64_BTI = 1 << 17,
20
&2misc vm=%vm_dp vd=%vd_dp q=0
18
ARM_HWCAP2_A64_MTE = 1 << 18,
21
+ @2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
19
+ ARM_HWCAP2_A64_ECV = 1 << 19,
22
+ &2misc vm=%vm_dp vd=%vd_dp q=1
20
+ ARM_HWCAP2_A64_AFP = 1 << 20,
23
21
+ ARM_HWCAP2_A64_RPRES = 1 << 21,
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
22
+ ARM_HWCAP2_A64_MTE3 = 1 << 22,
25
23
+ ARM_HWCAP2_A64_SME = 1 << 23,
26
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
24
+ ARM_HWCAP2_A64_SME_I16I64 = 1 << 24,
27
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
25
+ ARM_HWCAP2_A64_SME_F64F64 = 1 << 25,
28
26
+ ARM_HWCAP2_A64_SME_I8I32 = 1 << 26,
29
+ AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
27
+ ARM_HWCAP2_A64_SME_F16F32 = 1 << 27,
30
+ AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
28
+ ARM_HWCAP2_A64_SME_B16F32 = 1 << 28,
31
+ AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
29
+ ARM_HWCAP2_A64_SME_F32F32 = 1 << 29,
32
+ AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
30
+ ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
33
+
31
};
34
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
32
35
33
#define ELF_HWCAP get_elf_hwcap()
36
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
34
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
37
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
35
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
38
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
36
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
39
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
37
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
40
38
+ GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
41
+ SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
39
+ ARM_HWCAP2_A64_SME_F32F32 |
42
+
40
+ ARM_HWCAP2_A64_SME_B16F32 |
43
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
41
+ ARM_HWCAP2_A64_SME_F16F32 |
44
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
42
+ ARM_HWCAP2_A64_SME_I8I32));
45
43
+ GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
46
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
44
+ GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
47
45
+ GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
48
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
46
49
47
return hwcaps;
50
+ SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
51
+ SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
52
+
53
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
54
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
55
]
56
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-neon.inc.c
59
+++ b/target/arm/translate-neon.inc.c
60
@@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a)
61
}
62
return do_2misc_vec(s, a, tcg_gen_gvec_not);
63
}
48
}
64
+
65
+#define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \
66
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
67
+ uint32_t rm_ofs, uint32_t oprsz, \
68
+ uint32_t maxsz) \
69
+ { \
70
+ tcg_gen_gvec_3_ool(rd_ofs, rd_ofs, rm_ofs, oprsz, maxsz, \
71
+ DATA, FUNC); \
72
+ }
73
+
74
+#define WRAP_2M_2_OOL_FN(WRAPNAME, FUNC, DATA) \
75
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
76
+ uint32_t rm_ofs, uint32_t oprsz, \
77
+ uint32_t maxsz) \
78
+ { \
79
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, oprsz, maxsz, DATA, FUNC); \
80
+ }
81
+
82
+WRAP_2M_3_OOL_FN(gen_AESE, gen_helper_crypto_aese, 0)
83
+WRAP_2M_3_OOL_FN(gen_AESD, gen_helper_crypto_aese, 1)
84
+WRAP_2M_2_OOL_FN(gen_AESMC, gen_helper_crypto_aesmc, 0)
85
+WRAP_2M_2_OOL_FN(gen_AESIMC, gen_helper_crypto_aesmc, 1)
86
+WRAP_2M_2_OOL_FN(gen_SHA1H, gen_helper_crypto_sha1h, 0)
87
+WRAP_2M_2_OOL_FN(gen_SHA1SU1, gen_helper_crypto_sha1su1, 0)
88
+WRAP_2M_2_OOL_FN(gen_SHA256SU0, gen_helper_crypto_sha256su0, 0)
89
+
90
+#define DO_2M_CRYPTO(INSN, FEATURE, SIZE) \
91
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
92
+ { \
93
+ if (!dc_isar_feature(FEATURE, s) || a->size != SIZE) { \
94
+ return false; \
95
+ } \
96
+ return do_2misc_vec(s, a, gen_##INSN); \
97
+ }
98
+
99
+DO_2M_CRYPTO(AESE, aa32_aes, 0)
100
+DO_2M_CRYPTO(AESD, aa32_aes, 0)
101
+DO_2M_CRYPTO(AESMC, aa32_aes, 0)
102
+DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
103
+DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
104
+DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
105
+DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
106
diff --git a/target/arm/translate.c b/target/arm/translate.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate.c
109
+++ b/target/arm/translate.c
110
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
111
{
112
int op;
113
int q;
114
- int rd, rm, rd_ofs, rm_ofs;
115
+ int rd, rm;
116
int size;
117
int pass;
118
int u;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
120
VFP_DREG_D(rd, insn);
121
VFP_DREG_M(rm, insn);
122
size = (insn >> 20) & 3;
123
- rd_ofs = neon_reg_offset(rd, 0);
124
- rm_ofs = neon_reg_offset(rm, 0);
125
126
if ((insn & (1 << 23)) == 0) {
127
/* Three register same length: handled by decodetree */
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
case NEON_2RM_VCLE0:
130
case NEON_2RM_VCGE0:
131
case NEON_2RM_VCLT0:
132
+ case NEON_2RM_AESE: case NEON_2RM_AESMC:
133
+ case NEON_2RM_SHA1H:
134
+ case NEON_2RM_SHA1SU1:
135
/* handled by decodetree */
136
return 1;
137
case NEON_2RM_VTRN:
138
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
goto elementwise;
140
}
141
break;
142
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
143
- if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
144
- return 1;
145
- }
146
- /*
147
- * Bit 6 is the lowest opcode bit; it distinguishes
148
- * between encryption (AESE/AESMC) and decryption
149
- * (AESD/AESIMC).
150
- */
151
- if (op == NEON_2RM_AESE) {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
153
- vfp_reg_offset(true, rd),
154
- vfp_reg_offset(true, rm),
155
- 16, 16, extract32(insn, 6, 1),
156
- gen_helper_crypto_aese);
157
- } else {
158
- tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
159
- vfp_reg_offset(true, rm),
160
- 16, 16, extract32(insn, 6, 1),
161
- gen_helper_crypto_aesmc);
162
- }
163
- break;
164
- case NEON_2RM_SHA1H:
165
- if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
166
- return 1;
167
- }
168
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
169
- gen_helper_crypto_sha1h);
170
- break;
171
- case NEON_2RM_SHA1SU1:
172
- if ((rm | rd) & 1) {
173
- return 1;
174
- }
175
- /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
176
- if (q) {
177
- if (!dc_isar_feature(aa32_sha2, s)) {
178
- return 1;
179
- }
180
- } else if (!dc_isar_feature(aa32_sha1, s)) {
181
- return 1;
182
- }
183
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
184
- q ? gen_helper_crypto_sha256su0
185
- : gen_helper_crypto_sha1su1);
186
- break;
187
188
default:
189
elementwise:
190
--
49
--
191
2.20.1
50
2.25.1
192
193
diff view generated by jsdifflib