1
The following changes since commit 61fee7f45955cd0bf9b79be9fa9c7ebabb5e6a85:
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/acceptance-testing-20200622' into staging (2020-06-22 20:50:10 +0100)
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200623
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
8
8
9
for you to fetch changes up to 539533b85fbd269f777bed931de8ccae1dd837e9:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
10
10
11
arm/virt: Add memory hot remove support (2020-06-23 11:39:48 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* util/oslib-posix : qemu_init_exec_dir implementation for Mac
15
* more MVE instructions
16
* target/arm: Last parts of neon decodetree conversion
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
17
* hw/arm/virt: Add 5.0 HW compat props
17
* target/arm: Check NaN mode before silencing NaN
18
* hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
19
* mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices
19
* hw/arm: Add basic power management to raspi.
20
* mps2: Add some unimplemented-device stubs for audio and GPIO
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
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
Joe Komlodi (1):
28
hw/arm/virt: Add 5.0 HW compat props
24
target/arm: Check NaN mode before silencing NaN
29
tests/qtest/arm-cpu-features: Add feature setting tests
30
25
31
David CARLIER (1):
26
Maxim Uvarov (1):
32
util/oslib-posix : qemu_init_exec_dir implementation for Mac
27
hw/gpio/gpio_pwr: use shutdown function for reboot
33
28
34
Peter Maydell (23):
29
Nolan Leake (1):
35
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
30
hw/arm: Add basic power management to raspi.
36
target/arm: Convert Neon 2-reg-misc pairwise ops to decodetree
37
target/arm: Convert VZIP, VUZP to decodetree
38
target/arm: Convert Neon narrowing moves to decodetree
39
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
40
target/arm: Convert Neon VCVT f16/f32 insns to decodetree
41
target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree
42
target/arm: Convert Neon 2-reg-misc crypto operations to decodetree
43
target/arm: Rename NeonGenOneOpFn to NeonGenOne64OpFn
44
target/arm: Fix capitalization in NeonGenTwo{Single, Double}OPFn typedefs
45
target/arm: Make gen_swap_half() take separate src and dest
46
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
47
target/arm: Convert remaining simple 2-reg-misc Neon ops
48
target/arm: Convert Neon VQABS, VQNEG to decodetree
49
target/arm: Convert simple fp Neon 2-reg-misc insns
50
target/arm: Convert Neon 2-reg-misc fp-compare-with-zero insns to decodetree
51
target/arm: Convert Neon 2-reg-misc VRINT insns to decodetree
52
target/arm: Convert Neon 2-reg-misc VCVT insns to decodetree
53
target/arm: Convert Neon VSWP to decodetree
54
target/arm: Convert Neon VTRN to decodetree
55
target/arm: Move some functions used only in translate-neon.inc.c to that file
56
target/arm: Remove unnecessary gen_io_end() calls
57
target/arm: Remove dead code relating to SABA and UABA
58
31
59
Philippe Mathieu-Daudé (15):
32
Patrick Venture (2):
60
hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
33
docs/system/arm: Add quanta-q7l1-bmc reference
61
hw/i2c/versatile_i2c: Add definitions for register addresses
34
docs/system/arm: Add quanta-gbs-bmc reference
62
hw/i2c/versatile_i2c: Add SCL/SDA definitions
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
35
76
Shameer Kolothum (1):
36
Peter Maydell (18):
77
arm/virt: Add memory hot remove support
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
78
55
79
include/hw/i2c/arm_sbcon_i2c.h | 35 ++
56
Philippe Mathieu-Daudé (1):
80
target/arm/cpu.h | 2 +-
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
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
58
59
docs/system/arm/aspeed.rst | 1 +
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
82
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Cc: Cornelia Huck <cohuck@redhat.com>
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
entry.
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
5
6
Message-id: 20200616140803.25515-1-drjones@redhat.com
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/virt.c | 1 +
11
docs/system/arm/aspeed.rst | 1 +
10
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
11
13
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
16
--- a/docs/system/arm/aspeed.rst
15
+++ b/hw/arm/virt.c
17
+++ b/docs/system/arm/aspeed.rst
16
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
18
@@ -XXX,XX +XXX,XX @@ etc.
17
static void virt_machine_5_0_options(MachineClass *mc)
19
AST2400 SoC based machines :
18
{
20
19
virt_machine_5_1_options(mc);
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
20
+ compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
21
}
23
22
DEFINE_VIRT_MACHINE(5, 0)
24
AST2500 SoC based machines :
23
25
24
--
26
--
25
2.20.1
27
2.20.1
26
28
27
29
diff view generated by jsdifflib
Deleted patch
1
From: David CARLIER <devnexen@gmail.com>
2
1
3
From 3025a0ce3fdf7d3559fc35a52c659f635f5c750c Mon Sep 17 00:00:00 2001
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
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>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
util/oslib-posix.c | 15 +++++++++++++++
16
1 file changed, 15 insertions(+)
17
18
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/util/oslib-posix.c
21
+++ b/util/oslib-posix.c
22
@@ -XXX,XX +XXX,XX @@
23
#include <lwp.h>
24
#endif
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
}
36
}
37
+#elif defined(__APPLE__)
38
+ {
39
+ char fpath[PATH_MAX];
40
+ uint32_t len = sizeof(fpath);
41
+ if (_NSGetExecutablePath(fpath, &len) == 0) {
42
+ p = realpath(fpath, buf);
43
+ if (!p) {
44
+ return;
45
+ }
46
+ }
47
+ }
48
#endif
49
/* If we don't have any way of figuring out the actual executable
50
location then try argv[0]. */
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
2
1
3
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
target/arm/neon-dp.decode | 12 ++++++++
8
target/arm/translate-neon.inc.c | 50 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 24 ++--------------
10
3 files changed, 64 insertions(+), 22 deletions(-)
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
vm=%vm_dp vd=%vd_dp size=1
18
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
19
vm=%vm_dp vd=%vd_dp size=2
20
+
21
+ ##################################################################
22
+ # 2-reg-misc grouping:
23
+ # 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
24
+ ##################################################################
25
+
26
+ &2misc vd vm q size
27
+
28
+ @2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
29
+ &2misc vm=%vm_dp vd=%vd_dp
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
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
40
a->q ? 16 : 8, a->q ? 16 : 8);
41
return true;
42
}
43
+
44
+static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
45
+{
46
+ int pass, half;
47
+
48
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, 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
+ }
91
+ return true;
92
+}
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
--
129
2.20.1
130
131
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Some cpu features may be enabled and disabled for all configurations
3
Add line item reference to quanta-gbs-bmc machine.
4
that support the feature. Let's test that.
5
4
6
A recent regression[*] inspired adding these tests.
5
Signed-off-by: Patrick Venture <venture@google.com>
7
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
[*] '-cpu host,pmu=on' caused a segfault
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
8
[PMM: fixed underline Sphinx warning]
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>
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
docs/system/arm/nuvoton.rst | 5 +++--
18
1 file changed, 34 insertions(+), 4 deletions(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
19
13
20
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qtest/arm-cpu-features.c
16
--- a/docs/system/arm/nuvoton.rst
23
+++ b/tests/qtest/arm-cpu-features.c
17
+++ b/docs/system/arm/nuvoton.rst
24
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
18
@@ -XXX,XX +XXX,XX @@
25
qobject_unref(_resp); \
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
26
})
20
-=====================================================
27
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
28
-#define assert_feature(qts, cpu_type, feature, expected_value) \
22
+================================================================
29
+#define resp_assert_feature(resp, feature, expected_value) \
23
30
({ \
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
31
- QDict *_resp, *_props; \
25
designed to be used as Baseboard Management Controllers (BMCs) in various
32
+ QDict *_props; \
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
33
\
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
34
- _resp = do_query_no_props(qts, cpu_type); \
28
Hyperscale applications. The following machines are based on this chip :
35
g_assert(_resp); \
29
36
g_assert(resp_has_props(_resp)); \
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
37
_props = resp_get_props(_resp); \
31
- ``quanta-gsj`` Quanta GSJ server BMC
38
g_assert(qdict_get(_props, feature)); \
32
39
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
40
+})
41
+
42
+#define assert_feature(qts, cpu_type, feature, expected_value) \
43
+({ \
44
+ QDict *_resp; \
45
+ \
46
+ _resp = do_query_no_props(qts, cpu_type); \
47
+ g_assert(_resp); \
48
+ resp_assert_feature(_resp, feature, expected_value); \
49
+ qobject_unref(_resp); \
50
+})
51
+
52
+#define assert_set_feature(qts, cpu_type, feature, value) \
53
+({ \
54
+ const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
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
--
34
--
103
2.20.1
35
2.20.1
104
36
105
37
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
'ARM SBCon two-wire serial bus interface' is the official
3
This is just enough to make reboot and poweroff work. Works for
4
name describing the pair of registers used to bitbanging
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
I2C in the Versatile boards.
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
6
do what linux does for reset.
7
Make the private VersatileI2CState structure as public
7
8
ArmSbconI2CState.
8
The watchdog timer functionality is not yet implemented.
9
Add the TYPE_ARM_SBCON_I2C, alias to our current
9
10
TYPE_VERSATILE_I2C model.
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Rename the memory region description as 'arm_sbcon_i2c'.
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-5-f4bug@amsat.org
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
---
18
include/hw/i2c/arm_sbcon_i2c.h | 35 ++++++++++++++++++++++++++++++++++
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
19
hw/i2c/versatile_i2c.c | 17 +++++------------
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
20
MAINTAINERS | 1 +
21
hw/arm/bcm2835_peripherals.c | 13 ++-
21
3 files changed, 41 insertions(+), 12 deletions(-)
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
22
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
23
hw/misc/meson.build | 1 +
23
24
5 files changed, 204 insertions(+), 2 deletions(-)
24
diff --git a/include/hw/i2c/arm_sbcon_i2c.h b/include/hw/i2c/arm_sbcon_i2c.h
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
32
@@ -XXX,XX +XXX,XX @@
33
#include "hw/misc/bcm2835_mphi.h"
34
#include "hw/misc/bcm2835_thermal.h"
35
#include "hw/misc/bcm2835_cprman.h"
36
+#include "hw/misc/bcm2835_powermgt.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/sd/bcm2835_sdhost.h"
39
#include "hw/gpio/bcm2835_gpio.h"
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
25
new file mode 100644
50
new file mode 100644
26
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
27
--- /dev/null
52
--- /dev/null
28
+++ b/include/hw/i2c/arm_sbcon_i2c.h
53
+++ b/include/hw/misc/bcm2835_powermgt.h
29
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
30
+/*
55
+/*
31
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
56
+ * BCM2835 Power Management emulation
32
+ * a.k.a.
57
+ *
33
+ * ARM Versatile I2C controller
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
34
+ *
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
35
+ * Copyright (c) 2006-2007 CodeSourcery.
60
+ *
36
+ * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
37
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
62
+ * See the COPYING file in the top-level directory.
38
+ *
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
+ */
63
+ */
41
+#ifndef HW_I2C_ARM_SBCON_H
64
+
42
+#define HW_I2C_ARM_SBCON_H
65
+#ifndef BCM2835_POWERMGT_H
66
+#define BCM2835_POWERMGT_H
43
+
67
+
44
+#include "hw/sysbus.h"
68
+#include "hw/sysbus.h"
45
+#include "hw/i2c/bitbang_i2c.h"
69
+#include "qom/object.h"
46
+
70
+
47
+#define TYPE_VERSATILE_I2C "versatile_i2c"
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
48
+#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
49
+
73
+
50
+#define ARM_SBCON_I2C(obj) \
74
+struct BCM2835PowerMgtState {
51
+ OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
75
+ SysBusDevice busdev;
52
+
53
+typedef struct ArmSbconI2CState {
54
+ /*< private >*/
55
+ SysBusDevice parent_obj;
56
+ /*< public >*/
57
+
58
+ MemoryRegion iomem;
76
+ MemoryRegion iomem;
59
+ bitbang_i2c_interface bitbang;
77
+
60
+ int out;
78
+ uint32_t rstc;
61
+ int in;
79
+ uint32_t rsts;
62
+} ArmSbconI2CState;
80
+ uint32_t wdog;
63
+
81
+};
64
+#endif /* HW_I2C_ARM_SBCON_H */
82
+
65
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
66
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/i2c/versatile_i2c.c
86
--- a/hw/arm/bcm2835_peripherals.c
68
+++ b/hw/i2c/versatile_i2c.c
87
+++ b/hw/arm/bcm2835_peripherals.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
96
}
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
69
@@ -XXX,XX +XXX,XX @@
122
@@ -XXX,XX +XXX,XX @@
70
/*
123
+/*
71
- * ARM Versatile I2C controller
124
+ * BCM2835 Power Management emulation
72
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
125
+ *
73
+ * a.k.a. ARM Versatile I2C controller
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
74
*
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
75
* Copyright (c) 2006-2007 CodeSourcery.
128
+ *
76
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
77
@@ -XXX,XX +XXX,XX @@
130
+ * See the COPYING file in the top-level directory.
78
*/
131
+ */
79
132
+
80
#include "qemu/osdep.h"
133
+#include "qemu/osdep.h"
81
-#include "hw/sysbus.h"
134
+#include "qemu/log.h"
82
-#include "hw/i2c/bitbang_i2c.h"
135
+#include "qemu/module.h"
83
+#include "hw/i2c/arm_sbcon_i2c.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
84
#include "hw/registerfields.h"
137
+#include "migration/vmstate.h"
85
#include "qemu/log.h"
138
+#include "sysemu/runstate.h"
86
#include "qemu/module.h"
139
+
87
140
+#define PASSWORD 0x5a000000
88
-#define TYPE_VERSATILE_I2C "versatile_i2c"
141
+#define PASSWORD_MASK 0xff000000
89
#define VERSATILE_I2C(obj) \
142
+
90
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
143
+#define R_RSTC 0x1c
91
144
+#define V_RSTC_RESET 0x20
92
-typedef struct VersatileI2CState {
145
+#define R_RSTS 0x20
93
- SysBusDevice parent_obj;
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
94
+typedef ArmSbconI2CState VersatileI2CState;
147
+#define R_WDOG 0x24
95
148
+
96
- MemoryRegion iomem;
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
97
- bitbang_i2c_interface bitbang;
150
+ unsigned size)
98
- int out;
151
+{
99
- int in;
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
100
-} VersatileI2CState;
153
+ uint32_t res = 0;
101
154
+
102
REG32(CONTROL_GET, 0)
155
+ switch (offset) {
103
REG32(CONTROL_SET, 0)
156
+ case R_RSTC:
104
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_init(Object *obj)
157
+ res = s->rstc;
105
bus = i2c_init_bus(dev, "i2c");
158
+ break;
106
bitbang_i2c_init(&s->bitbang, bus);
159
+ case R_RSTS:
107
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
160
+ res = s->rsts;
108
- "versatile_i2c", 0x1000);
161
+ break;
109
+ "arm_sbcon_i2c", 0x1000);
162
+ case R_WDOG:
110
sysbus_init_mmio(sbd, &s->iomem);
163
+ res = s->wdog;
111
}
164
+ break;
112
165
+
113
diff --git a/MAINTAINERS b/MAINTAINERS
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
114
index XXXXXXX..XXXXXXX 100644
284
index XXXXXXX..XXXXXXX 100644
115
--- a/MAINTAINERS
285
--- a/hw/misc/meson.build
116
+++ b/MAINTAINERS
286
+++ b/hw/misc/meson.build
117
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
118
L: qemu-arm@nongnu.org
288
'bcm2835_rng.c',
119
S: Maintained
289
'bcm2835_thermal.c',
120
F: hw/*/versatile*
290
'bcm2835_cprman.c',
121
+F: include/hw/i2c/arm_sbcon_i2c.h
291
+ 'bcm2835_powermgt.c',
122
F: hw/misc/arm_sysctl.c
292
))
123
F: docs/system/arm/versatile.rst
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
124
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
125
--
295
--
126
2.20.1
296
2.20.1
127
297
128
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
From 'Application Note AN521', chapter 4.7:
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
4
5
5
The SMM implements four SBCon serial modules:
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
One SBCon module for use by the Color LCD touch interface.
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
8
One SBCon module to configure the audio controller.
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
9
Two general purpose SBCon modules, that connect to the
10
console: [ 0.000000] CPU: div instructions available: patching division code
10
Expansion headers J7 and J8, are intended for use with the
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
11
V2C-Shield1 which provide an I2C interface on the headers.
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
12
44
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-15-f4bug@amsat.org
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
49
---
18
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
19
1 file changed, 18 insertions(+), 5 deletions(-)
51
1 file changed, 43 insertions(+)
20
52
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
22
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
55
--- a/tests/acceptance/boot_linux_console.py
24
+++ b/hw/arm/mps2-tz.c
56
+++ b/tests/acceptance/boot_linux_console.py
25
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
26
#include "hw/arm/armsse.h"
58
from avocado import skip
27
#include "hw/dma/pl080.h"
59
from avocado import skipUnless
28
#include "hw/ssi/pl022.h"
60
from avocado_qemu import Test
29
+#include "hw/i2c/arm_sbcon_i2c.h"
61
+from avocado_qemu import exec_command
30
#include "hw/net/lan9118.h"
62
from avocado_qemu import exec_command_and_wait_for_pattern
31
#include "net/net.h"
63
from avocado_qemu import interrupt_interactive_console_until_pattern
32
#include "hw/core/split-irq.h"
64
from avocado_qemu import wait_for_console_pattern
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
34
TZPPC ppc[5];
66
"""
35
TZMPC ssram_mpc[3];
67
self.do_test_arm_raspi2(0)
36
PL022State spi[5];
68
37
- UnimplementedDeviceState i2c[4];
69
+ def test_arm_raspi2_initrd(self):
38
+ ArmSbconI2CState i2c[4];
70
+ """
39
UnimplementedDeviceState i2s_audio;
71
+ :avocado: tags=arch:arm
40
UnimplementedDeviceState gpio[4];
72
+ :avocado: tags=machine:raspi2
41
UnimplementedDeviceState gfx;
73
+ """
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
43
return sysbus_mmio_get_region(s, 0);
75
+ 'pool/main/r/raspberrypi-firmware/'
44
}
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
45
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
46
+static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
47
+ const char *name, hwaddr size)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
48
+{
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
49
+ ArmSbconI2CState *i2c = opaque;
50
+ SysBusDevice *s;
51
+
81
+
52
+ object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
53
+ s = SYS_BUS_DEVICE(i2c);
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
54
+ sysbus_realize(s, &error_fatal);
84
+ 'arm/rootfs-armv7a.cpio.gz')
55
+ return sysbus_mmio_get_region(s, 0);
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
56
+}
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
57
+
89
+
58
static void mps2tz_common_init(MachineState *machine)
90
+ self.vm.set_console()
59
{
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
60
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
61
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
93
+ 'panic=-1 noreboot ' +
62
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
94
+ 'dwc_otg.fiq_fsm_enable=0')
63
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
95
+ self.vm.add_args('-kernel', kernel_path,
64
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
96
+ '-dtb', dtb_path,
65
- { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
97
+ '-initrd', initrd_path,
66
- { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
98
+ '-append', kernel_command_line,
67
- { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
99
+ '-no-reboot')
68
- { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
100
+ self.vm.launch()
69
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
101
+ self.wait_for_console_pattern('Boot successful.')
70
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
102
+
71
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
72
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
104
+ 'BCM2835')
73
},
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
74
}, {
106
+ '/soc/cprman@7e101000')
75
.name = "apb_ppcexp2",
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
76
--
114
--
77
2.20.1
115
2.20.1
78
116
79
117
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
Message-id: 20200617072539.32686-14-f4bug@amsat.org
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
6
7
To avoid this, we check to see what NaN mode we're running in before we call
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
hw/arm/mps2.c | 1 +
16
target/arm/helper-a64.c | 12 +++++++++---
9
1 file changed, 1 insertion(+)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
10
19
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
22
--- a/target/arm/helper-a64.c
14
+++ b/hw/arm/mps2.c
23
+++ b/target/arm/helper-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
16
0x4002a000}; /* Shield1 */
25
float16 nan = a;
17
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
26
if (float16_is_signaling_nan(a, fpst)) {
18
}
27
float_raise(float_flag_invalid, fpst);
19
+ create_unimplemented_device("i2s", 0x40024000, 0x400);
28
- nan = float16_silence_nan(a, fpst);
20
29
+ if (!fpst->default_nan_mode) {
21
/* In hardware this is a LAN9220; the LAN9118 is software compatible
30
+ nan = float16_silence_nan(a, fpst);
22
* except that it doesn't support the checksum-offload feature.
31
+ }
32
}
33
if (fpst->default_nan_mode) {
34
nan = float16_default_nan(fpst);
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
23
--
127
--
24
2.20.1
128
2.20.1
25
129
26
130
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
Since commit d70c996df23f, when enabling the PMU we get:
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
4
6
5
$ qemu-system-aarch64 -cpu host,pmu=on -M virt,accel=kvm,gic-version=3
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
6
Segmentation fault (core dumped)
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
8
Thread 1 "qemu-system-aar" received signal SIGSEGV, Segmentation fault.
10
[PMM: tweaked commit message]
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
12
---
50
target/arm/kvm_arm.h | 21 +++++++++------------
13
hw/gpio/gpio_pwr.c | 2 +-
51
target/arm/cpu.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
52
target/arm/cpu64.c | 10 +++++-----
53
target/arm/kvm.c | 4 ++--
54
target/arm/kvm64.c | 14 +++++---------
55
5 files changed, 22 insertions(+), 29 deletions(-)
56
15
57
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
58
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/kvm_arm.h
18
--- a/hw/gpio/gpio_pwr.c
60
+++ b/target/arm/kvm_arm.h
19
+++ b/hw/gpio/gpio_pwr.c
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj);
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
62
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
63
/**
64
* kvm_arm_aarch32_supported:
65
- * @cs: CPUState
66
*
67
- * Returns: true if the KVM VCPU can enable AArch32 mode
68
+ * Returns: true if KVM can enable AArch32 mode
69
* and false otherwise.
70
*/
71
-bool kvm_arm_aarch32_supported(CPUState *cs);
72
+bool kvm_arm_aarch32_supported(void);
73
74
/**
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
{
22
{
104
return false;
23
if (level) {
105
}
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
106
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
107
-static inline bool kvm_arm_pmu_supported(CPUState *cs)
108
+static inline bool kvm_arm_pmu_supported(void)
109
{
110
return false;
111
}
112
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
}
131
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/cpu64.c
134
+++ b/target/arm/cpu64.c
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
136
137
/* Collect the set of vector lengths supported by KVM. */
138
bitmap_zero(kvm_supported, ARM_MAX_VQ);
139
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
140
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
141
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
142
} else if (kvm_enabled()) {
143
assert(!cpu_isar_feature(aa64_sve, cpu));
144
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
145
return;
146
}
147
148
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
149
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
150
error_setg(errp, "cannot set sve-max-vq");
151
error_append_hint(errp, "SVE not supported by KVM on this host\n");
152
return;
153
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
154
return;
155
}
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
}
26
}
186
}
27
}
187
188
-bool kvm_arm_pmu_supported(CPUState *cpu)
189
+bool kvm_arm_pmu_supported(void)
190
{
191
- return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
192
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
193
}
194
195
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
196
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/kvm64.c
199
+++ b/target/arm/kvm64.c
200
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
201
return true;
202
}
203
204
-bool kvm_arm_aarch32_supported(CPUState *cpu)
205
+bool kvm_arm_aarch32_supported(void)
206
{
207
- KVMState *s = KVM_STATE(current_accel());
208
-
209
- return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
210
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
211
}
212
213
-bool kvm_arm_sve_supported(CPUState *cpu)
214
+bool kvm_arm_sve_supported(void)
215
{
216
- KVMState *s = KVM_STATE(current_accel());
217
-
218
- return kvm_check_extension(s, KVM_CAP_ARM_SVE);
219
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
220
}
221
222
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
223
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
224
env->features &= ~(1ULL << ARM_FEATURE_PMU);
225
}
226
if (cpu_isar_feature(aa64_sve, cpu)) {
227
- assert(kvm_arm_sve_supported(cs));
228
+ assert(kvm_arm_sve_supported());
229
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
230
}
231
28
232
--
29
--
233
2.20.1
30
2.20.1
234
31
235
32
diff view generated by jsdifflib
1
Make gen_swap_half() take a source and destination TCGv_i32 rather
1
In do_ldst(), the calculation of the offset needs to be based on the
2
than modifying the input TCGv_i32; we're going to want to be able to
2
size of the memory access, not the size of the elements in the
3
use it with the more flexible function signature, and this also
3
vector. This meant we were getting it wrong for the widening and
4
brings it into line with other functions like gen_rev16() and
4
narrowing variants of the various VLDR and VSTR insns.
5
gen_revsh().
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-12-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
10
---
9
---
11
target/arm/translate-neon.inc.c | 2 +-
10
target/arm/translate-mve.c | 17 +++++++++--------
12
target/arm/translate.c | 10 +++++-----
11
1 file changed, 9 insertions(+), 8 deletions(-)
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
12
15
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-neon.inc.c
15
--- a/target/arm/translate-mve.c
18
+++ b/target/arm/translate-neon.inc.c
16
+++ b/target/arm/translate-mve.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
20
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
18
}
21
break;
22
case 1:
23
- gen_swap_half(tmp[half]);
24
+ gen_swap_half(tmp[half], tmp[half]);
25
break;
26
case 2:
27
break;
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.c
31
+++ b/target/arm/translate.c
32
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
33
}
19
}
34
20
35
/* Swap low and high halfwords. */
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
36
-static void gen_swap_half(TCGv_i32 var)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
37
+static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
23
+ unsigned msize)
38
{
24
{
39
- tcg_gen_rotri_i32(var, var, 16);
25
TCGv_i32 addr;
40
+ tcg_gen_rotri_i32(dest, var, 16);
26
uint32_t offset;
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
28
return true;
29
}
30
31
- offset = a->imm << a->size;
32
+ offset = a->imm << msize;
33
if (!a->a) {
34
offset = -offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
38
{ NULL, NULL }
39
};
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
41
}
42
}
42
43
43
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
44
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
45
case NEON_2RM_VREV32:
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
46
switch (size) {
47
{ \
47
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
48
- case 1: gen_swap_half(tmp); break;
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
49
+ case 1: gen_swap_half(tmp, tmp); break;
50
{ NULL, gen_helper_mve_##ULD }, \
50
default: abort();
51
}; \
51
}
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
52
break;
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
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
}
54
}
60
gen_smul_dual(t1, t2);
55
61
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
62
@@ -XXX,XX +XXX,XX @@ static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
63
t1 = load_reg(s, a->rn);
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
64
t2 = load_reg(s, a->rm);
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
65
if (m_swap) {
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
66
- gen_swap_half(t2);
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
67
+ gen_swap_half(t2, t2);
62
68
}
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
69
gen_smul_dual(t1, t2);
64
{
70
71
--
65
--
72
2.20.1
66
2.20.1
73
67
74
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
In particular, fixing the second of these allows us to recast
4
Message-id: 20200617072539.32686-7-f4bug@amsat.org
11
the implementation to avoid 128-bit arithmetic entirely.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
7
---
20
---
8
hw/arm/mps2.c | 5 ++++-
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
9
1 file changed, 4 insertions(+), 1 deletion(-)
22
1 file changed, 21 insertions(+), 17 deletions(-)
10
23
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
26
--- a/target/arm/mve_helper.c
14
+++ b/hw/arm/mps2.c
27
+++ b/target/arm/mve_helper.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
28
@@ -XXX,XX +XXX,XX @@
16
MemoryRegion blockram_m2;
29
*/
17
MemoryRegion blockram_m3;
30
18
MemoryRegion sram;
31
#include "qemu/osdep.h"
19
+ /* FPGA APB subsystem */
32
-#include "qemu/int128.h"
20
MPS2SCC scc;
33
#include "cpu.h"
21
+ /* CMSDK APB subsystem */
34
#include "internals.h"
22
CMSDKAPBDualTimer dualtimer;
35
#include "vec_internal.h"
23
} MPS2MachineState;
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
24
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
25
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
38
26
g_assert_not_reached();
39
/*
40
- * Rounding multiply add long dual accumulate high: we must keep
41
- * a 72-bit internal accumulator value and return the top 64 bits.
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
27
}
81
}
28
82
29
+ /* CMSDK APB subsystem */
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
30
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
31
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
32
-
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
33
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
87
34
TYPE_CMSDK_APB_DUALTIMER);
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
35
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
36
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
90
37
qdev_get_gpio_in(armv7m, 10));
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
38
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
39
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
40
+ /* FPGA APB subsystem */
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
41
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
95
42
sccdev = DEVICE(&mms->scc);
96
/* Vector add across vector */
43
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
97
#define DO_VADDV(OP, ESIZE, TYPE) \
44
--
98
--
45
2.20.1
99
2.20.1
46
100
47
101
diff view generated by jsdifflib
1
All the other typedefs like these spell "Op" with a lowercase 'p';
1
The function asimd_imm_const() in translate-neon.c is an
2
remane the NeonGenTwoSingleOPFn and NeonGenTwoDoubleOPFn typedefs to
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
match.
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-11-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate.h | 4 ++--
10
target/arm/translate.h | 16 ++++++++++
10
target/arm/translate-a64.c | 4 ++--
11
target/arm/translate-neon.c | 63 -------------------------------------
11
target/arm/translate-neon.inc.c | 2 +-
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
12
3 files changed, 5 insertions(+), 5 deletions(-)
13
3 files changed, 73 insertions(+), 63 deletions(-)
13
14
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
20
return opc | s->be_data;
20
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
21
}
21
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
22
22
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
23
+/**
23
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
24
+typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
25
+ *
25
+typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
27
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
28
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
29
+ *
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
30
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
42
--- a/target/arm/translate-neon.c
32
+++ b/target/arm/translate-a64.c
43
+++ b/target/arm/translate-neon.c
33
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
35
TCGv_i64 tcg_zero = tcg_const_i64(0);
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
36
TCGv_i64 tcg_res = tcg_temp_new_i64();
47
37
- NeonGenTwoDoubleOPFn *genfn;
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
38
+ NeonGenTwoDoubleOpFn *genfn;
49
-{
39
bool swap = false;
50
- /*
40
int pass;
51
- * Expand the encoded constant.
41
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
42
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
53
- * We choose to not special-case this and will behave as if a
43
TCGv_i32 tcg_op = tcg_temp_new_i32();
54
- * valid constant encoding of 0 had been given.
44
TCGv_i32 tcg_zero = tcg_const_i32(0);
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
45
TCGv_i32 tcg_res = tcg_temp_new_i32();
56
- */
46
- NeonGenTwoSingleOPFn *genfn;
57
- switch (cmode) {
47
+ NeonGenTwoSingleOpFn *genfn;
58
- case 0: case 1:
48
bool swap = false;
59
- /* no-op */
49
int pass, maxpasses;
60
- break;
50
61
- case 2: case 3:
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
52
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
116
--- a/target/arm/translate.c
54
+++ b/target/arm/translate-neon.inc.c
117
+++ b/target/arm/translate.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
56
}
120
}
57
121
58
static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
59
- NeonGenTwoSingleOPFn *fn)
123
+{
60
+ NeonGenTwoSingleOpFn *fn)
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
61
{
181
{
62
/* FP operations in 2-reg-and-shift group */
63
TCGv_i32 tmp, shiftv;
64
--
182
--
65
2.20.1
183
2.20.1
66
184
67
185
diff view generated by jsdifflib
1
The NeonGenOneOpFn typedef breaks with the pattern of the other
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
NeonGen*Fn typedefs, because it is a TCGv_i64 -> TCGv_i64 operation
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
but it does not have '64' in its name. Rename it to NeonGenOne64OpFn,
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
so that the old name is available for a TCGv_i32 -> TCGv_i32 operation
4
reimplementing it all.
5
(which we will need in a subsequent commit).
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-10-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
10
---
9
---
11
target/arm/translate.h | 2 +-
10
target/arm/translate.h | 3 +-
12
target/arm/translate-a64.c | 4 ++--
11
target/arm/translate-a64.c | 86 ++++----------------------------------
13
2 files changed, 3 insertions(+), 3 deletions(-)
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
14
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
20
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
20
* VMVN and VBIC (when cmode < 14 && op == 1).
21
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
21
*
22
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
23
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
23
- * callers must catch this.
24
+typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
24
+ * callers must catch this; we return the 64-bit constant value defined
25
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
25
+ * for AArch64.
26
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
26
*
27
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
33
} else {
34
{
34
for (pass = 0; pass < maxpass; pass++) {
35
int rd = extract32(insn, 0, 5);
35
TCGv_i64 tcg_op = tcg_temp_new_i64();
36
int cmode = extract32(insn, 12, 4);
36
- NeonGenOneOpFn *genfn;
37
- int cmode_3_1 = extract32(cmode, 1, 3);
37
- static NeonGenOneOpFn * const fns[2][2] = {
38
- int cmode_0 = extract32(cmode, 0, 1);
38
+ NeonGenOne64OpFn *genfn;
39
int o2 = extract32(insn, 11, 1);
39
+ static NeonGenOne64OpFn * const fns[2][2] = {
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
40
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
41
bool is_neg = extract32(insn, 29, 1);
41
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
42
};
43
return;
44
}
45
46
- /* See AdvSIMDExpandImm() in ARM ARM */
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
131
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate.c
136
+++ b/target/arm/translate.c
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
138
case 14:
139
if (op) {
140
/*
141
- * This is the only case where the top and bottom 32 bits
142
- * of the encoded constant differ.
143
+ * This and cmode == 15 op == 1 are the only cases where
144
+ * the top and bottom 32 bits of the encoded constant differ.
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
150
break;
151
case 15:
152
+ if (op) {
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
43
--
168
--
44
2.20.1
169
2.20.1
45
170
46
171
diff view generated by jsdifflib
1
In commit cfdb2c0c95ae9205b0 ("target/arm: Vectorize SABA/UABA") we
1
Use dup_const() instead of bitfield_replicate() in
2
replaced the old handling of SABA/UABA with a vectorized implementation
2
disas_simd_mod_imm().
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
3
8
Fixes: cfdb2c0c95ae9205b0
4
(We can't replace the other use of bitfield_replicate() in this file,
5
in logic_imm_decode_wmask(), because that location needs to handle 2
6
and 4 bit elements, which dup_const() cannot.)
7
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
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>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200619171547.29780-1-peter.maydell@linaro.org
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
13
---
11
---
14
target/arm/translate-a64.c | 12 ------------
12
target/arm/translate-a64.c | 2 +-
15
1 file changed, 12 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
14
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
20
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
22
genfn(tcg_res, tcg_op1, tcg_op2);
20
/* FMOV (vector, immediate) - half-precision */
23
}
21
imm = vfp_expand_imm(MO_16, abcdefgh);
24
22
/* now duplicate across the lanes */
25
- if (opcode == 0xf) {
23
- imm = bitfield_replicate(imm, 16);
26
- /* SABA, UABA: accumulating ops */
24
+ imm = dup_const(MO_16, imm);
27
- static NeonGenTwoOpFn * const fns[3] = {
25
} else {
28
- gen_helper_neon_add_u8,
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
29
- gen_helper_neon_add_u16,
27
}
30
- tcg_gen_add_i32,
31
- };
32
-
33
- read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
34
- fns[size](tcg_res, tcg_op1, tcg_res);
35
- }
36
-
37
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
38
39
tcg_temp_free_i32(tcg_res);
40
--
28
--
41
2.20.1
29
2.20.1
42
30
43
31
diff view generated by jsdifflib
1
Convert to decodetree the insns in the Neon 2-reg-misc grouping which
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
we implement using gvec.
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
3
5
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-8-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 11 +++++++
10
target/arm/helper-mve.h | 4 +++
9
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
11
target/arm/mve.decode | 17 +++++++++++++
10
target/arm/translate.c | 35 +++++----------------
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
11
3 files changed, 74 insertions(+), 27 deletions(-)
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
12
15
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
18
--- a/target/arm/helper-mve.h
16
+++ b/target/arm/neon-dp.decode
19
+++ b/target/arm/helper-mve.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 @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
18
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
+ VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
22
+
24
+
23
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
25
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
26
+ VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
27
+ VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
29
index XXXXXXX..XXXXXXX 100644
28
+ VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
30
--- a/target/arm/mve.decode
29
+ VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
31
+++ b/target/arm/mve.decode
30
+ VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
31
+
38
+
32
+ VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
39
&vldr_vstr rn qd imm p a w size l u
33
+ VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
34
+
59
+
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
60
+# Logical immediate operations (1 reg and modified-immediate)
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
61
+
37
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
39
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-neon.inc.c
73
--- a/target/arm/mve_helper.c
41
+++ b/target/arm/translate-neon.inc.c
74
+++ b/target/arm/mve_helper.c
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
43
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
94
+
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
44
return true;
120
return true;
45
}
121
}
46
+
122
+
47
+static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
48
+{
124
+{
49
+ int vec_size = a->q ? 16 : 8;
125
+ TCGv_ptr qd;
50
+ int rd_ofs = neon_reg_offset(a->vd, 0);
126
+ uint64_t imm;
51
+ int rm_ofs = neon_reg_offset(a->vm, 0);
52
+
127
+
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
54
+ return false;
131
+ return false;
55
+ }
132
+ }
56
+
133
+ if (!mve_eci_check(s) || !vfp_access_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;
134
+ return true;
73
+ }
135
+ }
74
+
136
+
75
+ fn(a->size, rd_ofs, rm_ofs, vec_size, vec_size);
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
76
+
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
77
+ return true;
143
+ return true;
78
+}
144
+}
79
+
145
+
80
+#define DO_2MISC_VEC(INSN, FN) \
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
81
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
147
+{
82
+ { \
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
83
+ return do_2misc_vec(s, a, FN); \
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
84
+ }
168
+ }
85
+
169
+ return do_1imm(s, a, fn);
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
+}
170
+}
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
--
171
--
169
2.20.1
172
2.20.1
170
173
171
174
diff view generated by jsdifflib
1
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
group to decodetree.
2
and VQSHLU.
3
4
The size-and-immediate encoding here is the same as Neon, and we
5
handle it the same way neon-dp.decode does.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-5-peter.maydell@linaro.org
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 9 ++++
11
target/arm/helper-mve.h | 16 +++++++++++
9
target/arm/translate-neon.inc.c | 59 ++++++++++++++++++++++++
12
target/arm/mve.decode | 23 +++++++++++++++
10
target/arm/translate.c | 81 +--------------------------------
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 70 insertions(+), 79 deletions(-)
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
12
15
4 files changed, 147 insertions(+)
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
14
index XXXXXXX..XXXXXXX 100644
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
--- a/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
16
+++ b/target/arm/neon-dp.decode
19
--- a/target/arm/helper-mve.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
+++ b/target/arm/helper-mve.h
18
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
20
&2misc vm=%vm_dp vd=%vd_dp
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
21
+ @2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
22
+ &2misc vm=%vm_dp vd=%vd_dp q=0
25
+
23
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
29
+
27
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+
33
+
31
+ VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ # VQMOVUN: unsigned result (source is always signed)
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ # VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
37
+
35
+ VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+ VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
]
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
39
# Subgroup for size != 0b11
42
index XXXXXXX..XXXXXXX 100644
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
43
--- a/target/arm/mve.decode
41
index XXXXXXX..XXXXXXX 100644
44
+++ b/target/arm/mve.decode
42
--- a/target/arm/translate-neon.inc.c
45
@@ -XXX,XX +XXX,XX @@
43
+++ b/target/arm/translate-neon.inc.c
46
&2op qd qm qn size
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
47
&2scalar qd qn rm size
45
};
48
&1imm qd imm cmode op
46
return do_zip_uzp(s, a, fn[a->q][a->size]);
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
47
}
173
}
48
+
174
+
49
+static bool do_vmovn(DisasContext *s, arg_2misc *a,
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
50
+ NeonGenNarrowEnvFn *narrowfn)
176
+ bool negateshift)
51
+{
177
+{
52
+ TCGv_i64 rm;
178
+ TCGv_ptr qd, qm;
53
+ TCGv_i32 rd0, rd1;
179
+ int shift = a->shift;
54
+
180
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
56
+ return false;
184
+ return false;
57
+ }
185
+ }
58
+
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if (a->vm & 1) {
66
+ return false;
67
+ }
68
+
69
+ if (!narrowfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
187
+ return true;
75
+ }
188
+ }
76
+
189
+
77
+ rm = tcg_temp_new_i64();
190
+ /*
78
+ rd0 = tcg_temp_new_i32();
191
+ * When we handle a right shift insn using a left-shift helper
79
+ rd1 = tcg_temp_new_i32();
192
+ * which permits a negative shift count to indicate a right-shift,
80
+
193
+ * we must negate the shift count.
81
+ neon_load_reg64(rm, a->vm);
194
+ */
82
+ narrowfn(rd0, cpu_env, rm);
195
+ if (negateshift) {
83
+ neon_load_reg64(rm, a->vm + 1);
196
+ shift = -shift;
84
+ narrowfn(rd1, cpu_env, rm);
197
+ }
85
+ neon_store_reg(a->vd, 0, rd0);
198
+
86
+ neon_store_reg(a->vd, 1, rd1);
199
+ qd = mve_qreg_ptr(a->qd);
87
+ tcg_temp_free_i64(rm);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
88
+ return true;
205
+ return true;
89
+}
206
+}
90
+
207
+
91
+#define DO_VMOVN(INSN, FUNC) \
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
92
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
93
+ { \
210
+ { \
94
+ static NeonGenNarrowEnvFn * const narrowfn[] = { \
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
95
+ FUNC##8, \
212
+ gen_helper_mve_##FN##b, \
96
+ FUNC##16, \
213
+ gen_helper_mve_##FN##h, \
97
+ FUNC##32, \
214
+ gen_helper_mve_##FN##w, \
98
+ NULL, \
215
+ NULL, \
99
+ }; \
216
+ }; \
100
+ return do_vmovn(s, a, narrowfn[a->size]); \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
101
+ }
218
+ }
102
+
219
+
103
+DO_VMOVN(VMOVN, gen_neon_narrow_u)
220
+DO_2SHIFT(VSHLI, vshli_u, false)
104
+DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
105
+DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
106
+DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
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
--
224
--
228
2.20.1
225
2.20.1
229
226
230
227
diff view generated by jsdifflib
1
The functions neon_element_offset(), neon_load_element(),
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
neon_load_element64(), neon_store_element() and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
neon_store_element64() are used only in the translate-neon.inc.c
3
which perform left shifts but allow negative shift counts to indicate
4
file, so move their definitions there.
4
right shifts.
5
6
Since the .inc.c file is #included in translate.c this doesn't make
7
much difference currently, but it's a more logical place to put the
8
functions and it might be helpful if we ever decide to try to make
9
the .inc.c files genuinely separate compilation units.
10
5
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200616170844.13318-22-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
14
---
9
---
15
target/arm/translate-neon.inc.c | 101 ++++++++++++++++++++++++++++++++
10
target/arm/helper-mve.h | 12 ++++++++++++
16
target/arm/translate.c | 101 --------------------------------
11
target/arm/translate.h | 20 ++++++++++++++++++++
17
2 files changed, 101 insertions(+), 101 deletions(-)
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
18
17
19
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-neon.inc.c
20
--- a/target/arm/helper-mve.h
22
+++ b/target/arm/translate-neon.inc.c
21
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
#include "decode-neon-ls.inc.c"
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
25
#include "decode-neon-shared.inc.c"
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
26
25
27
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ * where 0 is the least significant end of the register.
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+ */
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+static inline long
29
+
31
+neon_element_offset(int reg, int element, MemOp size)
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
50
return x * 2 + 1;
51
}
52
53
+static inline int rsub_64(DisasContext *s, int x)
32
+{
54
+{
33
+ int element_size = 1 << size;
55
+ return 64 - x;
34
+ int ofs = element * element_size;
35
+#ifdef HOST_WORDS_BIGENDIAN
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
+}
56
+}
45
+
57
+
46
+static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
58
+static inline int rsub_32(DisasContext *s, int x)
47
+{
59
+{
48
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
60
+ return 32 - x;
49
+
50
+ switch (mop) {
51
+ case MO_UB:
52
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
53
+ break;
54
+ case MO_UW:
55
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
56
+ break;
57
+ case MO_UL:
58
+ tcg_gen_ld_i32(var, cpu_env, offset);
59
+ break;
60
+ default:
61
+ g_assert_not_reached();
62
+ }
63
+}
61
+}
64
+
62
+
65
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
63
+static inline int rsub_16(DisasContext *s, int x)
66
+{
64
+{
67
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
65
+ return 16 - x;
68
+
69
+ switch (mop) {
70
+ case MO_UB:
71
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
72
+ break;
73
+ case MO_UW:
74
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
75
+ break;
76
+ case MO_UL:
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
+ }
85
+}
66
+}
86
+
67
+
87
+static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
68
+static inline int rsub_8(DisasContext *s, int x)
88
+{
69
+{
89
+ long offset = neon_element_offset(reg, ele, size);
70
+ return 8 - x;
90
+
91
+ switch (size) {
92
+ case MO_8:
93
+ tcg_gen_st8_i32(var, cpu_env, offset);
94
+ break;
95
+ case MO_16:
96
+ tcg_gen_st16_i32(var, cpu_env, offset);
97
+ break;
98
+ case MO_32:
99
+ tcg_gen_st_i32(var, cpu_env, offset);
100
+ break;
101
+ default:
102
+ g_assert_not_reached();
103
+ }
104
+}
71
+}
105
+
72
+
106
+static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
107
+{
74
{
108
+ long offset = neon_element_offset(reg, ele, size);
75
return (dc->features & (1ULL << feature)) != 0;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/mve.decode
79
+++ b/target/arm/mve.decode
80
@@ -XXX,XX +XXX,XX @@
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
109
+
88
+
110
+ switch (size) {
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
111
+ case MO_8:
90
+ size=0 shift=%rshift_i3
112
+ tcg_gen_st8_i64(var, cpu_env, offset);
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
113
+ break;
92
+ size=1 shift=%rshift_i4
114
+ case MO_16:
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
115
+ tcg_gen_st16_i64(var, cpu_env, offset);
94
+ size=2 shift=%rshift_i5
116
+ break;
117
+ case MO_32:
118
+ tcg_gen_st32_i64(var, cpu_env, offset);
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
+ }
126
+}
127
+
95
+
128
static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
96
# Vector loads and stores
129
{
97
130
int opr_sz;
98
# Widening loads and narrowing stores:
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
132
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
121
--- a/target/arm/mve_helper.c
134
+++ b/target/arm/translate.c
122
+++ b/target/arm/mve_helper.c
135
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
136
return vfp_reg_offset(0, sreg);
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
137
}
163
}
138
164
139
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
165
-static inline int rsub_64(DisasContext *s, int x)
140
- * where 0 is the least significant end of the register.
141
- */
142
-static inline long
143
-neon_element_offset(int reg, int element, MemOp size)
144
-{
166
-{
145
- int element_size = 1 << size;
167
- return 64 - x;
146
- int ofs = element * element_size;
147
-#ifdef HOST_WORDS_BIGENDIAN
148
- /* Calculate the offset assuming fully little-endian,
149
- * then XOR to account for the order of the 8-byte units.
150
- */
151
- if (element_size < 8) {
152
- ofs ^= 8 - element_size;
153
- }
154
-#endif
155
- return neon_reg_offset(reg, 0) + ofs;
156
-}
168
-}
157
-
169
-
158
static TCGv_i32 neon_load_reg(int reg, int pass)
170
-static inline int rsub_32(DisasContext *s, int x)
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
-{
171
-{
167
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
172
- return 32 - x;
168
-
173
-}
169
- switch (mop) {
174
-static inline int rsub_16(DisasContext *s, int x)
170
- case MO_UB:
175
-{
171
- tcg_gen_ld8u_i32(var, cpu_env, offset);
176
- return 16 - x;
172
- break;
177
-}
173
- case MO_UW:
178
-static inline int rsub_8(DisasContext *s, int x)
174
- tcg_gen_ld16u_i32(var, cpu_env, offset);
179
-{
175
- break;
180
- return 8 - x;
176
- case MO_UL:
177
- tcg_gen_ld_i32(var, cpu_env, offset);
178
- break;
179
- default:
180
- g_assert_not_reached();
181
- }
182
-}
181
-}
183
-
182
-
184
-static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
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
{
184
{
208
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
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
--
186
--
257
2.20.1
187
2.20.1
258
188
259
189
diff view generated by jsdifflib
1
Convert the Neon VTRN insn to decodetree. This is the last insn in the
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
Neon data-processing group, so we can remove all the now-unused old
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
decoder framework.
3
and the T2 encoding is a special case where the shift count is always
4
4
equal to the element size.
5
It's possible that there's a more efficient implementation of
6
VTRN, but for this conversion we just copy the existing approach.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
11
---
9
---
12
target/arm/neon-dp.decode | 2 +-
10
target/arm/helper-mve.h | 9 +++++++
13
target/arm/translate-neon.inc.c | 90 ++++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
14
target/arm/translate.c | 363 +-------------------------------
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
15
3 files changed, 93 insertions(+), 362 deletions(-)
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
16
15
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
18
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/neon-dp.decode
19
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
-
24
+
26
+ VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
35
--- a/target/arm/mve.decode
33
+++ b/target/arm/translate-neon.inc.c
36
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
37
@@ -XXX,XX +XXX,XX @@
35
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
36
return true;
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
37
}
40
38
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
39
+{
60
+{
40
+ TCGv_i32 rd, tmp;
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
41
+
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
42
+ rd = tcg_temp_new_i32();
63
43
+ tmp = tcg_temp_new_i32();
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
44
+
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
45
+ tcg_gen_shli_i32(rd, t0, 8);
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
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
+}
67
+}
59
+
68
+
60
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
61
+{
69
+{
62
+ TCGv_i32 rd, tmp;
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
63
+
72
+
64
+ rd = tcg_temp_new_i32();
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
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
+}
74
+}
78
+
75
+
79
+static bool trans_VTRN(DisasContext *s, arg_2misc *a)
80
+{
76
+{
81
+ TCGv_i32 tmp, tmp2;
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
82
+ int pass;
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
83
+
79
+
84
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
85
+ return false;
81
+}
82
+
83
+{
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
86
+
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
88
+}
89
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
86
+ }
139
+ }
87
+
140
+
88
+ /* UNDEF accesses to D16-D31 if they don't exist. */
141
+#define DO_VSHLL_ALL(OP, TOP) \
89
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
90
+ ((a->vd | a->vm) & 0x10)) {
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
91
+ return false;
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
146
+
147
+DO_VSHLL_ALL(vshllb, false)
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
+
158
+#define DO_VSHLL(INSN, FN) \
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
92
+ }
166
+ }
93
+
167
+
94
+ if ((a->vd | a->vm) & a->q) {
168
+DO_VSHLL(VSHLL_BS, vshllbs)
95
+ return false;
169
+DO_VSHLL(VSHLL_BU, vshllbu)
96
+ }
170
+DO_VSHLL(VSHLL_TS, vshllts)
97
+
171
+DO_VSHLL(VSHLL_TU, vshlltu)
98
+ if (a->size == 3) {
99
+ return false;
100
+ }
101
+
102
+ if (!vfp_access_check(s)) {
103
+ return true;
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
+ }
125
+ }
126
+ return true;
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
133
gen_rfe(s, pc, load_cpu_field(spsr));
134
}
135
136
-static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
137
-{
138
- TCGv_i32 rd, tmp;
139
-
140
- rd = tcg_temp_new_i32();
141
- tmp = tcg_temp_new_i32();
142
-
143
- tcg_gen_shli_i32(rd, t0, 8);
144
- tcg_gen_andi_i32(rd, rd, 0xff00ff00);
145
- tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
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;
511
}
512
if (((insn >> 24) & 3) == 3) {
513
- /* Translate into the equivalent ARM encoding. */
514
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
515
- if (disas_neon_data_insn(s, insn)) {
516
- goto illegal_op;
517
- }
518
+ /* Neon DP, but failed disas_neon_dp() */
519
+ goto illegal_op;
520
} else if (((insn >> 8) & 0xe) == 10) {
521
/* VFP, but failed disas_vfp. */
522
goto illegal_op;
523
--
172
--
524
2.20.1
173
2.20.1
525
174
526
175
diff view generated by jsdifflib
1
Convert the Neon VSWP insn to decodetree. Since the new implementation
1
Implement the MVE VSRI and VSLI insns, which perform a
2
doesn't have to share a pass-loop with the other 2-reg-misc operations
2
shift-and-insert operation.
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
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-20-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
9
---
7
---
10
target/arm/neon-dp.decode | 2 ++
8
target/arm/helper-mve.h | 8 ++++++++
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
9
target/arm/mve.decode | 9 ++++++++
12
target/arm/translate.c | 5 +---
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
13
3 files changed, 44 insertions(+), 4 deletions(-)
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
14
13
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
16
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/neon-dp.decode
17
+++ b/target/arm/helper-mve.h
19
@@ -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_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
24
+
22
+
25
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-neon.inc.c
32
--- a/target/arm/mve.decode
31
+++ b/target/arm/translate-neon.inc.c
33
+++ b/target/arm/mve.decode
32
@@ -XXX,XX +XXX,XX @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
33
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
35
34
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
35
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
36
+
38
+
37
+static bool trans_VSWP(DisasContext *s, arg_2misc *a)
39
+# Shift-and-insert
38
+{
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
39
+ TCGv_i64 rm, rd;
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
40
+ int pass;
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
41
+
43
+
42
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
43
+ return false;
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
44
+ }
83
+ }
45
+
84
+
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
48
+ ((a->vd | a->vm) & 0x10)) {
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
49
+ return false;
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
50
+ }
51
+
89
+
52
+ if (a->size != 0) {
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
53
+ return false;
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
54
+ }
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
55
+
96
+
56
+ if ((a->vd | a->vm) & a->q) {
97
/*
57
+ return false;
98
* Long shifts taking half-sized inputs from top or bottom of the input
58
+ }
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
59
+
110
+
60
+ if (!vfp_access_check(s)) {
111
#define DO_VSHLL(INSN, FN) \
61
+ return true;
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
62
+ }
113
{ \
63
+
64
+ rm = tcg_temp_new_i64();
65
+ rd = tcg_temp_new_i64();
66
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
67
+ neon_load_reg64(rm, a->vm + pass);
68
+ neon_load_reg64(rd, a->vd + pass);
69
+ neon_store_reg64(rm, a->vd + pass);
70
+ neon_store_reg64(rd, a->vm + pass);
71
+ }
72
+ tcg_temp_free_i64(rm);
73
+ tcg_temp_free_i64(rd);
74
+
75
+ return true;
76
+}
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
--
114
--
101
2.20.1
115
2.20.1
102
116
103
117
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc VRINT insns to decodetree.
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
Giving these insns their own do_vrint() function allows us
2
3
to change the rounding mode just once at the start and end
3
do_urshr() is borrowed from sve_helper.c.
4
rather than doing it for every element in the vector.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-18-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
9
---
8
---
10
target/arm/neon-dp.decode | 8 +++++
9
target/arm/helper-mve.h | 10 ++++++++++
11
target/arm/translate-neon.inc.c | 61 +++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 11 +++++++++++
12
target/arm/translate.c | 31 +++--------------
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
13
3 files changed, 74 insertions(+), 26 deletions(-)
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
14
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/helper-mve.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 @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
24
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
25
+ VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
26
+ VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
27
28
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
29
+
23
+
30
+ VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+
28
+
32
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
35
+
41
+
36
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
42
+# Narrowing shifts (which only support b and h sizes)
37
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
38
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
40
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-neon.inc.c
54
--- a/target/arm/mve_helper.c
42
+++ b/target/arm/translate-neon.inc.c
55
+++ b/target/arm/mve_helper.c
43
@@ -XXX,XX +XXX,XX @@ DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
44
DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
57
45
DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
58
DO_VSHLL_ALL(vshllb, false)
46
DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
59
DO_VSHLL_ALL(vshllt, true)
47
+
60
+
48
+static bool do_vrint(DisasContext *s, arg_2misc *a, int rmode)
61
+/*
49
+{
62
+ * Narrowing right shifts, taking a double sized input, shifting it
50
+ /*
63
+ * and putting the result in either the top or bottom half of the output.
51
+ * Handle a VRINT* operation by iterating 32 bits at a time,
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
52
+ * with a specified rounding mode in operation.
65
+ */
53
+ */
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
54
+ int pass;
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
55
+ TCGv_ptr fpst;
68
+ void *vm, uint32_t shift) \
56
+ TCGv_i32 tcg_rmode;
69
+ { \
57
+
70
+ LTYPE *m = vm; \
58
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
71
+ TYPE *d = vd; \
59
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
72
+ uint16_t mask = mve_element_mask(env); \
60
+ return false;
73
+ unsigned le; \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
77
+ } \
78
+ mve_advance_vpt(env); \
61
+ }
79
+ }
62
+
80
+
63
+ /* UNDEF accesses to D16-D31 if they don't exist. */
81
+#define DO_VSHRN_ALL(OP, FN) \
64
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
65
+ ((a->vd | a->vm) & 0x10)) {
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
66
+ return false;
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
86
+
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
88
+{
89
+ if (likely(sh < 64)) {
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
91
+ } else if (sh == 64) {
92
+ return x >> 63;
93
+ } else {
94
+ return 0;
95
+ }
96
+}
97
+
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
108
+
109
+#define DO_2SHIFT_N(INSN, FN) \
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
111
+ { \
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
113
+ gen_helper_mve_##FN##b, \
114
+ gen_helper_mve_##FN##h, \
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
67
+ }
117
+ }
68
+
118
+
69
+ if (a->size != 2) {
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
70
+ /* TODO: FP16 will be the size == 1 case */
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
71
+ return false;
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
72
+ }
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
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
110
--- a/target/arm/translate.c
111
+++ b/target/arm/translate.c
112
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
113
case NEON_2RM_VCEQ0_F:
114
case NEON_2RM_VCLE0_F:
115
case NEON_2RM_VCLT0_F:
116
+ case NEON_2RM_VRINTN:
117
+ case NEON_2RM_VRINTA:
118
+ case NEON_2RM_VRINTM:
119
+ case NEON_2RM_VRINTP:
120
+ case NEON_2RM_VRINTZ:
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
}
126
neon_store_reg(rm, pass, tmp2);
127
break;
128
- case NEON_2RM_VRINTN:
129
- case NEON_2RM_VRINTA:
130
- case NEON_2RM_VRINTM:
131
- case NEON_2RM_VRINTP:
132
- case NEON_2RM_VRINTZ:
133
- {
134
- TCGv_i32 tcg_rmode;
135
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
136
- int rmode;
137
-
138
- if (op == NEON_2RM_VRINTZ) {
139
- rmode = FPROUNDING_ZERO;
140
- } else {
141
- rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
142
- }
143
-
144
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
146
- cpu_env);
147
- gen_helper_rints(tmp, tmp, fpstatus);
148
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
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
--
123
--
158
2.20.1
124
2.20.1
159
125
160
126
diff view generated by jsdifflib
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
This adds support for memory(pc-dimm) hot remove on arm/virt that
3
4
uses acpi ged device.
4
do_srshr() is borrowed from sve_helper.c.
5
5
6
NVDIMM hot removal is not yet supported.
7
8
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
13
---
9
---
14
hw/acpi/generic_event_device.c | 29 ++++++++++++++++
10
target/arm/helper-mve.h | 30 +++++++++++
15
hw/arm/virt.c | 62 ++++++++++++++++++++++++++++++++--
11
target/arm/mve.decode | 28 ++++++++++
16
2 files changed, 89 insertions(+), 2 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
17
13
target/arm/translate-mve.c | 12 +++++
18
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
14
4 files changed, 174 insertions(+)
19
index XXXXXXX..XXXXXXX 100644
15
20
--- a/hw/acpi/generic_event_device.c
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
+++ b/hw/acpi/generic_event_device.c
17
index XXXXXXX..XXXXXXX 100644
22
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
18
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
57
+++ b/target/arm/mve.decode
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
23
}
95
}
24
}
96
}
25
97
26
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
27
+ DeviceState *dev, Error **errp)
28
+{
99
+{
29
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
100
+ if (likely(sh < 64)) {
30
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
31
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
32
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
33
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
34
+ } else {
102
+ } else {
35
+ error_setg(errp, "acpi: device unplug request for unsupported device"
103
+ /* Rounding the sign bit always produces 0. */
36
+ " type: %s", object_get_typename(OBJECT(dev)));
104
+ return 0;
37
+ }
105
+ }
38
+}
106
+}
39
+
107
+
40
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
108
DO_VSHRN_ALL(vshrn, DO_SHR)
41
+ DeviceState *dev, Error **errp)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
42
+{
113
+{
43
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
114
+ if (val > max) {
44
+
115
+ *satp = true;
45
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
116
+ return max;
46
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
47
+ } else {
120
+ } else {
48
+ error_setg(errp, "acpi: device unplug for unsupported device"
121
+ return val;
49
+ " type: %s", object_get_typename(OBJECT(dev)));
50
+ }
122
+ }
51
+}
123
+}
52
+
124
+
53
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
125
+/* Saturating narrowing right shifts */
54
{
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
55
AcpiGedState *s = ACPI_GED(adev);
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
56
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
128
+ void *vm, uint32_t shift) \
57
dc->vmsd = &vmstate_acpi_ged;
129
+ { \
58
130
+ LTYPE *m = vm; \
59
hc->plug = acpi_ged_device_plug_cb;
131
+ TYPE *d = vd; \
60
+ hc->unplug_request = acpi_ged_unplug_request_cb;
132
+ uint16_t mask = mve_element_mask(env); \
61
+ hc->unplug = acpi_ged_unplug_cb;
133
+ bool qc = false; \
62
134
+ unsigned le; \
63
adevc->send_event = acpi_ged_send_event;
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
64
}
136
+ bool sat = false; \
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
66
index XXXXXXX..XXXXXXX 100644
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
67
--- a/hw/arm/virt.c
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
68
+++ b/hw/arm/virt.c
140
+ } \
69
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
141
+ if (qc) { \
70
}
142
+ env->vfp.qc[0] = qc; \
71
}
143
+ } \
72
144
+ mve_advance_vpt(env); \
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
+ }
145
+ }
84
+
146
+
85
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
86
+ error_setg(&local_err,
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
87
+ "nvdimm device hot unplug is not supported yet.");
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
88
+ goto out;
150
+
89
+ }
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
90
+
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
91
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
92
+ &local_err);
154
+
93
+out:
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
94
+ error_propagate(errp, local_err);
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
95
+}
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
96
+
158
+
97
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
98
+ DeviceState *dev, Error **errp)
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
99
+{
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
100
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
162
+
101
+ Error *local_err = NULL;
163
+#define DO_SHRN_SB(N, M, SATP) \
102
+
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
103
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
165
+#define DO_SHRN_UB(N, M, SATP) \
104
+ if (local_err) {
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
105
+ goto out;
167
+#define DO_SHRUN_B(N, M, SATP) \
106
+ }
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
107
+
169
+
108
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
170
+#define DO_SHRN_SH(N, M, SATP) \
109
+ qdev_unrealize(dev);
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
110
+
172
+#define DO_SHRN_UH(N, M, SATP) \
111
+out:
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
112
+ error_propagate(errp, local_err);
174
+#define DO_SHRUN_H(N, M, SATP) \
113
+}
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
114
+
176
+
115
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
177
+#define DO_RSHRN_SB(N, M, SATP) \
116
DeviceState *dev, Error **errp)
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
117
{
179
+#define DO_RSHRN_UB(N, M, SATP) \
118
- error_setg(errp, "device unplug request for unsupported device"
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
119
- " type: %s", object_get_typename(OBJECT(dev)));
181
+#define DO_RSHRUN_B(N, M, SATP) \
120
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
121
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
183
+
122
+ } else {
184
+#define DO_RSHRN_SH(N, M, SATP) \
123
+ error_setg(errp, "device unplug request for unsupported device"
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
124
+ " type: %s", object_get_typename(OBJECT(dev)));
186
+#define DO_RSHRN_UH(N, M, SATP) \
125
+ }
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
126
+}
188
+#define DO_RSHRUN_H(N, M, SATP) \
127
+
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
128
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
190
+
129
+ DeviceState *dev, Error **errp)
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
130
+{
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
131
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
132
+ virt_dimm_unplug(hotplug_dev, dev, errp);
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
133
+ } else {
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
134
+ error_setg(errp, "virt: device unplug for unsupported device"
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
135
+ " type: %s", object_get_typename(OBJECT(dev)));
197
+
136
+ }
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
137
}
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
138
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
139
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
140
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
141
hc->pre_plug = virt_machine_device_pre_plug_cb;
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
142
hc->plug = virt_machine_device_plug_cb;
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
143
hc->unplug_request = virt_machine_device_unplug_request_cb;
205
index XXXXXXX..XXXXXXX 100644
144
+ hc->unplug = virt_machine_device_unplug_cb;
206
--- a/target/arm/translate-mve.c
145
mc->numa_mem_supported = true;
207
+++ b/target/arm/translate-mve.c
146
mc->nvdimm_supported = true;
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
147
mc->auto_enable_numa_with_memhp = true;
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
148
--
224
--
149
2.20.1
225
2.20.1
150
226
151
227
diff view generated by jsdifflib
1
Convert the VCVT instructions in the 2-reg-misc grouping to
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
decodetree.
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
3
4
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: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-19-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
7
---
8
---
8
target/arm/neon-dp.decode | 9 +++++
9
target/arm/helper-mve.h | 2 ++
9
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 2 ++
10
target/arm/translate.c | 70 ++++-----------------------------
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 87 insertions(+), 62 deletions(-)
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
12
14
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/helper-mve.h
16
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/helper-mve.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 @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
18
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
+ VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
22
+ VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
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
+
23
+
30
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
31
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
32
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
27
--- a/target/arm/mve.decode
36
+++ b/target/arm/translate-neon.inc.c
28
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
38
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
39
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
40
DO_VRINT(VRINTP, FPROUNDING_POSINF)
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
41
+
33
+
42
+static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed)
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
46
+{
47
+ uint32_t *d = vd;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
52
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
43
+{
91
+{
44
+ /*
92
+ /*
45
+ * Handle a VCVT* operation by iterating 32 bits at a time,
93
+ * Whole Vector Left Shift with Carry. The carry is taken
46
+ * with a specified rounding mode in operation.
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
47
+ */
96
+ */
48
+ int pass;
97
+ TCGv_ptr qd;
49
+ TCGv_ptr fpst;
98
+ TCGv_i32 rdm;
50
+ TCGv_i32 tcg_rmode, tcg_shift;
51
+
99
+
52
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
53
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
54
+ return false;
101
+ return false;
55
+ }
102
+ }
56
+
103
+ if (a->rdm == 13 || a->rdm == 15) {
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
105
+ return false;
61
+ }
106
+ }
62
+
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
63
+ if (a->size != 2) {
64
+ /* TODO: FP16 will be the size == 1 case */
65
+ return false;
66
+ }
67
+
68
+ if ((a->vd | a->vm) & a->q) {
69
+ return false;
70
+ }
71
+
72
+ if (!vfp_access_check(s)) {
73
+ return true;
108
+ return true;
74
+ }
109
+ }
75
+
110
+
76
+ fpst = get_fpstatus_ptr(1);
111
+ qd = mve_qreg_ptr(a->qd);
77
+ tcg_shift = tcg_const_i32(0);
112
+ rdm = load_reg(s, a->rdm);
78
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
79
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
114
+ store_reg(s, a->rdm, rdm);
80
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
115
+ tcg_temp_free_ptr(qd);
81
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
116
+ mve_update_eci(s);
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;
117
+ return true;
95
+}
118
+}
96
+
97
+#define DO_VCVT(INSN, RMODE, SIGNED) \
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
99
+ { \
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
--
119
--
214
2.20.1
120
2.20.1
215
121
216
122
diff view generated by jsdifflib
1
Convert the pairwise ops VPADDL and VPADAL in the 2-reg-misc grouping
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
to decodetree.
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
3
stored in a pair of general-purpose registers.
4
At this point we can get rid of the weird CPU_V001 #define that was
5
used to avoid having to explicitly list all the arguments being
6
passed to some TCG gen/helper functions.
7
4
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-3-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
11
---
8
---
12
target/arm/neon-dp.decode | 6 ++
9
target/arm/helper-mve.h | 3 ++
13
target/arm/translate-neon.inc.c | 149 ++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 6 +++-
14
target/arm/translate.c | 35 +-------
11
target/arm/mve_helper.c | 19 ++++++++++++
15
3 files changed, 157 insertions(+), 33 deletions(-)
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
16
14
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
17
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/neon-dp.decode
18
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
&2misc vm=%vm_dp vd=%vd_dp
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
23
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
22
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
25
+
25
+
26
+ VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
+ VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
28
+
69
+
29
+ VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
30
+ VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
31
]
72
+
32
73
/* Shifts by immediate */
33
# Subgroup for size != 0b11
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
35
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
78
--- a/target/arm/translate-mve.c
37
+++ b/target/arm/translate-neon.inc.c
79
+++ b/target/arm/translate-mve.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
39
}
40
return true;
81
return true;
41
}
82
}
42
+
83
43
+static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
44
+ NeonGenWidenFn *widenfn,
45
+ NeonGenTwo64OpFn *opfn,
46
+ NeonGenTwo64OpFn *accfn)
47
+{
85
+{
48
+ /*
86
+ /*
49
+ * Pairwise long operations: widen both halves of the pair,
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
50
+ * combine the pairs with the opfn, and then possibly accumulate
88
+ * elements of the vector into a 64-bit result stored in
51
+ * into the destination with the accfn.
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
52
+ */
91
+ */
53
+ int pass;
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
54
+
95
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
96
+ if (!dc_isar_feature(aa32_mve, s)) {
56
+ return false;
97
+ return false;
57
+ }
98
+ }
58
+
99
+ /*
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
61
+ ((a->vd | a->vm) & 0x10)) {
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
62
+ return false;
104
+ return false;
63
+ }
105
+ }
64
+
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
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;
107
+ return true;
75
+ }
108
+ }
76
+
109
+
77
+ for (pass = 0; pass < a->q + 1; pass++) {
110
+ /*
78
+ TCGv_i32 tmp;
111
+ * This insn is subject to beat-wise execution. Partial execution
79
+ TCGv_i64 rm0_64, rm1_64, rd_64;
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
114
+ */
115
+ if (a->a || mve_skip_first_beat(s)) {
116
+ /* Accumulate input from RdaHi:RdaLo */
117
+ rda = tcg_temp_new_i64();
118
+ rdalo = load_reg(s, a->rdalo);
119
+ rdahi = load_reg(s, a->rdahi);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
126
+ }
80
+
127
+
81
+ rm0_64 = tcg_temp_new_i64();
128
+ qm = mve_qreg_ptr(a->qm);
82
+ rm1_64 = tcg_temp_new_i64();
129
+ if (a->u) {
83
+ rd_64 = tcg_temp_new_i64();
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
84
+ tmp = neon_load_reg(a->vm, pass * 2);
131
+ } else {
85
+ widenfn(rm0_64, tmp);
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
86
+ tcg_temp_free_i32(tmp);
133
+ }
87
+ tmp = neon_load_reg(a->vm, pass * 2 + 1);
134
+ tcg_temp_free_ptr(qm);
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
+
135
+
94
+ if (accfn) {
136
+ rdalo = tcg_temp_new_i32();
95
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
137
+ rdahi = tcg_temp_new_i32();
96
+ neon_load_reg64(tmp64, a->vd + pass);
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
97
+ accfn(rd_64, tmp64, rd_64);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
98
+ tcg_temp_free_i64(tmp64);
140
+ store_reg(s, a->rdalo, rdalo);
99
+ }
141
+ store_reg(s, a->rdahi, rdahi);
100
+ neon_store_reg64(rd_64, a->vd + pass);
142
+ tcg_temp_free_i64(rda);
101
+ tcg_temp_free_i64(rd_64);
143
+ mve_update_eci(s);
102
+ }
103
+ return true;
144
+ return true;
104
+}
145
+}
105
+
146
+
106
+static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a)
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
107
+{
108
+ static NeonGenWidenFn * const widenfn[] = {
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
{
148
{
203
TCGv_ptr pd, pm;
149
TCGv_ptr qd;
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
--
150
--
254
2.20.1
151
2.20.1
255
152
256
153
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc insns which are implemented with
1
The MVE extension to v8.1M includes some new shift instructions which
2
simple calls to functions that take the input, output and
2
sit entirely within the non-coprocessor part of the encoding space
3
fpstatus pointer.
3
and which operate only on general-purpose registers. They take up
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
4
23
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-16-peter.maydell@linaro.org
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
8
---
27
---
9
target/arm/translate.h | 1 +
28
target/arm/helper-mve.h | 3 ++
10
target/arm/neon-dp.decode | 8 +++++
29
target/arm/translate.h | 1 +
11
target/arm/translate-neon.inc.c | 62 +++++++++++++++++++++++++++++++++
30
target/arm/t32.decode | 28 +++++++++++++
12
target/arm/translate.c | 56 ++++-------------------------
31
target/arm/mve_helper.c | 10 +++++
13
4 files changed, 78 insertions(+), 49 deletions(-)
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
14
33
5 files changed, 132 insertions(+)
34
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
38
+++ b/target/arm/helper-mve.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
48
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
49
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
20
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
21
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
22
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
23
+typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
24
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
55
25
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
56
/**
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
57
* arm_tbflags_from_tb:
27
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
28
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/neon-dp.decode
60
--- a/target/arm/t32.decode
30
+++ b/target/arm/neon-dp.decode
61
+++ b/target/arm/t32.decode
31
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
62
@@ -XXX,XX +XXX,XX @@
32
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
63
&mcr !extern cp opc1 crn crm opc2 rt
33
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
64
&mcrr !extern cp opc1 crm rt rt2
34
65
35
+ VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
66
+&mve_shl_ri rdalo rdahi shim
36
+
67
+
37
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
38
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
39
70
+%rdahi_9 9:3 !function=times_2_plus_1
40
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
71
+%rdalo_17 17:3 !function=times_2
41
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
72
+
42
+ VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
73
# Data-processing (register)
43
+ VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
74
44
+ VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
75
%imm5_12_6 12:3 6:2
45
+ VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
76
@@ -XXX,XX +XXX,XX @@
46
+ VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
47
+ VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
48
]
79
49
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
50
# Subgroup for size != 0b11
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
82
+
52
index XXXXXXX..XXXXXXX 100644
83
{
53
--- a/target/arm/translate-neon.inc.c
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
54
+++ b/target/arm/translate-neon.inc.c
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
86
}
56
};
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
57
return do_2misc(s, a, fn[a->size]);
88
{
58
}
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
59
+
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
60
+static bool do_2misc_fp(DisasContext *s, arg_2misc *a,
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
61
+ NeonGenOneSingleOpFn *fn)
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
62
+{
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
63
+ int pass;
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
64
+ TCGv_ptr fpst;
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
65
+
96
+ [
66
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
+ return false;
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ }
100
+
70
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
71
+ /* UNDEF accesses to D16-D31 if they don't exist. */
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
72
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
73
+ ((a->vd | a->vm) & 0x10)) {
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
74
+ return false;
105
+ ]
75
+ }
106
+
76
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
77
+ if (a->size != 2) {
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
78
+ /* TODO: FP16 will be the size == 1 case */
109
}
79
+ return false;
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
80
+ }
111
index XXXXXXX..XXXXXXX 100644
81
+
112
--- a/target/arm/mve_helper.c
82
+ if ((a->vd | a->vm) & a->q) {
113
+++ b/target/arm/mve_helper.c
83
+ return false;
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
84
+ }
115
mve_advance_vpt(env);
85
+
116
return rdm;
86
+ if (!vfp_access_check(s)) {
117
}
87
+ return true;
118
+
88
+ }
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
89
+
120
+{
90
+ fpst = get_fpstatus_ptr(1);
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
91
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
122
+}
92
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
123
+
93
+ fn(tmp, tmp, fpst);
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
94
+ neon_store_reg(a->vd, pass, tmp);
125
+{
95
+ }
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
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
+}
127
+}
121
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
122
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
124
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
125
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
126
case NEON_2RM_VRSQRTE:
133
return true;
127
case NEON_2RM_VQABS:
134
}
128
case NEON_2RM_VQNEG:
135
129
+ case NEON_2RM_VRECPE_F:
136
+/*
130
+ case NEON_2RM_VRSQRTE_F:
137
+ * v8.1M MVE wide-shifts
131
+ case NEON_2RM_VCVT_FS:
138
+ */
132
+ case NEON_2RM_VCVT_FU:
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
133
+ case NEON_2RM_VCVT_SF:
140
+ WideShiftImmFn *fn)
134
+ case NEON_2RM_VCVT_UF:
141
+{
135
+ case NEON_2RM_VRINTX:
142
+ TCGv_i64 rda;
136
/* handled by decodetree */
143
+ TCGv_i32 rdalo, rdahi;
137
return 1;
144
+
138
case NEON_2RM_VTRN:
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
139
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
140
tcg_temp_free_i32(tcg_rmode);
147
+ return false;
141
break;
148
+ }
142
}
149
+ if (a->rdahi == 15) {
143
- case NEON_2RM_VRINTX:
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
144
- {
151
+ return false;
145
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
152
+ }
146
- gen_helper_rints_exact(tmp, tmp, fpstatus);
153
+ if (!dc_isar_feature(aa32_mve, s) ||
147
- tcg_temp_free_ptr(fpstatus);
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
148
- break;
155
+ a->rdahi == 13) {
149
- }
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
150
case NEON_2RM_VCVTAU:
157
+ unallocated_encoding(s);
151
case NEON_2RM_VCVTAS:
158
+ return true;
152
case NEON_2RM_VCVTNU:
159
+ }
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
160
+
154
tcg_temp_free_ptr(fpst);
161
+ if (a->shim == 0) {
155
break;
162
+ a->shim = 32;
156
}
163
+ }
157
- case NEON_2RM_VRECPE_F:
164
+
158
- {
165
+ rda = tcg_temp_new_i64();
159
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
166
+ rdalo = load_reg(s, a->rdalo);
160
- gen_helper_recpe_f32(tmp, tmp, fpstatus);
167
+ rdahi = load_reg(s, a->rdahi);
161
- tcg_temp_free_ptr(fpstatus);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
162
- break;
169
+
163
- }
170
+ fn(rda, rda, a->shim);
164
- case NEON_2RM_VRSQRTE_F:
171
+
165
- {
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
166
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
167
- gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
174
+ store_reg(s, a->rdalo, rdalo);
168
- tcg_temp_free_ptr(fpstatus);
175
+ store_reg(s, a->rdahi, rdahi);
169
- break;
176
+ tcg_temp_free_i64(rda);
170
- }
177
+
171
- case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
178
+ return true;
172
- {
179
+}
173
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
180
+
174
- gen_helper_vfp_sitos(tmp, tmp, fpstatus);
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
175
- tcg_temp_free_ptr(fpstatus);
182
+{
176
- break;
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
177
- }
184
+}
178
- case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
185
+
179
- {
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
180
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
187
+{
181
- gen_helper_vfp_uitos(tmp, tmp, fpstatus);
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
182
- tcg_temp_free_ptr(fpstatus);
189
+}
183
- break;
190
+
184
- }
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
185
- case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
192
+{
186
- {
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
187
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
194
+}
188
- gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
195
+
189
- tcg_temp_free_ptr(fpstatus);
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
190
- break;
197
+{
191
- }
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
192
- case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
199
+}
193
- {
200
+
194
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
195
- gen_helper_vfp_touizs(tmp, tmp, fpstatus);
202
+{
196
- tcg_temp_free_ptr(fpstatus);
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
197
- break;
204
+}
198
- }
205
+
199
default:
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
200
/* Reserved op values were caught by the
207
+{
201
* neon_2rm_sizes[] check earlier.
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
202
--
229
--
203
2.20.1
230
2.20.1
204
231
205
232
diff view generated by jsdifflib
1
Convert the Neon insns in the 2-reg-misc group which are
1
Implement the MVE long shifts by register, which perform shifts on a
2
VCVT between f32 and f16 to decodetree.
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
the shift count in another general-purpose register, which might be
4
either positive or negative.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
3
11
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-7-peter.maydell@linaro.org
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
7
---
15
---
8
target/arm/neon-dp.decode | 3 ++
16
target/arm/helper-mve.h | 6 +++
9
target/arm/translate-neon.inc.c | 96 +++++++++++++++++++++++++++++++++
17
target/arm/translate.h | 1 +
10
target/arm/translate.c | 65 ++--------------------
18
target/arm/t32.decode | 16 +++++--
11
3 files changed, 102 insertions(+), 62 deletions(-)
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
12
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
21
5 files changed, 182 insertions(+), 3 deletions(-)
14
index XXXXXXX..XXXXXXX 100644
22
15
--- a/target/arm/neon-dp.decode
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
+++ b/target/arm/neon-dp.decode
24
index XXXXXXX..XXXXXXX 100644
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
25
--- a/target/arm/helper-mve.h
18
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
26
+++ b/target/arm/helper-mve.h
19
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
28
21
+
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
22
+ VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
30
23
+ VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
42
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
48
49
/**
50
* arm_tbflags_from_tb:
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
55
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
57
58
&mve_shl_ri rdalo rdahi shim
59
+&mve_shl_rr rdalo rdahi rm
60
61
# rdahi: bits [3:1] from insn, bit 0 is 1
62
# rdalo: bits [3:1] from insn, bit 0 is 0
63
@@ -XXX,XX +XXX,XX @@
64
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
24
]
83
]
25
84
26
# Subgroup for size != 0b11
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
28
index XXXXXXX..XXXXXXX 100644
87
+
29
--- a/target/arm/translate-neon.inc.c
88
+ # v8.1M CSEL and friends
30
+++ b/target/arm/translate-neon.inc.c
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
90
}
32
tcg_temp_free_i32(rm1);
91
{
33
return true;
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
34
}
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
35
+
94
}
36
+static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
37
+{
96
38
+ TCGv_ptr fpst;
97
-# v8.1M CSEL and friends
39
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
40
+
99
-
41
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
100
# Data-processing (register-shifted register)
42
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
101
43
+ return false;
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
44
+ }
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
45
+
104
index XXXXXXX..XXXXXXX 100644
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
105
--- a/target/arm/mve_helper.c
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
106
+++ b/target/arm/mve_helper.c
48
+ ((a->vd | a->vm) & 0x10)) {
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
49
+ return false;
108
return rdm;
50
+ }
109
}
51
+
110
52
+ if ((a->vm & 1) || (a->size != 1)) {
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
53
+ return false;
112
+{
54
+ }
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
55
+
114
+}
56
+ if (!vfp_access_check(s)) {
115
+
57
+ return true;
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
58
+ }
117
+{
59
+
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
60
+ fpst = get_fpstatus_ptr(true);
119
+}
61
+ ahp = get_ahp_flag();
120
+
62
+ tmp = neon_load_reg(a->vm, 0);
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
63
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
122
{
64
+ tmp2 = neon_load_reg(a->vm, 1);
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
65
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
66
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
125
{
67
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
68
+ tcg_temp_free_i32(tmp);
127
}
69
+ tmp = neon_load_reg(a->vm, 2);
128
+
70
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
71
+ tmp3 = neon_load_reg(a->vm, 3);
130
+{
72
+ neon_store_reg(a->vd, 0, tmp2);
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
73
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
132
+}
74
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
133
+
75
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
76
+ neon_store_reg(a->vd, 1, tmp3);
135
+{
77
+ tcg_temp_free_i32(tmp);
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
78
+ tcg_temp_free_i32(ahp);
137
+}
79
+ tcg_temp_free_ptr(fpst);
138
+
80
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
81
+ return true;
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
82
+}
141
+ bool round, uint32_t *sat)
83
+
142
+{
84
+static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
143
+ if (shift <= -48) {
85
+{
144
+ /* Rounding the sign bit always produces 0. */
86
+ TCGv_ptr fpst;
145
+ if (round) {
87
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
146
+ return 0;
88
+
147
+ }
89
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
148
+ return src >> 63;
90
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
149
+ } else if (shift < 0) {
91
+ return false;
150
+ if (round) {
92
+ }
151
+ src >>= -shift - 1;
93
+
152
+ return (src >> 1) + (src & 1);
94
+ /* UNDEF accesses to D16-D31 if they don't exist. */
153
+ }
95
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
154
+ return src >> -shift;
96
+ ((a->vd | a->vm) & 0x10)) {
155
+ } else if (shift < 48) {
97
+ return false;
156
+ int64_t val = src << shift;
98
+ }
157
+ int64_t extval = sextract64(val, 0, 48);
99
+
158
+ if (!sat || val == extval) {
100
+ if ((a->vd & 1) || (a->size != 1)) {
159
+ return extval;
101
+ return false;
160
+ }
102
+ }
161
+ } else if (!sat || src == 0) {
103
+
162
+ return 0;
104
+ if (!vfp_access_check(s)) {
163
+ }
105
+ return true;
164
+
106
+ }
165
+ *sat = 1;
107
+
166
+ return (1ULL << 47) - (src >= 0);
108
+ fpst = get_fpstatus_ptr(true);
167
+}
109
+ ahp = get_ahp_flag();
168
+
110
+ tmp3 = tcg_temp_new_i32();
169
+/* Operate on 64-bit values, but saturate at 48 bits */
111
+ tmp = neon_load_reg(a->vm, 0);
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
112
+ tmp2 = neon_load_reg(a->vm, 1);
171
+ bool round, uint32_t *sat)
113
+ tcg_gen_ext16u_i32(tmp3, tmp);
172
+{
114
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
173
+ uint64_t val, extval;
115
+ neon_store_reg(a->vd, 0, tmp3);
174
+
116
+ tcg_gen_shri_i32(tmp, tmp, 16);
175
+ if (shift <= -(48 + round)) {
117
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
176
+ return 0;
118
+ neon_store_reg(a->vd, 1, tmp);
177
+ } else if (shift < 0) {
119
+ tmp3 = tcg_temp_new_i32();
178
+ if (round) {
120
+ tcg_gen_ext16u_i32(tmp3, tmp2);
179
+ val = src >> (-shift - 1);
121
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
180
+ val = (val >> 1) + (val & 1);
122
+ neon_store_reg(a->vd, 2, tmp3);
181
+ } else {
123
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
182
+ val = src >> -shift;
124
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
183
+ }
125
+ neon_store_reg(a->vd, 3, tmp2);
184
+ extval = extract64(val, 0, 48);
126
+ tcg_temp_free_i32(ahp);
185
+ if (!sat || val == extval) {
127
+ tcg_temp_free_ptr(fpst);
186
+ return extval;
128
+
187
+ }
129
+ return true;
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
130
+}
210
+}
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
213
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
214
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
136
int pass;
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
137
int u;
217
}
138
int vec_size;
218
139
- TCGv_i32 tmp, tmp2, tmp3;
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
140
+ TCGv_i32 tmp, tmp2;
220
+{
141
221
+ TCGv_i64 rda;
142
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
222
+ TCGv_i32 rdalo, rdahi;
143
return 1;
223
+
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
145
case NEON_2RM_VZIP:
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
146
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
226
+ return false;
147
case NEON_2RM_VSHLL:
227
+ }
148
+ case NEON_2RM_VCVT_F16_F32:
228
+ if (a->rdahi == 15) {
149
+ case NEON_2RM_VCVT_F32_F16:
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
150
/* handled by decodetree */
230
+ return false;
151
return 1;
231
+ }
152
case NEON_2RM_VTRN:
232
+ if (!dc_isar_feature(aa32_mve, s) ||
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
154
goto elementwise;
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
155
}
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
156
break;
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
157
- case NEON_2RM_VCVT_F16_F32:
237
+ unallocated_encoding(s);
158
- {
238
+ return true;
159
- TCGv_ptr fpst;
239
+ }
160
- TCGv_i32 ahp;
240
+
161
-
241
+ rda = tcg_temp_new_i64();
162
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
242
+ rdalo = load_reg(s, a->rdalo);
163
- q || (rm & 1)) {
243
+ rdahi = load_reg(s, a->rdahi);
164
- return 1;
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
165
- }
245
+
166
- fpst = get_fpstatus_ptr(true);
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
167
- ahp = get_ahp_flag();
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
168
- tmp = neon_load_reg(rm, 0);
248
+
169
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
170
- tmp2 = neon_load_reg(rm, 1);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
171
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
251
+ store_reg(s, a->rdalo, rdalo);
172
- tcg_gen_shli_i32(tmp2, tmp2, 16);
252
+ store_reg(s, a->rdahi, rdahi);
173
- tcg_gen_or_i32(tmp2, tmp2, tmp);
253
+ tcg_temp_free_i64(rda);
174
- tcg_temp_free_i32(tmp);
254
+
175
- tmp = neon_load_reg(rm, 2);
255
+ return true;
176
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
256
+}
177
- tmp3 = neon_load_reg(rm, 3);
257
+
178
- neon_store_reg(rd, 0, tmp2);
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
179
- gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
259
+{
180
- tcg_gen_shli_i32(tmp3, tmp3, 16);
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
181
- tcg_gen_or_i32(tmp3, tmp3, tmp);
261
+}
182
- neon_store_reg(rd, 1, tmp3);
262
+
183
- tcg_temp_free_i32(tmp);
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
184
- tcg_temp_free_i32(ahp);
264
+{
185
- tcg_temp_free_ptr(fpst);
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
186
- break;
266
+}
187
- }
267
+
188
- case NEON_2RM_VCVT_F32_F16:
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
189
- {
269
+{
190
- TCGv_ptr fpst;
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
191
- TCGv_i32 ahp;
271
+}
192
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
272
+
193
- q || (rd & 1)) {
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
194
- return 1;
274
+{
195
- }
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
196
- fpst = get_fpstatus_ptr(true);
276
+}
197
- ahp = get_ahp_flag();
277
+
198
- tmp3 = tcg_temp_new_i32();
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
199
- tmp = neon_load_reg(rm, 0);
279
+{
200
- tmp2 = neon_load_reg(rm, 1);
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
201
- tcg_gen_ext16u_i32(tmp3, tmp);
281
+}
202
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
282
+
203
- neon_store_reg(rd, 0, tmp3);
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
204
- tcg_gen_shri_i32(tmp, tmp, 16);
284
+{
205
- gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
206
- neon_store_reg(rd, 1, tmp);
286
+}
207
- tmp3 = tcg_temp_new_i32();
287
+
208
- tcg_gen_ext16u_i32(tmp3, tmp2);
288
/*
209
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
289
* Multiply and multiply accumulate
210
- neon_store_reg(rd, 2, tmp3);
290
*/
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
--
291
--
222
2.20.1
292
2.20.1
223
293
224
294
diff view generated by jsdifflib
1
Convert the Neon VZIP and VUZP insns in the 2-reg-misc group to
1
Implement the MVE shifts by immediate, which perform shifts
2
decodetree.
2
on a single general-purpose register.
3
4
These patterns overlap with the long-shift-by-immediates,
5
so we have to rearrange the grouping a little here.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-4-peter.maydell@linaro.org
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 3 ++
11
target/arm/helper-mve.h | 3 ++
9
target/arm/translate-neon.inc.c | 74 ++++++++++++++++++++++++++
12
target/arm/translate.h | 1 +
10
target/arm/translate.c | 92 +--------------------------------
13
target/arm/t32.decode | 31 ++++++++++++++-----
11
3 files changed, 79 insertions(+), 90 deletions(-)
14
target/arm/mve_helper.c | 10 ++++++
12
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
5 files changed, 104 insertions(+), 9 deletions(-)
14
index XXXXXXX..XXXXXXX 100644
17
15
--- a/target/arm/neon-dp.decode
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
+++ b/target/arm/neon-dp.decode
19
index XXXXXXX..XXXXXXX 100644
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
--- a/target/arm/helper-mve.h
18
21
+++ b/target/arm/helper-mve.h
19
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
20
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
21
+
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
22
+ VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
+ VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
26
+
24
]
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
26
# Subgroup for size != 0b11
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
29
--- a/target/arm/translate-neon.inc.c
32
+++ b/target/arm/translate.h
30
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
32
return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
33
accfn[a->size]);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
34
}
105
}
35
+
106
+
36
+typedef void ZipFn(TCGv_ptr, TCGv_ptr);
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
37
+
108
+{
38
+static bool do_zip_uzp(DisasContext *s, arg_2misc *a,
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
39
+ ZipFn *fn)
110
+}
40
+{
111
+
41
+ TCGv_ptr pd, pm;
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
42
+
113
+{
43
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
44
+ return false;
45
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
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;
64
+ }
65
+
66
+ pd = vfp_reg_ptr(true, a->vd);
67
+ pm = vfp_reg_ptr(true, a->vm);
68
+ fn(pd, pm);
69
+ tcg_temp_free_ptr(pd);
70
+ tcg_temp_free_ptr(pm);
71
+ return true;
72
+}
73
+
74
+static bool trans_VUZP(DisasContext *s, arg_2misc *a)
75
+{
76
+ static ZipFn * const fn[2][4] = {
77
+ {
78
+ gen_helper_neon_unzip8,
79
+ gen_helper_neon_unzip16,
80
+ NULL,
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
+
92
+static bool trans_VZIP(DisasContext *s, arg_2misc *a)
93
+{
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
+}
115
+}
109
diff --git a/target/arm/translate.c b/target/arm/translate.c
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
110
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate.c
118
--- a/target/arm/translate.c
112
+++ b/target/arm/translate.c
119
+++ b/target/arm/translate.c
113
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
114
gen_rfe(s, pc, load_cpu_field(spsr));
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
115
}
154
}
116
155
117
-static int gen_neon_unzip(int rd, int rm, int size, int q)
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
118
-{
157
+{
119
- TCGv_ptr pd, pm;
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
120
-
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
121
- if (!q && size == 2) {
160
+ return false;
122
- return 1;
161
+ }
123
- }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
124
- pd = vfp_reg_ptr(true, rd);
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
125
- pm = vfp_reg_ptr(true, rm);
164
+ a->rda == 13 || a->rda == 15) {
126
- if (q) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
127
- switch (size) {
166
+ unallocated_encoding(s);
128
- case 0:
167
+ return true;
129
- gen_helper_neon_qunzip8(pd, pm);
168
+ }
130
- break;
169
+
131
- case 1:
170
+ if (a->shim == 0) {
132
- gen_helper_neon_qunzip16(pd, pm);
171
+ a->shim = 32;
133
- break;
172
+ }
134
- case 2:
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
135
- gen_helper_neon_qunzip32(pd, pm);
174
+
136
- break;
175
+ return true;
137
- default:
176
+}
138
- abort();
177
+
139
- }
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
140
- } else {
179
+{
141
- switch (size) {
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
142
- case 0:
181
+}
143
- gen_helper_neon_unzip8(pd, pm);
182
+
144
- break;
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
145
- case 1:
184
+{
146
- gen_helper_neon_unzip16(pd, pm);
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
147
- break;
186
+}
148
- default:
187
+
149
- abort();
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
150
- }
189
+{
151
- }
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
152
- tcg_temp_free_ptr(pd);
191
+}
153
- tcg_temp_free_ptr(pm);
192
+
154
- return 0;
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
155
-}
194
+{
156
-
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
157
-static int gen_neon_zip(int rd, int rm, int size, int q)
196
+}
158
-{
197
+
159
- TCGv_ptr pd, pm;
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
160
-
199
+{
161
- if (!q && size == 2) {
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
162
- return 1;
201
+}
163
- }
202
+
164
- pd = vfp_reg_ptr(true, rd);
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
165
- pm = vfp_reg_ptr(true, rm);
204
+{
166
- if (q) {
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
167
- switch (size) {
206
+}
168
- case 0:
207
+
169
- gen_helper_neon_qzip8(pd, pm);
208
/*
170
- break;
209
* Multiply and multiply accumulate
171
- case 1:
210
*/
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
--
211
--
227
2.20.1
212
2.20.1
228
213
229
214
diff view generated by jsdifflib
Deleted patch
1
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree.
2
1
3
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
---
7
target/arm/neon-dp.decode | 2 ++
8
target/arm/translate-neon.inc.c | 52 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 35 +---------------------
10
3 files changed, 55 insertions(+), 34 deletions(-)
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
18
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
19
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
20
+
21
+ VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
22
]
23
24
# Subgroup for size != 0b11
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
28
+++ b/target/arm/translate-neon.inc.c
29
@@ -XXX,XX +XXX,XX @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
30
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
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;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ ((a->vd | a->vm) & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & 1) {
57
+ return false;
58
+ }
59
+
60
+ if (!widenfn) {
61
+ return false;
62
+ }
63
+
64
+ if (!vfp_access_check(s)) {
65
+ return true;
66
+ }
67
+
68
+ rd = tcg_temp_new_i64();
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;
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
}
92
93
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
94
-{
95
- if (u) {
96
- switch (size) {
97
- case 0: gen_helper_neon_widen_u8(dest, src); break;
98
- case 1: gen_helper_neon_widen_u16(dest, src); break;
99
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
100
- default: abort();
101
- }
102
- } else {
103
- switch (size) {
104
- case 0: gen_helper_neon_widen_s8(dest, src); break;
105
- case 1: gen_helper_neon_widen_s16(dest, src); break;
106
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
107
- default: abort();
108
- }
109
- }
110
- tcg_temp_free_i32(src);
111
-}
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;
142
case NEON_2RM_VCVT_F16_F32:
143
{
144
TCGv_ptr fpst;
145
--
146
2.20.1
147
148
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon-2-reg misc crypto ops (AESE, AESMC, SHA1H, SHA1SU1)
2
to decodetree.
3
1
4
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
---
8
target/arm/neon-dp.decode | 12 ++++++++
9
target/arm/translate-neon.inc.c | 42 ++++++++++++++++++++++++++
10
target/arm/translate.c | 52 +++------------------------------
11
3 files changed, 58 insertions(+), 48 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
&2misc vm=%vm_dp vd=%vd_dp
19
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
20
&2misc vm=%vm_dp vd=%vd_dp q=0
21
+ @2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
22
+ &2misc vm=%vm_dp vd=%vd_dp q=1
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
25
26
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
27
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
28
29
+ AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
30
+ AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
31
+ AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
32
+ AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
33
+
34
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
35
36
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
37
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
38
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
39
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
40
41
+ SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
42
+
43
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
44
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
45
46
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
47
48
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
49
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
}
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
--
191
2.20.1
192
193
diff view generated by jsdifflib
1
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group
1
Implement the MVE shifts by register, which perform
2
to decodetree.
2
shifts on a single general-purpose register.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate.h | 1 +
8
target/arm/helper-mve.h | 2 ++
9
target/arm/neon-dp.decode | 2 ++
9
target/arm/translate.h | 1 +
10
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/translate.c | 12 ++-----
11
target/arm/mve_helper.c | 10 ++++++++++
12
4 files changed, 60 insertions(+), 10 deletions(-)
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
13
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
20
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
27
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
28
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
19
uint32_t, uint32_t, uint32_t);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
20
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
21
/* Function prototype for gen_ functions for calling Neon helpers */
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
22
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
23
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
34
24
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
35
/**
25
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
36
* arm_tbflags_from_tb:
26
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
27
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/neon-dp.decode
39
--- a/target/arm/t32.decode
29
+++ b/target/arm/neon-dp.decode
40
+++ b/target/arm/t32.decode
30
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
41
@@ -XXX,XX +XXX,XX @@
31
&2misc vm=%vm_dp vd=%vd_dp q=1
42
&mve_shl_ri rdalo rdahi shim
32
43
&mve_shl_rr rdalo rdahi rm
33
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
44
&mve_sh_ri rda shim
34
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
45
+&mve_sh_rr rda rm
35
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
46
36
47
# rdahi: bits [3:1] from insn, bit 0 is 1
37
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
48
# rdalo: bits [3:1] from insn, bit 0 is 0
38
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
49
@@ -XXX,XX +XXX,XX @@
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
40
index XXXXXXX..XXXXXXX 100644
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
41
--- a/target/arm/translate-neon.inc.c
52
&mve_sh_ri shim=%imm5_12_6
42
+++ b/target/arm/translate-neon.inc.c
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
43
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
54
44
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
55
{
45
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
46
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
47
+
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
48
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
59
}
49
+{
60
50
+ int pass;
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
51
+
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
52
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
54
+ return false;
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
55
+ }
69
+ }
56
+
70
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
71
+ {
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
59
+ ((a->vd | a->vm) & 0x10)) {
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
60
+ return false;
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
61
+ }
75
+ }
62
+
76
+
63
+ if (!fn) {
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
64
+ return false;
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
65
+ }
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
87
}
66
+
88
+
67
+ if ((a->vd | a->vm) & a->q) {
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
68
+ return false;
90
+{
69
+ }
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
76
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
77
+ fn(tmp, tmp);
78
+ neon_store_reg(a->vd, pass, tmp);
79
+ }
80
+
81
+ return true;
82
+}
92
+}
83
+
93
+
84
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
85
+{
95
+{
86
+ static NeonGenOneOpFn * const fn[] = {
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
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
+}
97
+}
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
103
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate.c
100
--- a/target/arm/translate.c
105
+++ b/target/arm/translate.c
101
+++ b/target/arm/translate.c
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
107
case NEON_2RM_AESE: case NEON_2RM_AESMC:
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
108
case NEON_2RM_SHA1H:
104
}
109
case NEON_2RM_SHA1SU1:
105
110
+ case NEON_2RM_VREV32:
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
111
+ case NEON_2RM_VREV16:
107
+{
112
/* handled by decodetree */
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
113
return 1;
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
114
case NEON_2RM_VTRN:
110
+ return false;
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
111
+ }
116
for (pass = 0; pass < (q ? 4 : 2); pass++) {
112
+ if (!dc_isar_feature(aa32_mve, s) ||
117
tmp = neon_load_reg(rm, pass);
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
118
switch (op) {
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
119
- case NEON_2RM_VREV32:
115
+ a->rm == a->rda) {
120
- switch (size) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
121
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
117
+ unallocated_encoding(s);
122
- case 1: gen_swap_half(tmp, tmp); break;
118
+ return true;
123
- default: abort();
119
+ }
124
- }
120
+
125
- break;
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
126
- case NEON_2RM_VREV16:
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
127
- gen_rev16(tmp, tmp);
123
+ return true;
128
- break;
124
+}
129
case NEON_2RM_VCLS:
125
+
130
switch (size) {
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
131
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
127
+{
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
129
+}
130
+
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
132
+{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+}
135
+
136
/*
137
* Multiply and multiply accumulate
138
*/
132
--
139
--
133
2.20.1
140
2.20.1
134
141
135
142
diff view generated by jsdifflib
Deleted patch
1
Convert the remaining ops in the Neon 2-reg-misc group which
2
can be implemented simply with our do_2misc() helper.
3
1
4
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
---
8
target/arm/neon-dp.decode | 10 +++++
9
target/arm/translate-neon.inc.c | 69 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 38 ++++--------------
11
3 files changed, 86 insertions(+), 31 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
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
}
56
+
57
+static bool trans_VCLS(DisasContext *s, arg_2misc *a)
58
+{
59
+ static NeonGenOneOpFn * const fn[] = {
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
+}
67
+
68
+static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm)
69
+{
70
+ tcg_gen_clzi_i32(rd, rm, 32);
71
+}
72
+
73
+static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
74
+{
75
+ static NeonGenOneOpFn * const fn[] = {
76
+ gen_helper_neon_clz_u8,
77
+ gen_helper_neon_clz_u16,
78
+ do_VCLZ_32,
79
+ NULL,
80
+ };
81
+ return do_2misc(s, a, fn[a->size]);
82
+}
83
+
84
+static bool trans_VCNT(DisasContext *s, arg_2misc *a)
85
+{
86
+ if (a->size != 0) {
87
+ return false;
88
+ }
89
+ return do_2misc(s, a, gen_helper_neon_cnt_u8);
90
+}
91
+
92
+static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
93
+{
94
+ if (a->size != 2) {
95
+ return false;
96
+ }
97
+ /* TODO: FP16 : size == 1 */
98
+ return do_2misc(s, a, gen_helper_vfp_abss);
99
+}
100
+
101
+static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
102
+{
103
+ if (a->size != 2) {
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
--
196
2.20.1
197
198
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VQABS and VQNEG insns to decodetree.
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
1
6
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
---
10
target/arm/neon-dp.decode | 3 +++
11
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 30 ++--------------------------
13
3 files changed, 40 insertions(+), 28 deletions(-)
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
18
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
21
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
22
23
+ VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
24
+ VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
25
+
26
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
27
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
28
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
29
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-neon.inc.c
32
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
34
}
35
return do_2misc(s, a, gen_helper_rsqrte_u32);
36
}
37
+
38
+#define WRAP_1OP_ENV_FN(WRAPNAME, FUNC) \
39
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m) \
40
+ { \
41
+ FUNC(d, cpu_env, m); \
42
+ }
43
+
44
+WRAP_1OP_ENV_FN(gen_VQABS_s8, gen_helper_neon_qabs_s8)
45
+WRAP_1OP_ENV_FN(gen_VQABS_s16, gen_helper_neon_qabs_s16)
46
+WRAP_1OP_ENV_FN(gen_VQABS_s32, gen_helper_neon_qabs_s32)
47
+WRAP_1OP_ENV_FN(gen_VQNEG_s8, gen_helper_neon_qneg_s8)
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
--
121
2.20.1
122
123
diff view generated by jsdifflib
Deleted patch
1
Convert the fp-compare-with-zero insns in the Neon 2-reg-misc group to
2
decodetree.
3
1
4
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
---
8
target/arm/neon-dp.decode | 6 ++++
9
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++
10
target/arm/translate.c | 50 ++++-----------------------------
11
3 files changed, 39 insertions(+), 45 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
19
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
20
21
+ VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
22
+ VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
23
+ VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
24
+ VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
25
+ VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
26
+
27
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
28
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
35
}
36
return do_2misc_fp(s, a, gen_helper_rints_exact);
37
}
38
+
39
+#define WRAP_FP_CMP0_FWD(WRAPNAME, FUNC) \
40
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
41
+ { \
42
+ TCGv_i32 zero = tcg_const_i32(0); \
43
+ FUNC(d, m, zero, fpst); \
44
+ tcg_temp_free_i32(zero); \
45
+ }
46
+#define WRAP_FP_CMP0_REV(WRAPNAME, FUNC) \
47
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
48
+ { \
49
+ TCGv_i32 zero = tcg_const_i32(0); \
50
+ FUNC(d, zero, m, fpst); \
51
+ tcg_temp_free_i32(zero); \
52
+ }
53
+
54
+#define DO_FP_CMP0(INSN, FUNC, REV) \
55
+ WRAP_FP_CMP0_##REV(gen_##INSN, FUNC) \
56
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
57
+ { \
58
+ return do_2misc_fp(s, a, gen_##INSN); \
59
+ }
60
+
61
+DO_FP_CMP0(VCGT0_F, gen_helper_neon_cgt_f32, FWD)
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
--
135
2.20.1
136
137
diff view generated by jsdifflib
Deleted patch
1
Since commit ba3e7926691ed3 it has been unnecessary for target code
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
1
6
Many now-unnecessary calls to gen_io_end() were removed in commit
7
9e9b10c6491153b, but some were missed or accidentally added later.
8
Remove unneeded calls from the arm target:
9
10
* the call in the handling of exception-return-via-LDM is
11
unnecessary, and the code is already forcing end-of-TB
12
* the call in the VFP access check code is more complicated:
13
we weren't ending the TB, so we need to add the code to
14
force that by setting DISAS_UPDATE
15
* the doc comment for ARM_CP_IO doesn't need to mention
16
gen_io_end() any more
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
34
* migration or KVM state synchronization. (Typically this is for "registers"
35
* which are actually used as instructions for cache maintenance and so on.)
36
* IO indicates that this register does I/O and therefore its accesses
37
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
38
+ * need to be marked with gen_io_start() and also end the TB. In particular,
39
* registers which implement clocks or timers require this.
40
* RAISES_EXC is for when the read or write hook might raise an exception;
41
* the generated code will synchronize the CPU state before calling the hook
42
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate-vfp.inc.c
45
+++ b/target/arm/translate-vfp.inc.c
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
}
72
gen_helper_cpsr_write_eret(cpu_env, tmp);
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
--
80
2.20.1
81
82
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Add a trace event to see when a guest disable/enable the watchdog.
4
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
11
hw/watchdog/trace-events | 1 +
12
2 files changed, 2 insertions(+)
13
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
19
break;
20
case A_WDOGLOCK:
21
s->lock = (value != WDOG_UNLOCK_VALUE);
22
+ trace_cmsdk_apb_watchdog_lock(s->lock);
23
break;
24
case A_WDOGITCR:
25
if (s->is_luminary) {
26
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/watchdog/trace-events
29
+++ b/hw/watchdog/trace-events
30
@@ -XXX,XX +XXX,XX @@
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"
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"
33
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
34
+cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/i2c/versatile_i2c.c | 14 ++++++++++----
11
1 file changed, 10 insertions(+), 4 deletions(-)
12
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
16
+++ b/hw/i2c/versatile_i2c.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "qemu/osdep.h"
19
#include "hw/sysbus.h"
20
#include "hw/i2c/bitbang_i2c.h"
21
+#include "hw/registerfields.h"
22
#include "qemu/log.h"
23
#include "qemu/module.h"
24
25
@@ -XXX,XX +XXX,XX @@ typedef struct VersatileI2CState {
26
int in;
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
--
61
2.20.1
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
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-4-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/i2c/versatile_i2c.c | 7 +++++--
11
1 file changed, 5 insertions(+), 2 deletions(-)
12
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
16
+++ b/hw/i2c/versatile_i2c.c
17
@@ -XXX,XX +XXX,XX @@ REG32(CONTROL_GET, 0)
18
REG32(CONTROL_SET, 0)
19
REG32(CONTROL_CLR, 4)
20
21
+#define SCL BIT(0)
22
+#define SDA BIT(1)
23
+
24
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
25
unsigned size)
26
{
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
}
36
37
static const MemoryRegionOps versatile_i2c_ops = {
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/realview.c | 3 ++-
13
hw/arm/versatilepb.c | 3 ++-
14
hw/arm/vexpress.c | 3 ++-
15
3 files changed, 6 insertions(+), 3 deletions(-)
16
17
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/realview.c
20
+++ b/hw/arm/realview.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/cpu/a9mpcore.h"
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
}
32
33
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
34
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
35
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
36
i2c_create_slave(i2c, "ds1338", 0x68);
37
38
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/versatilepb.c
41
+++ b/hw/arm/versatilepb.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "sysemu/sysemu.h"
44
#include "hw/pci/pci.h"
45
#include "hw/i2c/i2c.h"
46
+#include "hw/i2c/arm_sbcon_i2c.h"
47
#include "hw/irq.h"
48
#include "hw/boards.h"
49
#include "exec/address-spaces.h"
50
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
51
/* Add PL031 Real Time Clock. */
52
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
53
54
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
55
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
56
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
57
i2c_create_slave(i2c, "ds1338", 0x68);
58
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
80
--
81
2.20.1
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
To differenciate with the CMSDK APB peripheral region,
4
rename this region 'CMSDK AHB peripheral region'.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200617072539.32686-8-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/mps2.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
17
+++ b/hw/arm/mps2.c
18
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
*/
20
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
21
0x40000000, 0x00010000);
22
- create_unimplemented_device("CMSDK peripheral region @0x40010000",
23
+ create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
24
0x40010000, 0x00010000);
25
create_unimplemented_device("Extra peripheral region @0x40020000",
26
0x40020000, 0x00010000);
27
+
28
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
29
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
30
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
We already model the CMSDK APB watchdog device, let's use it!
4
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/mps2.c | 7 +++++++
12
hw/arm/Kconfig | 1 +
13
2 files changed, 8 insertions(+)
14
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2.c
18
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
20
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
21
qdev_get_gpio_in(armv7m, 10));
22
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
23
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
24
+ TYPE_CMSDK_APB_WATCHDOG);
25
+ qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
26
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
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
35
--- a/hw/arm/Kconfig
36
+++ b/hw/arm/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config MPS2
38
select PL080 # DMA controller
39
select SPLIT_IRQ
40
select UNIMP
41
+ select CMSDK_APB_WATCHDOG
42
43
config FSL_IMX7
44
bool
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Register the GPIO peripherals as unimplemented to better
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
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 20200617072539.32686-10-f4bug@amsat.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
28
hw/arm/mps2.c | 8 ++++++--
29
1 file changed, 6 insertions(+), 2 deletions(-)
30
31
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/mps2.c
34
+++ b/hw/arm/mps2.c
35
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
36
MemoryRegion *system_memory = get_system_memory();
37
MachineClass *mc = MACHINE_GET_CLASS(machine);
38
DeviceState *armv7m, *sccdev;
39
+ int i;
40
41
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
42
error_report("This board can only be used with CPU %s",
43
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
44
*/
45
Object *orgate;
46
DeviceState *orgate_dev;
47
- int i;
48
49
orgate = object_new(TYPE_OR_IRQ);
50
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
51
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
52
*/
53
Object *orgate;
54
DeviceState *orgate_dev;
55
- int i;
56
57
orgate = object_new(TYPE_OR_IRQ);
58
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
60
default:
61
g_assert_not_reached();
62
}
63
+ for (i = 0; i < 4; i++) {
64
+ static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
65
+ 0x40012000, 0x40013000};
66
+ create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
67
+ }
68
69
/* CMSDK APB subsystem */
70
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
71
--
72
2.20.1
73
74
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/arm/mps2.c | 9 +++++++++
9
1 file changed, 9 insertions(+)
10
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
14
+++ b/hw/arm/mps2.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "hw/timer/cmsdk-apb-timer.h"
17
#include "hw/timer/cmsdk-apb-dualtimer.h"
18
#include "hw/misc/mps2-scc.h"
19
+#include "hw/misc/mps2-fpgaio.h"
20
#include "hw/net/lan9118.h"
21
#include "net/net.h"
22
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
23
24
typedef enum MPS2FPGAType {
25
FPGA_AN385,
26
@@ -XXX,XX +XXX,XX @@ typedef struct {
27
MemoryRegion sram;
28
/* FPGA APB subsystem */
29
MPS2SCC scc;
30
+ MPS2FPGAIO fpgaio;
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
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
From 'Application Note AN385', chapter 3.9, SPI:
4
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/mps2.c | 24 ++++++++++++++++++++++++
15
hw/arm/Kconfig | 6 +++---
16
2 files changed, 27 insertions(+), 3 deletions(-)
17
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2.c
21
+++ b/hw/arm/mps2.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/timer/cmsdk-apb-dualtimer.h"
24
#include "hw/misc/mps2-scc.h"
25
#include "hw/misc/mps2-fpgaio.h"
26
+#include "hw/ssi/pl022.h"
27
#include "hw/net/lan9118.h"
28
#include "net/net.h"
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
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
62
--- a/hw/arm/Kconfig
63
+++ b/hw/arm/Kconfig
64
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
65
select ARM_TIMER # sp804
66
select ARM_V7M
67
select PL011 # UART
68
- select PL022 # Serial port
69
+ select PL022 # SPI
70
select PL031 # RTC
71
select PL061 # GPIO
72
select PL310 # cache controller
73
@@ -XXX,XX +XXX,XX @@ config STELLARIS
74
select CMSDK_APB_WATCHDOG
75
select I2C
76
select PL011 # UART
77
- select PL022 # Serial port
78
+ select PL022 # SPI
79
select PL061 # GPIO
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
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
From 'Application Note AN385', chapter 3.14:
4
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/mps2.c | 8 ++++++++
15
hw/arm/Kconfig | 1 +
16
2 files changed, 9 insertions(+)
17
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2.c
21
+++ b/hw/arm/mps2.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/misc/mps2-scc.h"
24
#include "hw/misc/mps2-fpgaio.h"
25
#include "hw/ssi/pl022.h"
26
+#include "hw/i2c/arm_sbcon_i2c.h"
27
#include "hw/net/lan9118.h"
28
#include "net/net.h"
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
31
qdev_get_gpio_in(orgate_dev, j));
32
}
33
}
34
+ for (i = 0; i < 4; i++) {
35
+ static const hwaddr i2cbase[] = {0x40022000, /* Touch */
36
+ 0x40023000, /* Audio */
37
+ 0x40029000, /* Shield0 */
38
+ 0x4002a000}; /* Shield1 */
39
+ sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
40
+ }
41
42
/* In hardware this is a LAN9220; the LAN9118 is software compatible
43
* except that it doesn't support the checksum-offload feature.
44
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/Kconfig
47
+++ b/hw/arm/Kconfig
48
@@ -XXX,XX +XXX,XX @@ config MPS2
49
select SPLIT_IRQ
50
select UNIMP
51
select CMSDK_APB_WATCHDOG
52
+ select VERSATILE_I2C
53
54
config FSL_IMX7
55
bool
56
--
57
2.20.1
58
59
diff view generated by jsdifflib