1
Hopefully last target-arm queue before softfreeze;
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
this one's largest part is the remainder of the SVE patches,
3
but there are a selection of other minor things too.
4
2
5
thanks
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
6
-- PMM
7
8
The following changes since commit 109b25045b3651f9c5d02c3766c0b3ff63e6d193:
9
10
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2018-06-29 12:30:29 +0100)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180629
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
15
8
16
for you to fetch changes up to 802abf4024d23e48d45373ac3f2b580124b54b47:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
17
10
18
target/arm: Add ID_ISAR6 (2018-06-29 15:30:54 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* last of the SVE patches; SVE is now enabled for aarch64 linux-user
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
23
* sd: Don't trace SDRequest crc field (coverity bugfix)
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
24
* target/arm: Mark PMINTENSET accesses as possibly doing IO
17
* Fix some errors in SVE/SME handling of MTE tags
25
* clean up v7VE feature bit handling
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
26
* i.mx7d: minor cleanups
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
27
* target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
28
* target/arm: Implement ARMv8.2-DotProd
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
29
* virt: add addresses to dt node names (which stops dtc from
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
30
complaining that they're not correctly named)
23
* Don't assert on vmload/vmsave of M-profile CPUs
31
* cleanups: replace error_setg(&error_fatal) by error_report() + exit()
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
32
30
33
----------------------------------------------------------------
31
----------------------------------------------------------------
34
Aaron Lindsay (3):
32
Luc Michel (1):
35
target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
33
hw/arm/smmuv3: add support for stage 1 access fault
36
target/arm: Remove redundant DIV detection for KVM
37
target/arm: Mark PMINTENSET accesses as possibly doing IO
38
34
39
Alex Bennée (1):
35
Nabih Estefan (1):
40
target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
41
37
42
Eric Auger (3):
38
Peter Maydell (22):
43
device_tree: Add qemu_fdt_node_unit_path
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
44
hw/arm/virt: Silence dtc /intc warnings
40
hw/block/tc58128: Don't emit deprecation warning under qtest
45
hw/arm/virt: Silence dtc /memory warning
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
46
61
47
Jean-Christophe Dubois (3):
62
Philippe Mathieu-Daudé (5):
48
i.mx7d: Remove unused header files
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
49
i.mx7d: Change SRC unimplemented device name from sdma to src
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
50
i.mx7d: Change IRQ number type from hwaddr to int
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
66
hw/arm/stellaris: Add missing QOM 'machine' parent
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
51
68
52
Peter Maydell (1):
69
Richard Henderson (6):
53
sd: Don't trace SDRequest crc field
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
72
target/arm: Adjust and validate mtedesc sizem1
73
target/arm: Split out make_svemte_desc
74
target/arm: Handle mte in do_ldrq, do_ldro
75
target/arm: Fix SVE/SME gross MTE suppression checks
54
76
55
Philippe Mathieu-Daudé (4):
77
MAINTAINERS | 3 +-
56
hw/block/fdc: Replace error_setg(&error_abort) by assert()
78
docs/system/arm/mps2.rst | 37 +-
57
hw/arm/sysbus-fdt: Replace error_setg(&error_fatal) by error_report() + exit()
79
configs/devices/arm-softmmu/default.mak | 1 +
58
device_tree: Replace error_setg(&error_fatal) by error_report() + exit()
80
hw/arm/smmuv3-internal.h | 1 +
59
sdcard: Use the ldst API
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
60
115
61
Richard Henderson (40):
62
target/arm: Implement SVE Memory Contiguous Load Group
63
target/arm: Implement SVE Contiguous Load, first-fault and no-fault
64
target/arm: Implement SVE Memory Contiguous Store Group
65
target/arm: Implement SVE load and broadcast quadword
66
target/arm: Implement SVE integer convert to floating-point
67
target/arm: Implement SVE floating-point arithmetic (predicated)
68
target/arm: Implement SVE FP Multiply-Add Group
69
target/arm: Implement SVE Floating Point Accumulating Reduction Group
70
target/arm: Implement SVE load and broadcast element
71
target/arm: Implement SVE store vector/predicate register
72
target/arm: Implement SVE scatter stores
73
target/arm: Implement SVE prefetches
74
target/arm: Implement SVE gather loads
75
target/arm: Implement SVE first-fault gather loads
76
target/arm: Implement SVE scatter store vector immediate
77
target/arm: Implement SVE floating-point compare vectors
78
target/arm: Implement SVE floating-point arithmetic with immediate
79
target/arm: Implement SVE Floating Point Multiply Indexed Group
80
target/arm: Implement SVE FP Fast Reduction Group
81
target/arm: Implement SVE Floating Point Unary Operations - Unpredicated Group
82
target/arm: Implement SVE FP Compare with Zero Group
83
target/arm: Implement SVE floating-point trig multiply-add coefficient
84
target/arm: Implement SVE floating-point convert precision
85
target/arm: Implement SVE floating-point convert to integer
86
target/arm: Implement SVE floating-point round to integral value
87
target/arm: Implement SVE floating-point unary operations
88
target/arm: Implement SVE MOVPRFX
89
target/arm: Implement SVE floating-point complex add
90
target/arm: Implement SVE fp complex multiply add
91
target/arm: Pass index to AdvSIMD FCMLA (indexed)
92
target/arm: Implement SVE fp complex multiply add (indexed)
93
target/arm: Implement SVE dot product (vectors)
94
target/arm: Implement SVE dot product (indexed)
95
target/arm: Enable SVE for aarch64-linux-user
96
target/arm: Implement ARMv8.2-DotProd
97
target/arm: Fix SVE signed division vs x86 overflow exception
98
target/arm: Fix SVE system register access checks
99
target/arm: Prune a57 features from max
100
target/arm: Prune a15 features from max
101
target/arm: Add ID_ISAR6
102
103
include/sysemu/device_tree.h | 16 +
104
target/arm/cpu.h | 3 +
105
target/arm/helper-sve.h | 682 +++++++++++++++
106
target/arm/helper.h | 44 +-
107
device_tree.c | 78 +-
108
hw/arm/boot.c | 41 +-
109
hw/arm/fsl-imx7.c | 8 +-
110
hw/arm/mcimx7d-sabre.c | 2 -
111
hw/arm/sysbus-fdt.c | 53 +-
112
hw/arm/virt.c | 70 +-
113
hw/block/fdc.c | 9 +-
114
hw/sd/bcm2835_sdhost.c | 13 +-
115
hw/sd/core.c | 2 +-
116
hw/sd/milkymist-memcard.c | 3 +-
117
hw/sd/omap_mmc.c | 6 +-
118
hw/sd/pl181.c | 11 +-
119
hw/sd/sdhci.c | 15 +-
120
hw/sd/ssi-sd.c | 6 +-
121
linux-user/elfload.c | 2 +
122
target/arm/cpu.c | 36 +-
123
target/arm/cpu64.c | 13 +-
124
target/arm/helper.c | 44 +-
125
target/arm/kvm32.c | 27 +-
126
target/arm/sve_helper.c | 1875 +++++++++++++++++++++++++++++++++++++++++-
127
target/arm/translate-a64.c | 62 +-
128
target/arm/translate-sve.c | 1688 ++++++++++++++++++++++++++++++++++++-
129
target/arm/translate.c | 102 ++-
130
target/arm/vec_helper.c | 311 ++++++-
131
hw/sd/trace-events | 2 +-
132
target/arm/sve.decode | 427 ++++++++++
133
30 files changed, 5394 insertions(+), 257 deletions(-)
134
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use assert() instead of error_setg(&error_abort),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
Likewise, don't error_setg(&error_abort, ...), use assert().
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: John Snow <jsnow@redhat.com>
12
Message-id: 20180625165749.3910-2-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/block/fdc.c | 9 +--------
16
1 file changed, 1 insertion(+), 8 deletions(-)
17
18
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/fdc.c
21
+++ b/hw/block/fdc.c
22
@@ -XXX,XX +XXX,XX @@ static int pick_geometry(FDrive *drv)
23
nb_sectors,
24
FloppyDriveType_str(parse->drive));
25
}
26
+ assert(type_match != -1 && "misconfigured fd_format");
27
match = type_match;
28
}
29
-
30
- /* No match of any kind found -- fd_format is misconfigured, abort. */
31
- if (match == -1) {
32
- error_setg(&error_abort, "No candidate geometries present in table "
33
- " for floppy drive type '%s'",
34
- FloppyDriveType_str(drv->drive));
35
- }
36
-
37
parse = &(fd_formats[match]);
38
39
out:
40
--
41
2.17.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use error_report() + exit() instead of error_setg(&error_fatal),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
9
This fixes CID 1352173:
10
"Passing null pointer dt_name to qemu_fdt_node_path, which dereferences it."
11
12
And this also fixes:
13
14
hw/arm/sysbus-fdt.c:322:9: warning: Array access (from variable 'node_path') results in a null pointer dereference
15
if (node_path[1]) {
16
^~~~~~~~~~~~
17
18
Fixes: Coverity CID 1352173 (Dereference after null check)
19
Suggested-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Message-id: 20180625165749.3910-3-f4bug@amsat.org
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/arm/sysbus-fdt.c | 53 +++++++++++++++++++++++++--------------------
26
1 file changed, 30 insertions(+), 23 deletions(-)
27
28
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sysbus-fdt.c
31
+++ b/hw/arm/sysbus-fdt.c
32
@@ -XXX,XX +XXX,XX @@ static void copy_properties_from_host(HostProperty *props, int nb_props,
33
r = qemu_fdt_getprop(host_fdt, node_path,
34
props[i].name,
35
&prop_len,
36
- props[i].optional ? &err : &error_fatal);
37
+ &err);
38
if (r) {
39
qemu_fdt_setprop(guest_fdt, nodename,
40
props[i].name, r, prop_len);
41
} else {
42
- if (prop_len != -FDT_ERR_NOTFOUND) {
43
- /* optional property not returned although property exists */
44
- error_report_err(err);
45
- } else {
46
+ if (props[i].optional && prop_len == -FDT_ERR_NOTFOUND) {
47
+ /* optional property does not exist */
48
error_free(err);
49
+ } else {
50
+ error_report_err(err);
51
+ }
52
+ if (!props[i].optional) {
53
+ /* mandatory property not found: bail out */
54
+ exit(1);
55
}
56
}
57
}
58
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
59
60
node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
61
if (node_offset <= 0) {
62
- error_setg(&error_fatal,
63
- "not able to locate clock handle %d in host device tree",
64
- host_phandle);
65
+ error_report("not able to locate clock handle %d in host device tree",
66
+ host_phandle);
67
+ exit(1);
68
}
69
node_path = g_malloc(path_len);
70
while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
71
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
72
node_path = g_realloc(node_path, path_len);
73
}
74
if (ret < 0) {
75
- error_setg(&error_fatal,
76
- "not able to retrieve node path for clock handle %d",
77
- host_phandle);
78
+ error_report("not able to retrieve node path for clock handle %d",
79
+ host_phandle);
80
+ exit(1);
81
}
82
83
r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
84
&error_fatal);
85
if (strcmp(r, "fixed-clock")) {
86
- error_setg(&error_fatal,
87
- "clock handle %d is not a fixed clock", host_phandle);
88
+ error_report("clock handle %d is not a fixed clock", host_phandle);
89
+ exit(1);
90
}
91
92
nodename = strrchr(node_path, '/');
93
@@ -XXX,XX +XXX,XX @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
94
95
dt_name = sysfs_to_dt_name(vbasedev->name);
96
if (!dt_name) {
97
- error_setg(&error_fatal, "%s incorrect sysfs device name %s",
98
- __func__, vbasedev->name);
99
+ error_report("%s incorrect sysfs device name %s",
100
+ __func__, vbasedev->name);
101
+ exit(1);
102
}
103
node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
104
&error_fatal);
105
if (!node_path || !node_path[0]) {
106
- error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
107
- __func__, dt_name, vdev->compat);
108
+ error_report("%s unable to retrieve node path for %s/%s",
109
+ __func__, dt_name, vdev->compat);
110
+ exit(1);
111
}
112
113
if (node_path[1]) {
114
- error_setg(&error_fatal, "%s more than one node matching %s/%s!",
115
- __func__, dt_name, vdev->compat);
116
+ error_report("%s more than one node matching %s/%s!",
117
+ __func__, dt_name, vdev->compat);
118
+ exit(1);
119
}
120
121
g_free(dt_name);
122
123
if (vbasedev->num_regions != 5) {
124
- error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
125
- __func__);
126
+ error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
127
+ exit(1);
128
}
129
130
/* generate nodes for DMA_CLK and PTP_CLK */
131
r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
132
&prop_len, &error_fatal);
133
if (prop_len != 8) {
134
- error_setg(&error_fatal, "%s clocks property should contain 2 handles",
135
- __func__);
136
+ error_report("%s clocks property should contain 2 handles", __func__);
137
+ exit(1);
138
}
139
host_clock_phandles = (uint32_t *)r;
140
guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
141
--
142
2.17.1
143
144
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use error_report() + exit() instead of error_setg(&error_fatal),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
13
Message-id: 20180625165749.3910-4-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
device_tree.c | 23 +++++++++++++----------
17
1 file changed, 13 insertions(+), 10 deletions(-)
18
19
diff --git a/device_tree.c b/device_tree.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/device_tree.c
22
+++ b/device_tree.c
23
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
24
const char *parent_node;
25
26
if (strstr(dirname, root_dir) != dirname) {
27
- error_setg(&error_fatal, "%s: %s must be searched within %s",
28
- __func__, dirname, root_dir);
29
+ error_report("%s: %s must be searched within %s",
30
+ __func__, dirname, root_dir);
31
+ exit(1);
32
}
33
parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];
34
35
d = opendir(dirname);
36
if (!d) {
37
- error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
38
- return;
39
+ error_report("%s cannot open %s", __func__, dirname);
40
+ exit(1);
41
}
42
43
while ((de = readdir(d)) != NULL) {
44
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
45
tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);
46
47
if (lstat(tmpnam, &st) < 0) {
48
- error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
49
+ error_report("%s cannot lstat %s", __func__, tmpnam);
50
+ exit(1);
51
}
52
53
if (S_ISREG(st.st_mode)) {
54
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
55
gsize len;
56
57
if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
58
- error_setg(&error_fatal, "%s not able to extract info from %s",
59
- __func__, tmpnam);
60
+ error_report("%s not able to extract info from %s",
61
+ __func__, tmpnam);
62
+ exit(1);
63
}
64
65
if (strlen(parent_node) > 0) {
66
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void)
67
host_fdt = create_device_tree(&host_fdt_size);
68
read_fstree(host_fdt, SYSFS_DT_BASEDIR);
69
if (fdt_check_header(host_fdt)) {
70
- error_setg(&error_fatal,
71
- "%s host device tree extracted into memory is invalid",
72
- __func__);
73
+ error_report("%s host device tree extracted into memory is invalid",
74
+ __func__);
75
+ exit(1);
76
}
77
return host_fdt;
78
}
79
--
80
2.17.1
81
82
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The load/store API will ease further code movement.
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
connect FIQ output of the GIC CPU interfaces to the CPU.
4
5
5
Per the Physical Layer Simplified Spec. "3.6 Bus Protocol":
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
7
"In the CMD line the Most Significant Bit (MSB) is transmitted
8
first, the Least Significant Bit (LSB) is the last."
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/sd/bcm2835_sdhost.c | 13 +++++--------
11
hw/arm/xilinx_zynq.c | 2 ++
15
hw/sd/milkymist-memcard.c | 3 +--
12
1 file changed, 2 insertions(+)
16
hw/sd/omap_mmc.c | 6 ++----
17
hw/sd/pl181.c | 11 ++++-------
18
hw/sd/sdhci.c | 15 +++++----------
19
hw/sd/ssi-sd.c | 6 ++----
20
6 files changed, 19 insertions(+), 35 deletions(-)
21
13
22
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/sd/bcm2835_sdhost.c
16
--- a/hw/arm/xilinx_zynq.c
25
+++ b/hw/sd/bcm2835_sdhost.c
17
+++ b/hw/arm/xilinx_zynq.c
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
27
goto error;
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
28
}
20
sysbus_connect_irq(busdev, 0,
29
if (!(s->cmd & SDCMD_NO_RESPONSE)) {
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
30
-#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
22
+ sysbus_connect_irq(busdev, 1,
31
- | (rsp[n + 2] << 8) | rsp[n + 3])
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
32
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
24
33
goto error;
25
for (n = 0; n < 64; n++) {
34
}
26
pic[n] = qdev_get_gpio_in(dev, n);
35
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
36
goto error;
37
}
38
if (rlen == 4) {
39
- s->rsp[0] = RWORD(0);
40
+ s->rsp[0] = ldl_be_p(&rsp[0]);
41
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
42
} else {
43
- s->rsp[0] = RWORD(12);
44
- s->rsp[1] = RWORD(8);
45
- s->rsp[2] = RWORD(4);
46
- s->rsp[3] = RWORD(0);
47
+ s->rsp[0] = ldl_be_p(&rsp[12]);
48
+ s->rsp[1] = ldl_be_p(&rsp[8]);
49
+ s->rsp[2] = ldl_be_p(&rsp[4]);
50
+ s->rsp[3] = ldl_be_p(&rsp[0]);
51
}
52
-#undef RWORD
53
}
54
/* We never really delay commands, so if this was a 'busywait' command
55
* then we've completed it now and can raise the interrupt.
56
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/sd/milkymist-memcard.c
59
+++ b/hw/sd/milkymist-memcard.c
60
@@ -XXX,XX +XXX,XX @@ static void memcard_sd_command(MilkymistMemcardState *s)
61
SDRequest req;
62
63
req.cmd = s->command[0] & 0x3f;
64
- req.arg = (s->command[1] << 24) | (s->command[2] << 16)
65
- | (s->command[3] << 8) | s->command[4];
66
+ req.arg = ldl_be_p(s->command + 1);
67
req.crc = s->command[5];
68
69
s->response[0] = req.cmd;
70
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/sd/omap_mmc.c
73
+++ b/hw/sd/omap_mmc.c
74
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
75
CID_CSD_OVERWRITE;
76
if (host->sdio & (1 << 13))
77
mask |= AKE_SEQ_ERROR;
78
- rspstatus = (response[0] << 24) | (response[1] << 16) |
79
- (response[2] << 8) | (response[3] << 0);
80
+ rspstatus = ldl_be_p(response);
81
break;
82
83
case sd_r2:
84
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
85
}
86
rsplen = 4;
87
88
- rspstatus = (response[0] << 24) | (response[1] << 16) |
89
- (response[2] << 8) | (response[3] << 0);
90
+ rspstatus = ldl_be_p(response);
91
if (rspstatus & 0x80000000)
92
host->status &= 0xe000;
93
else
94
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/sd/pl181.c
97
+++ b/hw/sd/pl181.c
98
@@ -XXX,XX +XXX,XX @@ static void pl181_send_command(PL181State *s)
99
if (rlen < 0)
100
goto error;
101
if (s->cmd & PL181_CMD_RESPONSE) {
102
-#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
103
- | (response[n + 2] << 8) | response[n + 3])
104
if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
105
goto error;
106
if (rlen != 4 && rlen != 16)
107
goto error;
108
- s->response[0] = RWORD(0);
109
+ s->response[0] = ldl_be_p(&response[0]);
110
if (rlen == 4) {
111
s->response[1] = s->response[2] = s->response[3] = 0;
112
} else {
113
- s->response[1] = RWORD(4);
114
- s->response[2] = RWORD(8);
115
- s->response[3] = RWORD(12) & ~1;
116
+ s->response[1] = ldl_be_p(&response[4]);
117
+ s->response[2] = ldl_be_p(&response[8]);
118
+ s->response[3] = ldl_be_p(&response[12]) & ~1;
119
}
120
DPRINTF("Response received\n");
121
s->status |= PL181_STATUS_CMDRESPEND;
122
-#undef RWORD
123
} else {
124
DPRINTF("Command sent\n");
125
s->status |= PL181_STATUS_CMDSENT;
126
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/sd/sdhci.c
129
+++ b/hw/sd/sdhci.c
130
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
131
132
if (s->cmdreg & SDHC_CMD_RESPONSE) {
133
if (rlen == 4) {
134
- s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
135
- (response[2] << 8) | response[3];
136
+ s->rspreg[0] = ldl_be_p(response);
137
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
138
trace_sdhci_response4(s->rspreg[0]);
139
} else if (rlen == 16) {
140
- s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
141
- (response[13] << 8) | response[14];
142
- s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
143
- (response[9] << 8) | response[10];
144
- s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
145
- (response[5] << 8) | response[6];
146
+ s->rspreg[0] = ldl_be_p(&response[11]);
147
+ s->rspreg[1] = ldl_be_p(&response[7]);
148
+ s->rspreg[2] = ldl_be_p(&response[3]);
149
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
150
response[2];
151
trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
152
@@ -XXX,XX +XXX,XX @@ static void sdhci_end_transfer(SDHCIState *s)
153
trace_sdhci_end_transfer(request.cmd, request.arg);
154
sdbus_do_command(&s->sdbus, &request, response);
155
/* Auto CMD12 response goes to the upper Response register */
156
- s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
157
- (response[2] << 8) | response[3];
158
+ s->rspreg[3] = ldl_be_p(response);
159
}
160
161
s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
162
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/sd/ssi-sd.c
165
+++ b/hw/sd/ssi-sd.c
166
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
167
uint8_t longresp[16];
168
/* FIXME: Check CRC. */
169
request.cmd = s->cmd;
170
- request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
171
- | (s->cmdarg[2] << 8) | s->cmdarg[3];
172
+ request.arg = ldl_be_p(s->cmdarg);
173
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
174
s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
175
if (s->arglen <= 0) {
176
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
177
/* CMD13 returns a 2-byte statuse work. Other commands
178
only return the first byte. */
179
s->arglen = (s->cmd == 13) ? 2 : 1;
180
- cardstatus = (longresp[0] << 24) | (longresp[1] << 16)
181
- | (longresp[2] << 8) | longresp[3];
182
+ cardstatus = ldl_be_p(longresp);
183
status = 0;
184
if (((cardstatus >> 9) & 0xf) < 4)
185
status |= SSI_SDR_IDLE;
186
--
27
--
187
2.17.1
28
2.34.1
188
29
189
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This register was added to aa32 state by ARMv8.2.
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
4
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Message-id: 20180629001538.11415-6-richard.henderson@linaro.org
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/cpu.h | 1 +
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
11
target/arm/cpu.c | 4 ++++
15
1 file changed, 17 insertions(+), 12 deletions(-)
12
target/arm/cpu64.c | 2 ++
13
target/arm/helper.c | 5 ++---
14
4 files changed, 9 insertions(+), 3 deletions(-)
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/linux-user/aarch64/target_prctl.h
19
+++ b/target/arm/cpu.h
20
+++ b/linux-user/aarch64/target_prctl.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
21
uint32_t id_isar3;
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
22
uint32_t id_isar4;
23
23
uint32_t id_isar5;
24
if (cpu_isar_feature(aa64_mte, cpu)) {
24
+ uint32_t id_isar6;
25
- switch (arg2 & PR_MTE_TCF_MASK) {
25
uint64_t id_aa64pfr0;
26
- case PR_MTE_TCF_NONE:
26
uint64_t id_aa64pfr1;
27
- case PR_MTE_TCF_SYNC:
27
uint64_t id_aa64dfr0;
28
- case PR_MTE_TCF_ASYNC:
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
- break;
29
index XXXXXXX..XXXXXXX 100644
30
- default:
30
--- a/target/arm/cpu.c
31
- return -EINVAL;
31
+++ b/target/arm/cpu.c
32
- }
32
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
33
-
33
cpu->id_isar3 = 0x01111110;
34
/*
34
cpu->id_isar4 = 0x01310102;
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
35
cpu->id_isar5 = 0x00000000;
36
- * Note that the syscall values are consistent with hw.
36
+ cpu->id_isar6 = 0x00000000;
37
+ *
37
}
38
+ * The kernel has a per-cpu configuration for the sysadmin,
38
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
39
static void cortex_m4_initfn(Object *obj)
40
+ * which qemu does not implement.
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
41
+ *
41
cpu->id_isar3 = 0x01111110;
42
+ * Because there is no performance difference between the modes, and
42
cpu->id_isar4 = 0x01310102;
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
43
cpu->id_isar5 = 0x00000000;
44
+ * as the preferred mode. With this preference, and the way the API
44
+ cpu->id_isar6 = 0x00000000;
45
+ * uses only two bits, there is no way for the program to select
45
}
46
+ * ASYMM mode.
46
47
*/
47
static void cortex_m33_initfn(Object *obj)
48
- env->cp15.sctlr_el[1] =
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
49
cpu->id_isar3 = 0x01111131;
50
+ unsigned tcf = 0;
50
cpu->id_isar4 = 0x01310132;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
51
cpu->id_isar5 = 0x00000000;
52
+ tcf = 1;
52
+ cpu->id_isar6 = 0x00000000;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
53
cpu->clidr = 0x00000000;
54
+ tcf = 2;
54
cpu->ctr = 0x8000c000;
55
+ }
55
}
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
56
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
57
57
cpu->id_isar3 = 0x01112131;
58
/*
58
cpu->id_isar4 = 0x0010142;
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
59
cpu->id_isar5 = 0x0;
60
+ cpu->id_isar6 = 0x0;
61
cpu->mp_is_up = true;
62
cpu->pmsav7_dregion = 16;
63
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
69
cpu->id_isar3 = 0x01112131;
70
cpu->id_isar4 = 0x00011142;
71
cpu->id_isar5 = 0x00011121;
72
+ cpu->id_isar6 = 0;
73
cpu->id_aa64pfr0 = 0x00002222;
74
cpu->id_aa64dfr0 = 0x10305106;
75
cpu->pmceid0 = 0x00000000;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
77
cpu->id_isar3 = 0x01112131;
78
cpu->id_isar4 = 0x00011142;
79
cpu->id_isar5 = 0x00011121;
80
+ cpu->id_isar6 = 0;
81
cpu->id_aa64pfr0 = 0x00002222;
82
cpu->id_aa64dfr0 = 0x10305106;
83
cpu->id_aa64isar0 = 0x00011120;
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
89
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
90
.access = PL1_R, .type = ARM_CP_CONST,
91
.resetvalue = cpu->id_mmfr4 },
92
- /* 7 is as yet unallocated and must RAZ */
93
- { .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,
94
+ { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
95
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
96
.access = PL1_R, .type = ARM_CP_CONST,
97
- .resetvalue = 0 },
98
+ .resetvalue = cpu->id_isar6 },
99
REGINFO_SENTINEL
100
};
101
define_arm_cp_regs(cpu, v6_idregs);
102
--
60
--
103
2.17.1
61
2.34.1
104
105
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The field is encoded as [0-3], which is convenient for
4
indexing our array of function pointers, but the true
5
value is [1-4]. Adjust before calling do_mem_zpa.
6
7
Add an assert, and move the comment re passing ZT to
8
the helper back next to the relevant code.
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-28-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
9
target/arm/sve.decode | 7 +++++
19
1 file changed, 8 insertions(+), 8 deletions(-)
10
2 files changed, 66 insertions(+), 1 deletion(-)
11
20
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
23
--- a/target/arm/tcg/translate-sve.c
15
+++ b/target/arm/translate-sve.c
24
+++ b/target/arm/tcg/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
17
return true;
26
TCGv_ptr t_pg;
27
int desc = 0;
28
29
- /*
30
- * For e.g. LD4, there are not enough arguments to pass all 4
31
- * registers as pointers, so encode the regno into the data field.
32
- * For consistency, do this even for LD1.
33
- */
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
if (s->mte_active[0]) {
36
int msz = dtype_msz(dtype);
37
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
addr = clean_data_tbi(s, addr);
40
}
41
42
+ /*
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+ * registers as pointers, so encode the regno into the data field.
45
+ * For consistency, do this even for LD1.
46
+ */
47
desc = simd_desc(vsz, vsz, zt | desc);
48
t_pg = tcg_temp_new_ptr();
49
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
* accessible via the instruction encoding.
52
*/
53
assert(fn != NULL);
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
18
}
56
}
19
57
20
+/* Select active elememnts from Zn and inactive elements from Zm,
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
21
+ * storing the result in Zd.
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
22
+ */
60
if (nreg == 0) {
23
+static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
61
/* ST1 */
24
+{
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
25
+ static gen_helper_gvec_4 * const fns[4] = {
63
- nreg = 1;
26
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
64
} else {
27
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
28
+ };
66
assert(msz == esz);
29
+ unsigned vsz = vec_full_reg_size(s);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
30
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
68
}
31
+ vec_full_reg_offset(s, rn),
69
assert(fn != NULL);
32
+ vec_full_reg_offset(s, rm),
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
33
+ pred_full_reg_offset(s, pg),
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
34
+ vsz, vsz, 0, fns[esz]);
35
+}
36
+
37
#define DO_ZPZZ(NAME, name) \
38
static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a, \
39
uint32_t insn) \
40
@@ -XXX,XX +XXX,XX @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
41
return do_zpzz_ool(s, a, fns[a->esz]);
42
}
72
}
43
73
44
-DO_ZPZZ(SEL, sel)
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
45
+static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
46
+{
47
+ if (sve_access_check(s)) {
48
+ do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
49
+ }
50
+ return true;
51
+}
52
53
#undef DO_ZPZZ
54
55
@@ -XXX,XX +XXX,XX @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
56
sve_access_check(s);
57
return true;
58
}
59
+
60
+/*
61
+ * Move Prefix
62
+ *
63
+ * TODO: The implementation so far could handle predicated merging movprfx.
64
+ * The helper functions as written take an extra source register to
65
+ * use in the operation, but the result is only written when predication
66
+ * succeeds. For unpredicated movprfx, we need to rearrange the helpers
67
+ * to allow the final write back to the destination to be unconditional.
68
+ * For predicated zeroing movprfx, we need to rearrange the helpers to
69
+ * allow the final write back to zero inactives.
70
+ *
71
+ * In the meantime, just emit the moves.
72
+ */
73
+
74
+static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)
75
+{
76
+ return do_mov_z(s, a->rd, a->rn);
77
+}
78
+
79
+static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
80
+{
81
+ if (sve_access_check(s)) {
82
+ do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
83
+ }
84
+ return true;
85
+}
86
+
87
+static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
88
+{
89
+ if (sve_access_check(s)) {
90
+ do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
91
+ }
92
+ return true;
93
+}
94
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/sve.decode
97
+++ b/target/arm/sve.decode
98
@@ -XXX,XX +XXX,XX @@ ORV 00000100 .. 011 000 001 ... ..... ..... @rd_pg_rn
99
EORV 00000100 .. 011 001 001 ... ..... ..... @rd_pg_rn
100
ANDV 00000100 .. 011 010 001 ... ..... ..... @rd_pg_rn
101
102
+# SVE constructive prefix (predicated)
103
+MOVPRFX_z 00000100 .. 010 000 001 ... ..... ..... @rd_pg_rn
104
+MOVPRFX_m 00000100 .. 010 001 001 ... ..... ..... @rd_pg_rn
105
+
106
# SVE integer add reduction (predicated)
107
# Note that saddv requires size != 3.
108
UADDV 00000100 .. 000 001 001 ... ..... ..... @rd_pg_rn
109
@@ -XXX,XX +XXX,XX @@ ADR_p64 00000100 11 1 ..... 1010 .. ..... ..... @rd_rn_msz_rm
110
111
### SVE Integer Misc - Unpredicated Group
112
113
+# SVE constructive prefix (unpredicated)
114
+MOVPRFX 00000100 00 1 00000 101111 rn:5 rd:5
115
+
116
# SVE floating-point exponential accelerator
117
# Note esz != 0
118
FEXPA 00000100 .. 1 00000 101110 ..... ..... @rd_rn
119
--
75
--
120
2.17.1
76
2.34.1
121
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Enable ARM_FEATURE_SVE for the generic "max" cpu.
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
4
7
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180627043328.11531-35-richard.henderson@linaro.org
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
linux-user/elfload.c | 1 +
15
target/arm/internals.h | 2 +-
12
target/arm/cpu.c | 7 +++++++
16
target/arm/tcg/translate-sve.c | 7 ++++---
13
target/arm/cpu64.c | 1 +
17
2 files changed, 5 insertions(+), 4 deletions(-)
14
3 files changed, 9 insertions(+)
15
18
16
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/elfload.c
21
--- a/target/arm/internals.h
19
+++ b/linux-user/elfload.c
22
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
21
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
24
FIELD(MTEDESC, TCMA, 6, 2)
22
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
25
FIELD(MTEDESC, WRITE, 8, 1)
23
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
26
FIELD(MTEDESC, ALIGN, 9, 3)
24
+ GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
25
#undef GET_FEATURE
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
26
29
27
return hwcaps;
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
29
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
34
--- a/target/arm/tcg/translate-sve.c
31
+++ b/target/arm/cpu.c
35
+++ b/target/arm/tcg/translate-sve.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
33
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
37
{
34
/* and to the FP/Neon instructions */
38
unsigned vsz = vec_full_reg_size(s);
35
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
39
TCGv_ptr t_pg;
36
+ /* and to the SVE instructions */
40
+ uint32_t sizem1;
37
+ env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
41
int desc = 0;
38
+ env->cp15.cptr_el[3] |= CPTR_EZ;
42
39
+ /* with maximum vector length */
43
assert(mte_n >= 1 && mte_n <= 4);
40
+ env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
41
+ env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
42
+ env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
46
if (s->mte_active[0]) {
43
#else
47
- int msz = dtype_msz(dtype);
44
/* Reset into the highest available EL */
48
-
45
if (arm_feature(env, ARM_FEATURE_EL3)) {
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
46
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
47
index XXXXXXX..XXXXXXX 100644
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
48
--- a/target/arm/cpu64.c
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
49
+++ b/target/arm/cpu64.c
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
50
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
55
desc <<= SVE_MTEDESC_SHIFT;
52
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
56
} else {
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
57
addr = clean_data_tbi(s, addr);
54
+ set_feature(&cpu->env, ARM_FEATURE_SVE);
55
/* For usermode -cpu max we can use a larger and more efficient DCZ
56
* blocksize since we don't have to follow what the hardware does.
57
*/
58
--
58
--
59
2.17.1
59
2.34.1
60
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Share code that creates mtedesc and embeds within simd_desc.
4
5
Cc: qemu-stable@nongnu.org
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-33-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
6
[PMM: moved 'ra=%reg_movprfx' here from following patch]
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/helper.h | 5 +++
12
target/arm/tcg/translate-a64.h | 2 ++
10
target/arm/translate-sve.c | 17 ++++++++++
13
target/arm/tcg/translate-sme.c | 15 +++--------
11
target/arm/vec_helper.c | 67 ++++++++++++++++++++++++++++++++++++++
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
12
target/arm/sve.decode | 3 ++
15
3 files changed, 31 insertions(+), 33 deletions(-)
13
4 files changed, 92 insertions(+)
14
16
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
19
--- a/target/arm/tcg/translate-a64.h
18
+++ b/target/arm/helper.h
20
+++ b/target/arm/tcg/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
20
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG,
22
bool sve_access_check(DisasContext *s);
21
void, ptr, ptr, ptr, ptr, i32)
23
bool sme_enabled_check(DisasContext *s);
22
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
23
+DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
24
+DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+ uint32_t msz, bool is_write, uint32_t data);
25
+DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
26
+DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
27
+
60
+
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
29
void, ptr, ptr, ptr, ptr, i32)
62
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
32
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
67
--- a/target/arm/tcg/translate-sve.c
34
+++ b/target/arm/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
35
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
36
70
3, 2, 1, 3
37
#undef DO_ZZI
71
};
38
72
39
+static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
40
+{
74
- int dtype, uint32_t mte_n, bool is_write,
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
75
- gen_helper_gvec_mem *fn)
42
+ { gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h },
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
43
+ { gen_helper_gvec_udot_b, gen_helper_gvec_udot_h }
77
+ uint32_t msz, bool is_write, uint32_t data)
44
+ };
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
45
+
92
+
46
+ if (sve_access_check(s)) {
93
if (s->mte_active[0]) {
47
+ unsigned vsz = vec_full_reg_size(s);
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
49
+ vec_full_reg_offset(s, a->rn),
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
50
+ vec_full_reg_offset(s, a->rm),
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
51
+ vsz, vsz, 0, fns[a->u][a->sz]);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
99
desc <<= SVE_MTEDESC_SHIFT;
100
- } else {
52
+ }
101
+ }
53
+ return true;
102
+ return simd_desc(vsz, vsz, desc | data);
54
+}
103
+}
55
+
104
+
56
/*
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
57
*** SVE Floating Point Multiply-Add Indexed Group
106
+ int dtype, uint32_t nregs, bool is_write,
58
*/
107
+ gen_helper_gvec_mem *fn)
59
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
108
+{
60
index XXXXXXX..XXXXXXX 100644
109
+ TCGv_ptr t_pg;
61
--- a/target/arm/vec_helper.c
110
+ uint32_t desc;
62
+++ b/target/arm/vec_helper.c
111
+
63
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
112
+ if (!s->mte_active[0]) {
64
clear_tail(d, opr_sz, simd_maxsz(desc));
113
addr = clean_data_tbi(s, addr);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
150
+
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
65
}
153
}
66
154
67
+/* Integer 8 and 16-bit dot-product.
68
+ *
69
+ * Note that for the loops herein, host endianness does not matter
70
+ * with respect to the ordering of data within the 64-bit lanes.
71
+ * All elements are treated equally, no matter where they are.
72
+ */
73
+
74
+void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, uint32_t desc)
75
+{
76
+ intptr_t i, opr_sz = simd_oprsz(desc);
77
+ uint32_t *d = vd;
78
+ int8_t *n = vn, *m = vm;
79
+
80
+ for (i = 0; i < opr_sz / 4; ++i) {
81
+ d[i] += n[i * 4 + 0] * m[i * 4 + 0]
82
+ + n[i * 4 + 1] * m[i * 4 + 1]
83
+ + n[i * 4 + 2] * m[i * 4 + 2]
84
+ + n[i * 4 + 3] * m[i * 4 + 3];
85
+ }
86
+ clear_tail(d, opr_sz, simd_maxsz(desc));
87
+}
88
+
89
+void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, uint32_t desc)
90
+{
91
+ intptr_t i, opr_sz = simd_oprsz(desc);
92
+ uint32_t *d = vd;
93
+ uint8_t *n = vn, *m = vm;
94
+
95
+ for (i = 0; i < opr_sz / 4; ++i) {
96
+ d[i] += n[i * 4 + 0] * m[i * 4 + 0]
97
+ + n[i * 4 + 1] * m[i * 4 + 1]
98
+ + n[i * 4 + 2] * m[i * 4 + 2]
99
+ + n[i * 4 + 3] * m[i * 4 + 3];
100
+ }
101
+ clear_tail(d, opr_sz, simd_maxsz(desc));
102
+}
103
+
104
+void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, uint32_t desc)
105
+{
106
+ intptr_t i, opr_sz = simd_oprsz(desc);
107
+ uint64_t *d = vd;
108
+ int16_t *n = vn, *m = vm;
109
+
110
+ for (i = 0; i < opr_sz / 8; ++i) {
111
+ d[i] += (int64_t)n[i * 4 + 0] * m[i * 4 + 0]
112
+ + (int64_t)n[i * 4 + 1] * m[i * 4 + 1]
113
+ + (int64_t)n[i * 4 + 2] * m[i * 4 + 2]
114
+ + (int64_t)n[i * 4 + 3] * m[i * 4 + 3];
115
+ }
116
+ clear_tail(d, opr_sz, simd_maxsz(desc));
117
+}
118
+
119
+void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
120
+{
121
+ intptr_t i, opr_sz = simd_oprsz(desc);
122
+ uint64_t *d = vd;
123
+ uint16_t *n = vn, *m = vm;
124
+
125
+ for (i = 0; i < opr_sz / 8; ++i) {
126
+ d[i] += (uint64_t)n[i * 4 + 0] * m[i * 4 + 0]
127
+ + (uint64_t)n[i * 4 + 1] * m[i * 4 + 1]
128
+ + (uint64_t)n[i * 4 + 2] * m[i * 4 + 2]
129
+ + (uint64_t)n[i * 4 + 3] * m[i * 4 + 3];
130
+ }
131
+ clear_tail(d, opr_sz, simd_maxsz(desc));
132
+}
133
+
134
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
135
void *vfpst, uint32_t desc)
136
{
137
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/sve.decode
140
+++ b/target/arm/sve.decode
141
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
142
# SVE integer multiply immediate (unpredicated)
143
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
144
145
+# SVE integer dot product (unpredicated)
146
+DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
147
+
148
# SVE floating-point complex add (predicated)
149
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
150
rn=%reg_movprfx
151
--
155
--
152
2.17.1
156
2.34.1
153
154
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
5
6
Cc: qemu-stable@nongnu.org
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-9-richard.henderson@linaro.org
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/helper-sve.h | 7 +++++
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
9
target/arm/sve_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
14
1 file changed, 13 insertions(+), 2 deletions(-)
10
target/arm/translate-sve.c | 45 ++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 5 ++++
12
4 files changed, 113 insertions(+)
13
15
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
18
--- a/target/arm/tcg/translate-sve.c
17
+++ b/target/arm/helper-sve.h
19
+++ b/target/arm/tcg/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
21
unsigned vsz = vec_full_reg_size(s);
20
void, ptr, ptr, ptr, ptr, i32)
22
TCGv_ptr t_pg;
21
23
int poff;
22
+DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
24
+ uint32_t desc;
23
+ i64, i64, ptr, ptr, ptr, i32)
25
24
+DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
26
/* Load the first quadword using the normal predicated load helpers. */
25
+ i64, i64, ptr, ptr, ptr, i32)
27
+ if (!s->mte_active[0]) {
26
+DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
28
+ addr = clean_data_tbi(s, addr);
27
+ i64, i64, ptr, ptr, ptr, i32)
28
+
29
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
30
void, ptr, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
32
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/sve_helper.c
35
+++ b/target/arm/sve_helper.c
36
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
37
return predtest_ones(d, oprsz, esz_mask);
38
}
39
40
+uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
41
+ void *status, uint32_t desc)
42
+{
43
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
44
+ float16 result = nn;
45
+
46
+ do {
47
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
48
+ do {
49
+ if (pg & 1) {
50
+ float16 mm = *(float16 *)(vm + H1_2(i));
51
+ result = float16_add(result, mm, status);
52
+ }
53
+ i += sizeof(float16), pg >>= sizeof(float16);
54
+ } while (i & 15);
55
+ } while (i < opr_sz);
56
+
57
+ return result;
58
+}
59
+
60
+uint64_t HELPER(sve_fadda_s)(uint64_t nn, void *vm, void *vg,
61
+ void *status, uint32_t desc)
62
+{
63
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
64
+ float32 result = nn;
65
+
66
+ do {
67
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
68
+ do {
69
+ if (pg & 1) {
70
+ float32 mm = *(float32 *)(vm + H1_2(i));
71
+ result = float32_add(result, mm, status);
72
+ }
73
+ i += sizeof(float32), pg >>= sizeof(float32);
74
+ } while (i & 15);
75
+ } while (i < opr_sz);
76
+
77
+ return result;
78
+}
79
+
80
+uint64_t HELPER(sve_fadda_d)(uint64_t nn, void *vm, void *vg,
81
+ void *status, uint32_t desc)
82
+{
83
+ intptr_t i = 0, opr_sz = simd_oprsz(desc) / 8;
84
+ uint64_t *m = vm;
85
+ uint8_t *pg = vg;
86
+
87
+ for (i = 0; i < opr_sz; i++) {
88
+ if (pg[H1(i)] & 1) {
89
+ nn = float64_add(nn, m[i], status);
90
+ }
91
+ }
29
+ }
92
+
30
+
93
+ return nn;
31
poff = pred_full_reg_offset(s, pg);
94
+}
32
if (vsz > 16) {
95
+
33
/*
96
/* Fully general three-operand expander, controlled by a predicate,
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
97
* With the extra float_status parameter.
35
98
*/
36
gen_helper_gvec_mem *fn
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
100
index XXXXXXX..XXXXXXX 100644
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
101
--- a/target/arm/translate-sve.c
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
102
+++ b/target/arm/translate-sve.c
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
103
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
41
104
42
/* Replicate that first quadword. */
105
#undef DO_ZZI
43
if (vsz > 16) {
106
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
107
+/*
45
unsigned vsz_r32;
108
+ *** SVE Floating Point Accumulating Reduction Group
46
TCGv_ptr t_pg;
109
+ */
47
int poff, doff;
110
+
48
+ uint32_t desc;
111
+static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
49
112
+{
50
if (vsz < 32) {
113
+ typedef void fadda_fn(TCGv_i64, TCGv_i64, TCGv_ptr,
51
/*
114
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
115
+ static fadda_fn * const fns[3] = {
53
}
116
+ gen_helper_sve_fadda_h,
54
117
+ gen_helper_sve_fadda_s,
55
/* Load the first octaword using the normal predicated load helpers. */
118
+ gen_helper_sve_fadda_d,
56
+ if (!s->mte_active[0]) {
119
+ };
57
+ addr = clean_data_tbi(s, addr);
120
+ unsigned vsz = vec_full_reg_size(s);
121
+ TCGv_ptr t_rm, t_pg, t_fpst;
122
+ TCGv_i64 t_val;
123
+ TCGv_i32 t_desc;
124
+
125
+ if (a->esz == 0) {
126
+ return false;
127
+ }
58
+ }
128
+ if (!sve_access_check(s)) {
59
129
+ return true;
60
poff = pred_full_reg_offset(s, pg);
130
+ }
61
if (vsz > 32) {
131
+
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
132
+ t_val = load_esz(cpu_env, vec_reg_offset(s, a->rn, 0, a->esz), a->esz);
63
133
+ t_rm = tcg_temp_new_ptr();
64
gen_helper_gvec_mem *fn
134
+ t_pg = tcg_temp_new_ptr();
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
135
+ tcg_gen_addi_ptr(t_rm, cpu_env, vec_full_reg_offset(s, a->rm));
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
136
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
137
+ t_fpst = get_fpstatus_ptr(a->esz == MO_16);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
138
+ t_desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
69
139
+
70
/*
140
+ fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
71
* Replicate that first octaword.
141
+
142
+ tcg_temp_free_i32(t_desc);
143
+ tcg_temp_free_ptr(t_fpst);
144
+ tcg_temp_free_ptr(t_pg);
145
+ tcg_temp_free_ptr(t_rm);
146
+
147
+ write_fp_dreg(s, a->rd, t_val);
148
+ tcg_temp_free_i64(t_val);
149
+ return true;
150
+}
151
+
152
/*
153
*** SVE Floating Point Arithmetic - Unpredicated Group
154
*/
155
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/sve.decode
158
+++ b/target/arm/sve.decode
159
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
160
# SVE integer multiply immediate (unpredicated)
161
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
162
163
+### SVE FP Accumulating Reduction Group
164
+
165
+# SVE floating-point serial reduction (predicated)
166
+FADDA 01100101 .. 011 000 001 ... ..... ..... @rdn_pg_rm
167
+
168
### SVE Floating Point Arithmetic - Unpredicated Group
169
170
# SVE floating-point arithmetic (unpredicated)
171
--
72
--
172
2.17.1
73
2.34.1
173
174
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We've already added the helpers with an SVE patch, all that remains
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
is to wire up the aa64 and aa32 translators. Enable the feature
5
within -cpu max for CONFIG_USER_ONLY.
6
4
5
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180627043328.11531-36-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/cpu.h | 1 +
12
target/arm/tcg/sme_helper.c | 8 ++++----
13
linux-user/elfload.c | 1 +
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
target/arm/cpu.c | 1 +
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
target/arm/cpu64.c | 1 +
16
target/arm/translate-a64.c | 36 +++++++++++++++++++
17
target/arm/translate.c | 74 +++++++++++++++++++++++++++-----------
18
6 files changed, 93 insertions(+), 21 deletions(-)
19
15
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
18
--- a/target/arm/tcg/sme_helper.c
23
+++ b/target/arm/cpu.h
19
+++ b/target/arm/tcg/sme_helper.c
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
25
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
26
ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
22
27
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
23
/* Perform gross MTE suppression early. */
28
+ ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
24
- if (!tbi_check(desc, bit55) ||
29
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
30
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
26
+ if (!tbi_check(mtedesc, bit55) ||
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
28
mtedesc = 0;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
33
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
44
--- a/target/arm/tcg/sve_helper.c
35
+++ b/linux-user/elfload.c
45
+++ b/target/arm/tcg/sve_helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
37
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
38
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
48
39
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
49
/* Perform gross MTE suppression early. */
40
+ GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
50
- if (!tbi_check(desc, bit55) ||
41
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
42
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
52
+ if (!tbi_check(mtedesc, bit55) ||
43
#undef GET_FEATURE
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
54
mtedesc = 0;
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
49
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
50
set_feature(&cpu->env, ARM_FEATURE_CRC);
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
52
+ set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
54
#endif
55
}
55
}
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
56
57
index XXXXXXX..XXXXXXX 100644
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
58
--- a/target/arm/cpu64.c
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
59
+++ b/target/arm/cpu64.c
59
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
60
/* Perform gross MTE suppression early. */
61
set_feature(&cpu->env, ARM_FEATURE_CRC);
61
- if (!tbi_check(desc, bit55) ||
62
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
63
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
63
+ if (!tbi_check(mtedesc, bit55) ||
64
+ set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
65
mtedesc = 0;
66
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
67
set_feature(&cpu->env, ARM_FEATURE_SVE);
68
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate-a64.c
71
+++ b/target/arm/translate-a64.c
72
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
73
vec_full_reg_size(s), gvec_op);
74
}
75
76
+/* Expand a 3-operand operation using an out-of-line helper. */
77
+static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
78
+ int rn, int rm, int data, gen_helper_gvec_3 *fn)
79
+{
80
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
81
+ vec_full_reg_offset(s, rn),
82
+ vec_full_reg_offset(s, rm),
83
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
84
+}
85
+
86
/* Expand a 3-operand + env pointer operation using
87
* an out-of-line helper.
88
*/
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
90
}
91
feature = ARM_FEATURE_V8_RDM;
92
break;
93
+ case 0x02: /* SDOT (vector) */
94
+ case 0x12: /* UDOT (vector) */
95
+ if (size != MO_32) {
96
+ unallocated_encoding(s);
97
+ return;
98
+ }
99
+ feature = ARM_FEATURE_V8_DOTPROD;
100
+ break;
101
case 0x8: /* FCMLA, #0 */
102
case 0x9: /* FCMLA, #90 */
103
case 0xa: /* FCMLA, #180 */
104
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
105
}
106
return;
107
108
+ case 0x2: /* SDOT / UDOT */
109
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0,
110
+ u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
111
+ return;
112
+
113
case 0x8: /* FCMLA, #0 */
114
case 0x9: /* FCMLA, #90 */
115
case 0xa: /* FCMLA, #180 */
116
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
117
return;
118
}
119
break;
120
+ case 0x0e: /* SDOT */
121
+ case 0x1e: /* UDOT */
122
+ if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
123
+ unallocated_encoding(s);
124
+ return;
125
+ }
126
+ break;
127
case 0x11: /* FCMLA #0 */
128
case 0x13: /* FCMLA #90 */
129
case 0x15: /* FCMLA #180 */
130
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
131
}
66
}
132
67
133
switch (16 * u + opcode) {
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
134
+ case 0x0e: /* SDOT */
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
135
+ case 0x1e: /* UDOT */
70
136
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, index,
71
/* Perform gross MTE suppression early. */
137
+ u ? gen_helper_gvec_udot_idx_b
72
- if (!tbi_check(desc, bit55) ||
138
+ : gen_helper_gvec_sdot_idx_b);
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
139
+ return;
74
+ if (!tbi_check(mtedesc, bit55) ||
140
case 0x11: /* FCMLA #0 */
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
141
case 0x13: /* FCMLA #90 */
76
mtedesc = 0;
142
case 0x15: /* FCMLA #180 */
143
diff --git a/target/arm/translate.c b/target/arm/translate.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate.c
146
+++ b/target/arm/translate.c
147
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
148
*/
149
static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
150
{
151
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
152
- int rd, rn, rm, rot, size, opr_sz;
153
- TCGv_ptr fpst;
154
+ gen_helper_gvec_3 *fn_gvec = NULL;
155
+ gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
156
+ int rd, rn, rm, opr_sz;
157
+ int data = 0;
158
bool q;
159
160
q = extract32(insn, 6, 1);
161
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
162
163
if ((insn & 0xfe200f10) == 0xfc200800) {
164
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
165
- size = extract32(insn, 20, 1);
166
- rot = extract32(insn, 23, 2);
167
+ int size = extract32(insn, 20, 1);
168
+ data = extract32(insn, 23, 2); /* rot */
169
if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
170
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
171
return 1;
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
173
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
174
} else if ((insn & 0xfea00f10) == 0xfc800800) {
175
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
176
- size = extract32(insn, 20, 1);
177
- rot = extract32(insn, 24, 1);
178
+ int size = extract32(insn, 20, 1);
179
+ data = extract32(insn, 24, 1); /* rot */
180
if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
181
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
182
return 1;
183
}
184
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
185
+ } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
186
+ /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
187
+ bool u = extract32(insn, 4, 1);
188
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
189
+ return 1;
190
+ }
191
+ fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
192
} else {
193
return 1;
194
}
77
}
195
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
196
}
197
198
opr_sz = (1 + q) * 8;
199
- fpst = get_fpstatus_ptr(1);
200
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
201
- vfp_reg_offset(1, rn),
202
- vfp_reg_offset(1, rm), fpst,
203
- opr_sz, opr_sz, rot, fn_gvec_ptr);
204
- tcg_temp_free_ptr(fpst);
205
+ if (fn_gvec_ptr) {
206
+ TCGv_ptr fpst = get_fpstatus_ptr(1);
207
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
208
+ vfp_reg_offset(1, rn),
209
+ vfp_reg_offset(1, rm), fpst,
210
+ opr_sz, opr_sz, data, fn_gvec_ptr);
211
+ tcg_temp_free_ptr(fpst);
212
+ } else {
213
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
214
+ vfp_reg_offset(1, rn),
215
+ vfp_reg_offset(1, rm),
216
+ opr_sz, opr_sz, data, fn_gvec);
217
+ }
218
return 0;
219
}
220
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
222
223
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
224
{
225
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
226
+ gen_helper_gvec_3 *fn_gvec = NULL;
227
+ gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
228
int rd, rn, rm, opr_sz, data;
229
- TCGv_ptr fpst;
230
bool q;
231
232
q = extract32(insn, 6, 1);
233
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
234
data = (index << 2) | rot;
235
fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
236
: gen_helper_gvec_fcmlah_idx);
237
+ } else if ((insn & 0xffb00f00) == 0xfe200d00) {
238
+ /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
239
+ int u = extract32(insn, 4, 1);
240
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
241
+ return 1;
242
+ }
243
+ fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
244
+ /* rm is just Vm, and index is M. */
245
+ data = extract32(insn, 5, 1); /* index */
246
+ rm = extract32(insn, 0, 4);
247
} else {
248
return 1;
249
}
250
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
251
}
252
253
opr_sz = (1 + q) * 8;
254
- fpst = get_fpstatus_ptr(1);
255
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
256
- vfp_reg_offset(1, rn),
257
- vfp_reg_offset(1, rm), fpst,
258
- opr_sz, opr_sz, data, fn_gvec_ptr);
259
- tcg_temp_free_ptr(fpst);
260
+ if (fn_gvec_ptr) {
261
+ TCGv_ptr fpst = get_fpstatus_ptr(1);
262
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
263
+ vfp_reg_offset(1, rn),
264
+ vfp_reg_offset(1, rm), fpst,
265
+ opr_sz, opr_sz, data, fn_gvec_ptr);
266
+ tcg_temp_free_ptr(fpst);
267
+ } else {
268
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
269
+ vfp_reg_offset(1, rn),
270
+ vfp_reg_offset(1, rm),
271
+ opr_sz, opr_sz, data, fn_gvec);
272
+ }
273
return 0;
274
}
275
78
276
--
79
--
277
2.17.1
80
2.34.1
278
279
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
2
10
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
with the case of being passed an unaligned address, so we can fix the
5
Message-id: 20180627043328.11531-15-richard.henderson@linaro.org
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
7
---
21
---
8
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++++++
22
hw/pci-host/raven.c | 1 +
9
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
23
1 file changed, 1 insertion(+)
10
target/arm/translate-sve.c | 40 ++++++++++++++++-
11
3 files changed, 193 insertions(+), 2 deletions(-)
12
24
13
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
14
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-sve.h
27
--- a/hw/pci-host/raven.c
16
+++ b/target/arm/helper-sve.h
28
+++ b/hw/pci-host/raven.c
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
18
DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
30
.write = raven_io_write,
19
void, env, ptr, ptr, ptr, tl, i32)
31
.endianness = DEVICE_LITTLE_ENDIAN,
20
32
.impl.max_access_size = 4,
21
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zsu, TCG_CALL_NO_WG,
33
+ .impl.unaligned = true,
22
+ void, env, ptr, ptr, ptr, tl, i32)
34
.valid.unaligned = true,
23
+DEF_HELPER_FLAGS_6(sve_ldffhsu_zsu, TCG_CALL_NO_WG,
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_6(sve_ldffssu_zsu, TCG_CALL_NO_WG,
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_6(sve_ldffbss_zsu, TCG_CALL_NO_WG,
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_6(sve_ldffhss_zsu, TCG_CALL_NO_WG,
30
+ void, env, ptr, ptr, ptr, tl, i32)
31
+
32
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zss, TCG_CALL_NO_WG,
33
+ void, env, ptr, ptr, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_6(sve_ldffhsu_zss, TCG_CALL_NO_WG,
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_6(sve_ldffssu_zss, TCG_CALL_NO_WG,
37
+ void, env, ptr, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_6(sve_ldffbss_zss, TCG_CALL_NO_WG,
39
+ void, env, ptr, ptr, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_6(sve_ldffhss_zss, TCG_CALL_NO_WG,
41
+ void, env, ptr, ptr, ptr, tl, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zsu, TCG_CALL_NO_WG,
44
+ void, env, ptr, ptr, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zsu, TCG_CALL_NO_WG,
46
+ void, env, ptr, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zsu, TCG_CALL_NO_WG,
48
+ void, env, ptr, ptr, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_6(sve_ldffddu_zsu, TCG_CALL_NO_WG,
50
+ void, env, ptr, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_6(sve_ldffbds_zsu, TCG_CALL_NO_WG,
52
+ void, env, ptr, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_6(sve_ldffhds_zsu, TCG_CALL_NO_WG,
54
+ void, env, ptr, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_6(sve_ldffsds_zsu, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+
58
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zss, TCG_CALL_NO_WG,
59
+ void, env, ptr, ptr, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zss, TCG_CALL_NO_WG,
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zss, TCG_CALL_NO_WG,
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_6(sve_ldffddu_zss, TCG_CALL_NO_WG,
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_6(sve_ldffbds_zss, TCG_CALL_NO_WG,
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+DEF_HELPER_FLAGS_6(sve_ldffhds_zss, TCG_CALL_NO_WG,
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_6(sve_ldffsds_zss, TCG_CALL_NO_WG,
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+
73
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zd, TCG_CALL_NO_WG,
74
+ void, env, ptr, ptr, ptr, tl, i32)
75
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zd, TCG_CALL_NO_WG,
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zd, TCG_CALL_NO_WG,
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_6(sve_ldffddu_zd, TCG_CALL_NO_WG,
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+DEF_HELPER_FLAGS_6(sve_ldffbds_zd, TCG_CALL_NO_WG,
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_6(sve_ldffhds_zd, TCG_CALL_NO_WG,
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_6(sve_ldffsds_zd, TCG_CALL_NO_WG,
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+
88
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
89
void, env, ptr, ptr, ptr, tl, i32)
90
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
91
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/sve_helper.c
94
+++ b/target/arm/sve_helper.c
95
@@ -XXX,XX +XXX,XX @@ DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
96
DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
97
DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
98
99
+/* First fault loads with a vector index. */
100
+
101
+#ifdef CONFIG_USER_ONLY
102
+
103
+#define DO_LDFF1_ZPZ(NAME, TYPEE, TYPEI, TYPEM, FN, H) \
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
105
+ target_ulong base, uint32_t desc) \
106
+{ \
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
108
+ unsigned scale = simd_data(desc); \
109
+ uintptr_t ra = GETPC(); \
110
+ bool first = true; \
111
+ mmap_lock(); \
112
+ for (i = 0; i < oprsz; i++) { \
113
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
114
+ do { \
115
+ TYPEM m = 0; \
116
+ if (pg & 1) { \
117
+ target_ulong off = *(TYPEI *)(vm + H(i)); \
118
+ target_ulong addr = base + (off << scale); \
119
+ if (!first && \
120
+ page_check_range(addr, sizeof(TYPEM), PAGE_READ)) { \
121
+ record_fault(env, i, oprsz); \
122
+ goto exit; \
123
+ } \
124
+ m = FN(env, addr, ra); \
125
+ first = false; \
126
+ } \
127
+ *(TYPEE *)(vd + H(i)) = m; \
128
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
129
+ } while (i & 15); \
130
+ } \
131
+ exit: \
132
+ mmap_unlock(); \
133
+}
134
+
135
+#else
136
+
137
+#define DO_LDFF1_ZPZ(NAME, TYPEE, TYPEI, TYPEM, FN, H) \
138
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
139
+ target_ulong base, uint32_t desc) \
140
+{ \
141
+ g_assert_not_reached(); \
142
+}
143
+
144
+#endif
145
+
146
+#define DO_LDFF1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
147
+ DO_LDFF1_ZPZ(NAME, uint32_t, TYPEI, TYPEM, FN, H1_4)
148
+#define DO_LDFF1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
149
+ DO_LDFF1_ZPZ(NAME, uint64_t, TYPEI, TYPEM, FN, )
150
+
151
+DO_LDFF1_ZPZ_S(sve_ldffbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
152
+DO_LDFF1_ZPZ_S(sve_ldffhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
153
+DO_LDFF1_ZPZ_S(sve_ldffssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
154
+DO_LDFF1_ZPZ_S(sve_ldffbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
155
+DO_LDFF1_ZPZ_S(sve_ldffhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
156
+
157
+DO_LDFF1_ZPZ_S(sve_ldffbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
158
+DO_LDFF1_ZPZ_S(sve_ldffhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
159
+DO_LDFF1_ZPZ_S(sve_ldffssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
160
+DO_LDFF1_ZPZ_S(sve_ldffbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
161
+DO_LDFF1_ZPZ_S(sve_ldffhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
162
+
163
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
164
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
165
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
166
+DO_LDFF1_ZPZ_D(sve_ldffddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
167
+DO_LDFF1_ZPZ_D(sve_ldffbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
168
+DO_LDFF1_ZPZ_D(sve_ldffhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
169
+DO_LDFF1_ZPZ_D(sve_ldffsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
170
+
171
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
172
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
173
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
174
+DO_LDFF1_ZPZ_D(sve_ldffddu_zss, int32_t, uint64_t, cpu_ldq_data_ra)
175
+DO_LDFF1_ZPZ_D(sve_ldffbds_zss, int32_t, int8_t, cpu_ldub_data_ra)
176
+DO_LDFF1_ZPZ_D(sve_ldffhds_zss, int32_t, int16_t, cpu_lduw_data_ra)
177
+DO_LDFF1_ZPZ_D(sve_ldffsds_zss, int32_t, int32_t, cpu_ldl_data_ra)
178
+
179
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zd, uint64_t, uint8_t, cpu_ldub_data_ra)
180
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zd, uint64_t, uint16_t, cpu_lduw_data_ra)
181
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zd, uint64_t, uint32_t, cpu_ldl_data_ra)
182
+DO_LDFF1_ZPZ_D(sve_ldffddu_zd, uint64_t, uint64_t, cpu_ldq_data_ra)
183
+DO_LDFF1_ZPZ_D(sve_ldffbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
184
+DO_LDFF1_ZPZ_D(sve_ldffhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
185
+DO_LDFF1_ZPZ_D(sve_ldffsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
186
+
187
/* Stores with a vector index. */
188
189
#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
190
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/target/arm/translate-sve.c
193
+++ b/target/arm/translate-sve.c
194
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
195
{ gen_helper_sve_ldbsu_zss,
196
gen_helper_sve_ldhsu_zss,
197
gen_helper_sve_ldssu_zss, } } },
198
- /* TODO fill in first-fault handlers */
199
+
200
+ { { { gen_helper_sve_ldffbss_zsu,
201
+ gen_helper_sve_ldffhss_zsu,
202
+ NULL, },
203
+ { gen_helper_sve_ldffbsu_zsu,
204
+ gen_helper_sve_ldffhsu_zsu,
205
+ gen_helper_sve_ldffssu_zsu, } },
206
+ { { gen_helper_sve_ldffbss_zss,
207
+ gen_helper_sve_ldffhss_zss,
208
+ NULL, },
209
+ { gen_helper_sve_ldffbsu_zss,
210
+ gen_helper_sve_ldffhsu_zss,
211
+ gen_helper_sve_ldffssu_zss, } } }
212
};
35
};
213
36
214
/* Note that we overload xs=2 to indicate 64-bit offset. */
215
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn64[2][3][2][4] = {
216
gen_helper_sve_ldhdu_zd,
217
gen_helper_sve_ldsdu_zd,
218
gen_helper_sve_ldddu_zd, } } },
219
- /* TODO fill in first-fault handlers */
220
+
221
+ { { { gen_helper_sve_ldffbds_zsu,
222
+ gen_helper_sve_ldffhds_zsu,
223
+ gen_helper_sve_ldffsds_zsu,
224
+ NULL, },
225
+ { gen_helper_sve_ldffbdu_zsu,
226
+ gen_helper_sve_ldffhdu_zsu,
227
+ gen_helper_sve_ldffsdu_zsu,
228
+ gen_helper_sve_ldffddu_zsu, } },
229
+ { { gen_helper_sve_ldffbds_zss,
230
+ gen_helper_sve_ldffhds_zss,
231
+ gen_helper_sve_ldffsds_zss,
232
+ NULL, },
233
+ { gen_helper_sve_ldffbdu_zss,
234
+ gen_helper_sve_ldffhdu_zss,
235
+ gen_helper_sve_ldffsdu_zss,
236
+ gen_helper_sve_ldffddu_zss, } },
237
+ { { gen_helper_sve_ldffbds_zd,
238
+ gen_helper_sve_ldffhds_zd,
239
+ gen_helper_sve_ldffsds_zd,
240
+ NULL, },
241
+ { gen_helper_sve_ldffbdu_zd,
242
+ gen_helper_sve_ldffhdu_zd,
243
+ gen_helper_sve_ldffsdu_zd,
244
+ gen_helper_sve_ldffddu_zd, } } }
245
};
246
247
static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a, uint32_t insn)
248
--
37
--
249
2.17.1
38
2.34.1
250
39
251
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Suppress the deprecation warning when we're running under qtest,
2
to avoid "make check" including warning messages in its output.
2
3
3
There is no need to re-set these 3 features already
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
implied by the call to aarch64_a15_initfn.
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
7
---
8
hw/block/tc58128.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180629001538.11415-5-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.c | 3 ---
13
1 file changed, 3 deletions(-)
14
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
13
--- a/hw/block/tc58128.c
18
+++ b/target/arm/cpu.c
14
+++ b/hw/block/tc58128.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
20
* since we don't correctly set the ID registers to advertise them,
16
21
*/
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
22
set_feature(&cpu->env, ARM_FEATURE_V8);
18
{
23
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
19
- warn_report_once("The TC58128 flash device is deprecated");
24
- set_feature(&cpu->env, ARM_FEATURE_NEON);
20
+ if (!qtest_enabled()) {
25
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
21
+ warn_report_once("The TC58128 flash device is deprecated");
26
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
22
+ }
27
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
23
init_dev(&tc58128_devs[0], zone1);
28
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
24
init_dev(&tc58128_devs[1], zone2);
25
return sh7750_register_io_device(s, &tc58128);
29
--
26
--
30
2.17.1
27
2.34.1
31
28
32
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
2
4
3
There is no need to re-set these 9 features already
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
4
implied by the call to aarch64_a57_initfn.
6
that change.
5
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180629001538.11415-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
11
---
12
---
12
target/arm/cpu64.c | 9 ---------
13
tests/qtest/meson.build | 1 -
13
1 file changed, 9 deletions(-)
14
1 file changed, 1 deletion(-)
14
15
15
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu64.c
18
--- a/tests/qtest/meson.build
18
+++ b/target/arm/cpu64.c
19
+++ b/tests/qtest/meson.build
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
20
* whereas the architecture requires them to be present in both if
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
21
* present in either.
22
(config_all_accel.has_key('CONFIG_TCG') and \
22
*/
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
23
- set_feature(&cpu->env, ARM_FEATURE_V8);
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
24
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
25
['arm-cpu-features',
25
- set_feature(&cpu->env, ARM_FEATURE_NEON);
26
'numa-test',
26
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
27
'boot-serial-test',
27
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
28
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
29
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
30
set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
31
set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
32
set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
33
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
34
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
35
- set_feature(&cpu->env, ARM_FEATURE_CRC);
36
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
37
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
38
set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
39
--
28
--
40
2.17.1
29
2.34.1
41
30
42
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
entry for a new timer to it.
2
3
3
We already check for the same condition within the normal integer
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
sdiv and sdiv64 helpers. Use a slightly different formation that
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
5
does not require deducing the expression type.
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
7
---
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
9
1 file changed, 2 insertions(+)
6
10
7
Fixes: f97cfd596ed
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180629001538.11415-2-richard.henderson@linaro.org
12
[PMM: reworded a comment]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/sve_helper.c | 20 +++++++++++++++-----
16
1 file changed, 15 insertions(+), 5 deletions(-)
17
18
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/sve_helper.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
21
+++ b/target/arm/sve_helper.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
22
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
15
@@ -1 +1,3 @@
23
#define DO_MIN(N, M) ((N) >= (M) ? (M) : (N))
16
/* List of comma-separated changed AML files to ignore */
24
#define DO_ABD(N, M) ((N) >= (M) ? (N) - (M) : (M) - (N))
17
+"tests/data/acpi/virt/FACP",
25
#define DO_MUL(N, M) (N * M)
18
+"tests/data/acpi/virt/GTDT",
26
-#define DO_DIV(N, M) (M ? N / M : 0)
27
+
28
+
29
+/*
30
+ * We must avoid the C undefined behaviour cases: division by
31
+ * zero and signed division of INT_MIN by -1. Both of these
32
+ * have architecturally defined required results for Arm.
33
+ * We special case all signed divisions by -1 to avoid having
34
+ * to deduce the minimum integer for the type involved.
35
+ */
36
+#define DO_SDIV(N, M) (unlikely(M == 0) ? 0 : unlikely(M == -1) ? -N : N / M)
37
+#define DO_UDIV(N, M) (unlikely(M == 0) ? 0 : N / M)
38
39
DO_ZPZZ(sve_and_zpzz_b, uint8_t, H1, DO_AND)
40
DO_ZPZZ(sve_and_zpzz_h, uint16_t, H1_2, DO_AND)
41
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ(sve_umulh_zpzz_h, uint16_t, H1_2, do_mulh_h)
42
DO_ZPZZ(sve_umulh_zpzz_s, uint32_t, H1_4, do_mulh_s)
43
DO_ZPZZ_D(sve_umulh_zpzz_d, uint64_t, do_umulh_d)
44
45
-DO_ZPZZ(sve_sdiv_zpzz_s, int32_t, H1_4, DO_DIV)
46
-DO_ZPZZ_D(sve_sdiv_zpzz_d, int64_t, DO_DIV)
47
+DO_ZPZZ(sve_sdiv_zpzz_s, int32_t, H1_4, DO_SDIV)
48
+DO_ZPZZ_D(sve_sdiv_zpzz_d, int64_t, DO_SDIV)
49
50
-DO_ZPZZ(sve_udiv_zpzz_s, uint32_t, H1_4, DO_DIV)
51
-DO_ZPZZ_D(sve_udiv_zpzz_d, uint64_t, DO_DIV)
52
+DO_ZPZZ(sve_udiv_zpzz_s, uint32_t, H1_4, DO_UDIV)
53
+DO_ZPZZ_D(sve_udiv_zpzz_d, uint64_t, DO_UDIV)
54
55
/* Note that all bits of the shift are significant
56
and not modulo the element size. */
57
--
19
--
58
2.17.1
20
2.34.1
59
60
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
When running dtc on the guest /proc/device-tree we get the
3
CPU model, but never wired up its IRQ line to the GIC.
4
following warning: Warning (unit_address_vs_reg): Node /memory
4
5
has a reg or ranges property, but no unit name".
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
6
interrupt or not, since it always creates the outbound IRQ line).
7
Let's fix that by adding the unit address to the node name. We also
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
don't create the /memory node anymore in create_fdt(). We directly
8
9
create it in load_dtb. /chosen still needs to be created in create_fdt
9
The DTB binding is documented in the kernel's
10
as the uart needs it. In case the user provided his own dtb, we nop
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
all memory nodes found in root and create new one(s).
11
and the ACPI table entries are documented in the ACPI specification
12
12
version 6.3 or later.
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
14
Message-id: 1530044492-24921-4-git-send-email-eric.auger@redhat.com
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
17
---
35
---
18
hw/arm/boot.c | 41 +++++++++++++++++++++++------------------
36
include/hw/arm/virt.h | 2 ++
19
hw/arm/virt.c | 7 +------
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
20
2 files changed, 24 insertions(+), 24 deletions(-)
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
21
39
3 files changed, 67 insertions(+), 15 deletions(-)
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
23
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
43
--- a/include/hw/arm/virt.h
25
+++ b/hw/arm/boot.c
44
+++ b/include/hw/arm/virt.h
26
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
27
hwaddr addr_limit, AddressSpace *as)
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
47
bool no_cpu_topology;
48
bool no_tcg_lpa2;
49
+ bool no_ns_el2_virt_timer_irq;
50
};
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
28
{
105
{
29
void *fdt = NULL;
106
- /* ACPI v6.0 */
30
- int size, rc;
107
+ /* ACPI v6.3 */
31
+ int size, rc, n = 0;
108
AcpiFadtData fadt = {
32
uint32_t acells, scells;
109
.rev = 6,
33
char *nodename;
110
- .minor_ver = 0,
34
unsigned int i;
111
+ .minor_ver = 3,
35
hwaddr mem_base, mem_len;
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
36
+ char **node_path;
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
37
+ Error *err = NULL;
114
};
38
39
if (binfo->dtb_filename) {
40
char *filename;
41
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
42
goto fail;
43
}
44
45
+ /* nop all root nodes matching /memory or /memory@unit-address */
46
+ node_path = qemu_fdt_node_unit_path(fdt, "memory", &err);
47
+ if (err) {
48
+ error_report_err(err);
49
+ goto fail;
50
+ }
51
+ while (node_path[n]) {
52
+ if (g_str_has_prefix(node_path[n], "/memory")) {
53
+ qemu_fdt_nop_node(fdt, node_path[n]);
54
+ }
55
+ n++;
56
+ }
57
+ g_strfreev(node_path);
58
+
59
if (nb_numa_nodes > 0) {
60
- /*
61
- * Turn the /memory node created before into a NOP node, then create
62
- * /memory@addr nodes for all numa nodes respectively.
63
- */
64
- qemu_fdt_nop_node(fdt, "/memory");
65
mem_base = binfo->loader_start;
66
for (i = 0; i < nb_numa_nodes; i++) {
67
mem_len = numa_info[i].node_mem;
68
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
69
g_free(nodename);
70
}
71
} else {
72
- Error *err = NULL;
73
+ nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
74
+ qemu_fdt_add_subnode(fdt, nodename);
75
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
76
77
- rc = fdt_path_offset(fdt, "/memory");
78
- if (rc < 0) {
79
- qemu_fdt_add_subnode(fdt, "/memory");
80
- }
81
-
82
- if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
83
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
84
- }
85
-
86
- rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
87
+ rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
88
acells, binfo->loader_start,
89
scells, binfo->ram_size);
90
if (rc < 0) {
91
- fprintf(stderr, "couldn't set /memory/reg\n");
92
+ fprintf(stderr, "couldn't set %s reg\n", nodename);
93
goto fail;
94
}
95
+ g_free(nodename);
96
}
97
98
rc = fdt_path_offset(fdt, "/chosen");
99
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
100
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/arm/virt.c
117
--- a/hw/arm/virt.c
102
+++ b/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
103
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
104
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
105
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
121
}
106
122
107
- /*
123
+/*
108
- * /chosen and /memory nodes must exist for load_dtb
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
109
- * to fill in necessary properties later
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
110
- */
126
+ * table unless it's really going to do something.
111
+ /* /chosen must exist for load_dtb to fill in necessary properties later */
127
+ */
112
qemu_fdt_add_subnode(fdt, "/chosen");
128
+static bool ns_el2_virt_timer_present(void)
113
- qemu_fdt_add_subnode(fdt, "/memory");
129
+{
114
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
115
131
+ CPUARMState *env = &cpu->env;
116
/* Clock node, for the benefit of the UART. The kernel device tree
132
+
117
* binding documentation claims the PL011 node clock properties are
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
118
--
216
--
119
2.17.1
217
2.34.1
120
121
diff view generated by jsdifflib
1
We don't actually implement SD command CRC checking, because
1
Update the virt golden reference files to say that the FACP is ACPI
2
for almost all of our SD controllers the CRC generation is
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
done in hardware, and so modelling CRC generation and checking
3
virtual EL2 timer.
4
would be a bit pointless. (The exception is that milkymist-memcard
4
5
makes the guest software compute the CRC.)
5
Diffs from iasl:
6
6
7
As a result almost all of our SD controller models don't bother
7
@@ -XXX,XX +XXX,XX @@
8
to set the SDRequest crc field, and the SD card model doesn't
8
/*
9
check it. So the tracing of it in sdbus_do_command() provokes
9
* Intel ACPI Component Architecture
10
Coverity warnings about use of uninitialized data.
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
Drop the CRC field from the trace; we can always add it back
12
*
13
if and when we do anything useful with the CRC.
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
Fixes Coverity issues 1386072, 1386074, 1386076, 1390571.
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
16
183
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
19
Message-id: 20180626180324.5537-1-peter.maydell@linaro.org
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
20
---
187
---
21
hw/sd/core.c | 2 +-
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
22
hw/sd/trace-events | 2 +-
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
23
2 files changed, 2 insertions(+), 2 deletions(-)
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
24
191
3 files changed, 2 deletions(-)
25
diff --git a/hw/sd/core.c b/hw/sd/core.c
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
26
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/core.c
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
28
+++ b/hw/sd/core.c
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
29
@@ -XXX,XX +XXX,XX @@ int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
197
@@ -1,3 +1 @@
30
{
198
/* List of comma-separated changed AML files to ignore */
31
SDState *card = get_card(sdbus);
199
-"tests/data/acpi/virt/FACP",
32
200
-"tests/data/acpi/virt/GTDT",
33
- trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg, req->crc);
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
34
+ trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg);
35
if (card) {
36
SDCardClass *sc = SD_CARD_GET_CLASS(card);
37
38
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
39
index XXXXXXX..XXXXXXX 100644
202
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/sd/trace-events
203
GIT binary patch
41
+++ b/hw/sd/trace-events
204
delta 25
42
@@ -XXX,XX +XXX,XX @@ bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x"
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
43
bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n"
206
44
207
delta 28
45
# hw/sd/core.c
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
46
-sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg, uint8_t crc) "@%s CMD%02d arg 0x%08x crc 0x%02x"
209
47
+sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
48
sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
211
index XXXXXXX..XXXXXXX 100644
49
sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
212
GIT binary patch
50
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
213
delta 25
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
215
216
delta 16
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
218
51
--
219
--
52
2.17.1
220
2.34.1
53
54
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
2
6
3
KVM implies V7VE, which implies ARM_DIV and THUMB_DIV. The conditional
7
Add the missing call.
4
detection here is therefore unnecessary. Because V7VE is already
5
unconditionally specified for all KVM hosts, ARM_DIV and THUMB_DIV are
6
already indirectly specified and do not need to be included here at all.
7
8
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
9
Message-id: 1529699547-17044-6-git-send-email-alindsay@codeaurora.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
11
---
13
---
12
target/arm/kvm32.c | 19 +------------------
14
hw/arm/npcm7xx.c | 1 +
13
1 file changed, 1 insertion(+), 18 deletions(-)
15
1 file changed, 1 insertion(+)
14
16
15
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/kvm32.c
19
--- a/hw/arm/npcm7xx.c
18
+++ b/target/arm/kvm32.c
20
+++ b/hw/arm/npcm7xx.c
19
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
20
* and then query that CPU for the relevant ID registers.
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
21
*/
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
22
int i, ret, fdarray[3];
24
23
- uint32_t midr, id_pfr0, id_isar0, mvfr1;
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
24
+ uint32_t midr, id_pfr0, mvfr1;
26
/*
25
uint64_t features = 0;
27
* The device exists regardless of whether it's connected to a QEMU
26
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
28
* netdev backend. So always instantiate it even if there is no
27
* we know these will only support creating one kind of guest CPU,
28
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
29
| ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
30
.addr = (uintptr_t)&id_pfr0,
31
},
32
- {
33
- .id = KVM_REG_ARM | KVM_REG_SIZE_U32
34
- | ENCODE_CP_REG(15, 0, 0, 0, 2, 0, 0),
35
- .addr = (uintptr_t)&id_isar0,
36
- },
37
{
38
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
39
| KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
40
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
41
set_feature(&features, ARM_FEATURE_VFP3);
42
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
43
44
- switch (extract32(id_isar0, 24, 4)) {
45
- case 1:
46
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
47
- break;
48
- case 2:
49
- set_feature(&features, ARM_FEATURE_ARM_DIV);
50
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
51
- break;
52
- default:
53
- break;
54
- }
55
-
56
if (extract32(id_pfr0, 12, 4) == 1) {
57
set_feature(&features, ARM_FEATURE_THUMB2EE);
58
}
59
--
29
--
60
2.17.1
30
2.34.1
61
62
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
Currently QEMU will warn if there is a NIC on the board that
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
2
6
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
4
Message-id: 1529699547-17044-5-git-send-email-alindsay@codeaurora.org
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
13
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
6
---
18
---
7
target/arm/cpu.h | 1 +
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
8
target/arm/cpu.c | 21 ++++++++++++++-------
20
1 file changed, 4 insertions(+), 1 deletion(-)
9
target/arm/kvm32.c | 8 ++++----
10
3 files changed, 19 insertions(+), 11 deletions(-)
11
21
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
24
--- a/tests/qtest/npcm7xx_emc-test.c
15
+++ b/target/arm/cpu.h
25
+++ b/tests/qtest/npcm7xx_emc-test.c
16
@@ -XXX,XX +XXX,XX @@ enum arm_features {
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
17
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
18
ARM_FEATURE_THUMB2EE,
28
* in the 'model' field to specify the device to match.
19
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
20
+ ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
21
ARM_FEATURE_V4T,
22
ARM_FEATURE_V5,
23
ARM_FEATURE_STRONGARM,
24
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.c
27
+++ b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
29
30
/* Some features automatically imply others: */
31
if (arm_feature(env, ARM_FEATURE_V8)) {
32
- set_feature(env, ARM_FEATURE_V7);
33
+ set_feature(env, ARM_FEATURE_V7VE);
34
+ }
35
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
36
+ /* v7 Virtualization Extensions. In real hardware this implies
37
+ * EL2 and also the presence of the Security Extensions.
38
+ * For QEMU, for backwards-compatibility we implement some
39
+ * CPUs or CPU configs which have no actual EL2 or EL3 but do
40
+ * include the various other features that V7VE implies.
41
+ * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
42
+ * Security Extensions is ARM_FEATURE_EL3.
43
+ */
44
set_feature(env, ARM_FEATURE_ARM_DIV);
45
set_feature(env, ARM_FEATURE_LPAE);
46
+ set_feature(env, ARM_FEATURE_V7);
47
}
48
if (arm_feature(env, ARM_FEATURE_V7)) {
49
set_feature(env, ARM_FEATURE_VAPA);
50
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
51
ARMCPU *cpu = ARM_CPU(obj);
52
53
cpu->dtb_compatible = "arm,cortex-a7";
54
- set_feature(&cpu->env, ARM_FEATURE_V7);
55
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
56
set_feature(&cpu->env, ARM_FEATURE_VFP4);
57
set_feature(&cpu->env, ARM_FEATURE_NEON);
58
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
59
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
60
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
61
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
62
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
63
- set_feature(&cpu->env, ARM_FEATURE_LPAE);
64
set_feature(&cpu->env, ARM_FEATURE_EL3);
65
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
66
cpu->midr = 0x410fc075;
67
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
68
ARMCPU *cpu = ARM_CPU(obj);
69
70
cpu->dtb_compatible = "arm,cortex-a15";
71
- set_feature(&cpu->env, ARM_FEATURE_V7);
72
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
73
set_feature(&cpu->env, ARM_FEATURE_VFP4);
74
set_feature(&cpu->env, ARM_FEATURE_NEON);
75
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
76
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
77
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
78
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
79
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
80
- set_feature(&cpu->env, ARM_FEATURE_LPAE);
81
set_feature(&cpu->env, ARM_FEATURE_EL3);
82
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
83
cpu->midr = 0x412fc0f1;
84
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/kvm32.c
87
+++ b/target/arm/kvm32.c
88
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
89
/* Now we've retrieved all the register information we can
90
* set the feature bits based on the ID register fields.
91
* We can assume any KVM supporting CPU is at least a v7
92
- * with VFPv3, LPAE and the generic timers; this in turn implies
93
- * most of the other feature bits, but a few must be tested.
94
+ * with VFPv3, virtualization extensions, and the generic
95
+ * timers; this in turn implies most of the other feature
96
+ * bits, but a few must be tested.
97
*/
29
*/
98
- set_feature(&features, ARM_FEATURE_V7);
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
99
+ set_feature(&features, ARM_FEATURE_V7VE);
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
100
set_feature(&features, ARM_FEATURE_VFP3);
32
+ "-nic user,model=npcm7xx-emc "
101
- set_feature(&features, ARM_FEATURE_LPAE);
33
+ "-nic user,model=npcm-gmac "
102
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
34
+ "-nic user,model=npcm-gmac",
103
35
test_sockets[1], module_num);
104
switch (extract32(id_isar0, 24, 4)) {
36
37
g_test_queue_destroy(packet_test_clear, test_sockets);
105
--
38
--
106
2.17.1
39
2.34.1
107
108
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
2
3
3
Leave ARM_CP_SVE, removing ARM_CP_FPU; the sve_access_check
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
4
produced by the flag already includes fp_access_check. If
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
5
we also check ARM_CP_FPU the double fp_access_check asserts.
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
6
9
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
from the migration pre/post hooks in machine.c); this should always
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
return false because these CPUs don't set ARM_FEATURE_PMU.
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
12
Message-id: 20180629001538.11415-3-richard.henderson@linaro.org
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
14
---
26
---
15
target/arm/helper.c | 8 ++++----
27
target/arm/helper.c | 12 ++++++++++--
16
target/arm/translate-a64.c | 5 ++---
28
1 file changed, 10 insertions(+), 2 deletions(-)
17
2 files changed, 6 insertions(+), 7 deletions(-)
18
29
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
24
static const ARMCPRegInfo zcr_el1_reginfo = {
35
bool enabled, prohibited = false, filtered;
25
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
36
bool secure = arm_is_secure(env);
26
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
37
int el = arm_current_el(env);
27
- .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
28
+ .access = PL1_RW, .type = ARM_CP_SVE,
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
29
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
40
+ uint64_t mdcr_el2;
30
.writefn = zcr_write, .raw_writefn = raw_write
41
+ uint8_t hpmn;
31
};
42
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
43
+ /*
33
static const ARMCPRegInfo zcr_el2_reginfo = {
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
34
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
35
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
46
+ * must be before we read that value.
36
- .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
47
+ */
37
+ .access = PL2_RW, .type = ARM_CP_SVE,
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
38
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
49
return false;
39
.writefn = zcr_write, .raw_writefn = raw_write
40
};
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
42
static const ARMCPRegInfo zcr_no_el2_reginfo = {
43
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
44
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
45
- .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
46
+ .access = PL2_RW, .type = ARM_CP_SVE,
47
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
48
};
49
50
static const ARMCPRegInfo zcr_el3_reginfo = {
51
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
52
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
53
- .access = PL3_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
54
+ .access = PL3_RW, .type = ARM_CP_SVE,
55
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
56
.writefn = zcr_write, .raw_writefn = raw_write
57
};
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
62
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
63
default:
64
break;
65
}
50
}
66
- if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
51
67
- return;
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
68
- }
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
69
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
54
+
70
return;
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
71
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
56
(counter < hpmn || counter == 31)) {
72
+ return;
57
e = env->cp15.c9_pmcr & PMCRE;
73
}
74
75
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
76
--
58
--
77
2.17.1
59
2.34.1
78
60
79
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
[PMM: commit message tweaks]
5
Message-id: 20180627043328.11531-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/translate-sve.c | 103 +++++++++++++++++++++++++++++++++++++
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
9
target/arm/sve.decode | 6 +++
15
tests/qtest/meson.build | 3 +-
10
2 files changed, 109 insertions(+)
16
2 files changed, 4 insertions(+), 83 deletions(-)
11
17
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
20
--- a/tests/qtest/npcm_gmac-test.c
15
+++ b/target/arm/translate-sve.c
21
+++ b/tests/qtest/npcm_gmac-test.c
16
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
17
tcg_temp_free_i64(t0);
23
const GMACModule *module;
24
} TestData;
25
26
-/* Values extracted from hw/arm/npcm8xx.c */
27
+/* Values extracted from hw/arm/npcm7xx.c */
28
static const GMACModule gmac_module_list[] = {
29
{
30
.irq = 14,
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
32
.irq = 15,
33
.base_addr = 0xf0804000
34
},
35
- {
36
- .irq = 16,
37
- .base_addr = 0xf0806000
38
- },
39
- {
40
- .irq = 17,
41
- .base_addr = 0xf0808000
42
- }
43
};
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
18
}
48
}
19
49
20
+/* Similarly for stores. */
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
21
+static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
51
- NPCMRegister regno)
22
+ int rn, int imm)
52
-{
23
+{
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
24
+ uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
25
+ uint32_t len_remain = len % 8;
55
- uint32_t read_offset = regno & 0x1ff;
26
+ uint32_t nparts = len / 8 + ctpop8(len_remain);
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
27
+ int midx = get_mem_index(s);
57
-}
28
+ TCGv_i64 addr, t0;
58
-
29
+
59
/* Check that GMAC registers are reset to default value */
30
+ addr = tcg_temp_new_i64();
60
static void test_init(gconstpointer test_data)
31
+ t0 = tcg_temp_new_i64();
32
+
33
+ /* Note that unpredicated load/store of vector/predicate registers
34
+ * are defined as a stream of bytes, which equates to little-endian
35
+ * operations on larger quantities. There is no nice way to force
36
+ * a little-endian store for aarch64_be-linux-user out of line.
37
+ *
38
+ * Attempt to keep code expansion to a minimum by limiting the
39
+ * amount of unrolling done.
40
+ */
41
+ if (nparts <= 4) {
42
+ int i;
43
+
44
+ for (i = 0; i < len_align; i += 8) {
45
+ tcg_gen_ld_i64(t0, cpu_env, vofs + i);
46
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + i);
47
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
48
+ }
49
+ } else {
50
+ TCGLabel *loop = gen_new_label();
51
+ TCGv_ptr t2, i = tcg_const_local_ptr(0);
52
+
53
+ gen_set_label(loop);
54
+
55
+ t2 = tcg_temp_new_ptr();
56
+ tcg_gen_add_ptr(t2, cpu_env, i);
57
+ tcg_gen_ld_i64(t0, t2, vofs);
58
+
59
+ /* Minimize the number of local temps that must be re-read from
60
+ * the stack each iteration. Instead, re-compute values other
61
+ * than the loop counter.
62
+ */
63
+ tcg_gen_addi_ptr(t2, i, imm);
64
+ tcg_gen_extu_ptr_i64(addr, t2);
65
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, rn));
66
+ tcg_temp_free_ptr(t2);
67
+
68
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
69
+
70
+ tcg_gen_addi_ptr(i, i, 8);
71
+
72
+ tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
73
+ tcg_temp_free_ptr(i);
74
+ }
75
+
76
+ /* Predicate register stores can be any multiple of 2. */
77
+ if (len_remain) {
78
+ tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
79
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + len_align);
80
+
81
+ switch (len_remain) {
82
+ case 2:
83
+ case 4:
84
+ case 8:
85
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LE | ctz32(len_remain));
86
+ break;
87
+
88
+ case 6:
89
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUL);
90
+ tcg_gen_addi_i64(addr, addr, 4);
91
+ tcg_gen_shri_i64(t0, t0, 32);
92
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUW);
93
+ break;
94
+
95
+ default:
96
+ g_assert_not_reached();
97
+ }
98
+ }
99
+ tcg_temp_free_i64(addr);
100
+ tcg_temp_free_i64(t0);
101
+}
102
+
103
static bool trans_LDR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
104
{
61
{
105
if (sve_access_check(s)) {
62
const TestData *td = test_data;
106
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
63
const GMACModule *mod = td->module;
107
return true;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
108
}
143
}
109
144
110
+static bool trans_STR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
111
+{
112
+ if (sve_access_check(s)) {
113
+ int size = vec_full_reg_size(s);
114
+ int off = vec_full_reg_offset(s, a->rd);
115
+ do_str(s, off, size, a->rn, a->imm * size);
116
+ }
117
+ return true;
118
+}
119
+
120
+static bool trans_STR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
121
+{
122
+ if (sve_access_check(s)) {
123
+ int size = pred_full_reg_size(s);
124
+ int off = pred_full_reg_offset(s, a->rd);
125
+ do_str(s, off, size, a->rn, a->imm * size);
126
+ }
127
+ return true;
128
+}
129
+
130
/*
131
*** SVE Memory - Contiguous Load Group
132
*/
133
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
134
index XXXXXXX..XXXXXXX 100644
146
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/sve.decode
147
--- a/tests/qtest/meson.build
136
+++ b/target/arm/sve.decode
148
+++ b/tests/qtest/meson.build
137
@@ -XXX,XX +XXX,XX @@ LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
138
150
'npcm7xx_sdhci-test',
139
### SVE Memory Store Group
151
'npcm7xx_smbus-test',
140
152
'npcm7xx_timer-test',
141
+# SVE store predicate register
153
- 'npcm7xx_watchdog_timer-test'] + \
142
+STR_pri 1110010 11 0. ..... 000 ... ..... 0 .... @pd_rn_i9
154
+ 'npcm7xx_watchdog_timer-test',
143
+
155
+ 'npcm_gmac-test'] + \
144
+# SVE store vector register
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
145
+STR_zri 1110010 11 0. ..... 010 ... ..... ..... @rd_rn_i9
157
qtests_aspeed = \
146
+
158
['aspeed_hace-test',
147
# SVE contiguous store (scalar plus immediate)
148
# ST1B, ST1H, ST1W, ST1D; require msz <= esz
149
ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
150
--
159
--
151
2.17.1
160
2.34.1
152
153
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
Since kernel commit a86bd139f2 (arm64: arch_timer: Enable CNTVCT_EL0
3
An access fault is raised when the Access Flag is not set in the
4
trap..), released in kernel version v4.12, user-space has been able
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
to read these system registers. As we can't use QEMUTimer's in
5
descriptor. This was already implemented for stage 2. Implement it for
6
linux-user mode we just directly call cpu_get_clock().
6
stage 1 as well.
7
7
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
10
Message-id: 20180625160009.17437-2-alex.bennee@linaro.org
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
15
---
14
target/arm/helper.c | 27 ++++++++++++++++++++++++---
16
hw/arm/smmuv3-internal.h | 1 +
15
1 file changed, 24 insertions(+), 3 deletions(-)
17
include/hw/arm/smmu-common.h | 1 +
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
16
21
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
24
--- a/hw/arm/smmuv3-internal.h
20
+++ b/target/arm/helper.c
25
+++ b/hw/arm/smmuv3-internal.h
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
22
};
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
23
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
24
#else
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
25
-/* In user-mode none of the generic timer registers are accessible,
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
26
- * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
27
- * so instead just don't register any of them.
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/smmu-common.h
37
+++ b/include/hw/arm/smmu-common.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
39
bool disabled; /* smmu is disabled */
40
bool bypassed; /* translation is bypassed */
41
bool aborted; /* translation is aborted */
42
+ bool affd; /* AF fault disable */
43
uint32_t iotlb_hits; /* counts IOTLB hits */
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
45
/* Used by stage-1 only. */
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
53
}
28
+
54
+
29
+/* In user-mode most of the generic timer registers are inaccessible
55
+ /*
30
+ * however modern kernels (4.12+) allow access to cntvct_el0
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
31
*/
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
58
+ * An Access flag fault takes priority over a Permission fault.
59
+ */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
61
+ info->type = SMMU_PTW_ERR_ACCESS;
62
+ goto error;
63
+ }
32
+
64
+
33
+static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
65
ap = PTE_AP(pte);
34
+{
66
if (is_permission_fault(ap, perm)) {
35
+ /* Currently we have no support for QEMUTimer in linux-user so we
67
info->type = SMMU_PTW_ERR_PERMISSION;
36
+ * can't call gt_get_countervalue(env), instead we directly
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
37
+ * call the lower level functions.
69
index XXXXXXX..XXXXXXX 100644
38
+ */
70
--- a/hw/arm/smmuv3.c
39
+ return cpu_get_clock() / GTIMER_SCALE;
71
+++ b/hw/arm/smmuv3.c
40
+}
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
41
+
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
42
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
74
cfg->tbi = CD_TBI(cd);
43
+ { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
75
cfg->asid = CD_ASID(cd);
44
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
76
+ cfg->affd = CD_AFFD(cd);
45
+ .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
77
46
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
78
trace_smmuv3_decode_cd(cfg->oas);
47
+ .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
48
+ },
49
+ { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
50
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
51
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
52
+ .readfn = gt_virt_cnt_read,
53
+ },
54
REGINFO_SENTINEL
55
};
56
79
57
--
80
--
58
2.17.1
81
2.34.1
59
60
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
5
Message-id: 20180627043328.11531-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 30 +++++++++++++
8
hw/arm/stellaris.c | 6 ++++--
9
target/arm/helper.h | 12 +++---
9
1 file changed, 4 insertions(+), 2 deletions(-)
10
target/arm/helper.c | 2 +-
11
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 70 ++++++++++++++++++++++++++++++
13
target/arm/sve.decode | 16 +++++++
14
6 files changed, 211 insertions(+), 7 deletions(-)
15
10
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
13
--- a/hw/arm/stellaris.c
19
+++ b/target/arm/helper-sve.h
14
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
21
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
16
}
22
void, ptr, ptr, ptr, ptr, i32)
23
24
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hs, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve_fcvtzs_ss, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve_fcvtzs_ds, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hd, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve_fcvtzs_sd, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_5(sve_fcvtzs_dd, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, i32)
38
+
39
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hh, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hs, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_5(sve_fcvtzu_ss, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(sve_fcvtzu_ds, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hd, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_5(sve_fcvtzu_sd, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(sve_fcvtzu_dd, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+
54
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
55
void, ptr, ptr, ptr, ptr, i32)
56
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
57
diff --git a/target/arm/helper.h b/target/arm/helper.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/helper.h
60
+++ b/target/arm/helper.h
61
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(vfp_touid, i32, f64, ptr)
62
DEF_HELPER_2(vfp_touizh, i32, f16, ptr)
63
DEF_HELPER_2(vfp_touizs, i32, f32, ptr)
64
DEF_HELPER_2(vfp_touizd, i32, f64, ptr)
65
-DEF_HELPER_2(vfp_tosih, i32, f16, ptr)
66
-DEF_HELPER_2(vfp_tosis, i32, f32, ptr)
67
-DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
68
-DEF_HELPER_2(vfp_tosizh, i32, f16, ptr)
69
-DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
70
-DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
71
+DEF_HELPER_2(vfp_tosih, s32, f16, ptr)
72
+DEF_HELPER_2(vfp_tosis, s32, f32, ptr)
73
+DEF_HELPER_2(vfp_tosid, s32, f64, ptr)
74
+DEF_HELPER_2(vfp_tosizh, s32, f16, ptr)
75
+DEF_HELPER_2(vfp_tosizs, s32, f32, ptr)
76
+DEF_HELPER_2(vfp_tosizd, s32, f64, ptr)
77
78
DEF_HELPER_3(vfp_toshs_round_to_zero, i32, f32, i32, ptr)
79
DEF_HELPER_3(vfp_tosls_round_to_zero, i32, f32, i32, ptr)
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ ftype HELPER(name)(uint32_t x, void *fpstp) \
85
}
17
}
86
18
87
#define CONV_FTOI(name, ftype, fsz, sign, round) \
19
-static void stellaris_adc_reset(StellarisADCState *s)
88
-uint32_t HELPER(name)(ftype x, void *fpstp) \
20
+static void stellaris_adc_reset_hold(Object *obj)
89
+sign##int32_t HELPER(name)(ftype x, void *fpstp) \
21
{
90
{ \
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
91
float_status *fpst = fpstp; \
23
int n;
92
if (float##fsz##_is_any_nan(x)) { \
24
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
25
for (n = 0; n < 4; n++) {
94
index XXXXXXX..XXXXXXX 100644
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
95
--- a/target/arm/sve_helper.c
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
96
+++ b/target/arm/sve_helper.c
28
"adc", 0x1000);
97
@@ -XXX,XX +XXX,XX @@ static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
29
sysbus_init_mmio(sbd, &s->iomem);
98
return ret;
30
- stellaris_adc_reset(s);
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
99
}
32
}
100
33
101
+static inline int16_t vfp_float16_to_int16_rtz(float16 f, float_status *s)
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
102
+{
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
103
+ if (float16_is_any_nan(f)) {
36
{
104
+ float_raise(float_flag_invalid, s);
37
DeviceClass *dc = DEVICE_CLASS(klass);
105
+ return 0;
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
106
+ }
39
107
+ return float16_to_int16_round_to_zero(f, s);
40
+ rc->phases.hold = stellaris_adc_reset_hold;
108
+}
41
dc->vmsd = &vmstate_stellaris_adc;
109
+
110
+static inline int64_t vfp_float16_to_int64_rtz(float16 f, float_status *s)
111
+{
112
+ if (float16_is_any_nan(f)) {
113
+ float_raise(float_flag_invalid, s);
114
+ return 0;
115
+ }
116
+ return float16_to_int64_round_to_zero(f, s);
117
+}
118
+
119
+static inline int64_t vfp_float32_to_int64_rtz(float32 f, float_status *s)
120
+{
121
+ if (float32_is_any_nan(f)) {
122
+ float_raise(float_flag_invalid, s);
123
+ return 0;
124
+ }
125
+ return float32_to_int64_round_to_zero(f, s);
126
+}
127
+
128
+static inline int64_t vfp_float64_to_int64_rtz(float64 f, float_status *s)
129
+{
130
+ if (float64_is_any_nan(f)) {
131
+ float_raise(float_flag_invalid, s);
132
+ return 0;
133
+ }
134
+ return float64_to_int64_round_to_zero(f, s);
135
+}
136
+
137
+static inline uint16_t vfp_float16_to_uint16_rtz(float16 f, float_status *s)
138
+{
139
+ if (float16_is_any_nan(f)) {
140
+ float_raise(float_flag_invalid, s);
141
+ return 0;
142
+ }
143
+ return float16_to_uint16_round_to_zero(f, s);
144
+}
145
+
146
+static inline uint64_t vfp_float16_to_uint64_rtz(float16 f, float_status *s)
147
+{
148
+ if (float16_is_any_nan(f)) {
149
+ float_raise(float_flag_invalid, s);
150
+ return 0;
151
+ }
152
+ return float16_to_uint64_round_to_zero(f, s);
153
+}
154
+
155
+static inline uint64_t vfp_float32_to_uint64_rtz(float32 f, float_status *s)
156
+{
157
+ if (float32_is_any_nan(f)) {
158
+ float_raise(float_flag_invalid, s);
159
+ return 0;
160
+ }
161
+ return float32_to_uint64_round_to_zero(f, s);
162
+}
163
+
164
+static inline uint64_t vfp_float64_to_uint64_rtz(float64 f, float_status *s)
165
+{
166
+ if (float64_is_any_nan(f)) {
167
+ float_raise(float_flag_invalid, s);
168
+ return 0;
169
+ }
170
+ return float64_to_uint64_round_to_zero(f, s);
171
+}
172
+
173
DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
174
DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
175
DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
176
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
177
DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
178
DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
179
180
+DO_ZPZ_FP(sve_fcvtzs_hh, uint16_t, H1_2, vfp_float16_to_int16_rtz)
181
+DO_ZPZ_FP(sve_fcvtzs_hs, uint32_t, H1_4, helper_vfp_tosizh)
182
+DO_ZPZ_FP(sve_fcvtzs_ss, uint32_t, H1_4, helper_vfp_tosizs)
183
+DO_ZPZ_FP(sve_fcvtzs_hd, uint64_t, , vfp_float16_to_int64_rtz)
184
+DO_ZPZ_FP(sve_fcvtzs_sd, uint64_t, , vfp_float32_to_int64_rtz)
185
+DO_ZPZ_FP(sve_fcvtzs_ds, uint64_t, , helper_vfp_tosizd)
186
+DO_ZPZ_FP(sve_fcvtzs_dd, uint64_t, , vfp_float64_to_int64_rtz)
187
+
188
+DO_ZPZ_FP(sve_fcvtzu_hh, uint16_t, H1_2, vfp_float16_to_uint16_rtz)
189
+DO_ZPZ_FP(sve_fcvtzu_hs, uint32_t, H1_4, helper_vfp_touizh)
190
+DO_ZPZ_FP(sve_fcvtzu_ss, uint32_t, H1_4, helper_vfp_touizs)
191
+DO_ZPZ_FP(sve_fcvtzu_hd, uint64_t, , vfp_float16_to_uint64_rtz)
192
+DO_ZPZ_FP(sve_fcvtzu_sd, uint64_t, , vfp_float32_to_uint64_rtz)
193
+DO_ZPZ_FP(sve_fcvtzu_ds, uint64_t, , helper_vfp_touizd)
194
+DO_ZPZ_FP(sve_fcvtzu_dd, uint64_t, , vfp_float64_to_uint64_rtz)
195
+
196
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
197
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
198
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
199
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/target/arm/translate-sve.c
202
+++ b/target/arm/translate-sve.c
203
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
204
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sd);
205
}
42
}
206
43
207
+static bool trans_FCVTZS_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
208
+{
209
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hh);
210
+}
211
+
212
+static bool trans_FCVTZU_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
213
+{
214
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hh);
215
+}
216
+
217
+static bool trans_FCVTZS_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
218
+{
219
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hs);
220
+}
221
+
222
+static bool trans_FCVTZU_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
223
+{
224
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hs);
225
+}
226
+
227
+static bool trans_FCVTZS_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
228
+{
229
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hd);
230
+}
231
+
232
+static bool trans_FCVTZU_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
233
+{
234
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hd);
235
+}
236
+
237
+static bool trans_FCVTZS_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
238
+{
239
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_ss);
240
+}
241
+
242
+static bool trans_FCVTZU_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
243
+{
244
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_ss);
245
+}
246
+
247
+static bool trans_FCVTZS_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
248
+{
249
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_sd);
250
+}
251
+
252
+static bool trans_FCVTZU_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
253
+{
254
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_sd);
255
+}
256
+
257
+static bool trans_FCVTZS_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
258
+{
259
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_ds);
260
+}
261
+
262
+static bool trans_FCVTZU_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
263
+{
264
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_ds);
265
+}
266
+
267
+static bool trans_FCVTZS_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
268
+{
269
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_dd);
270
+}
271
+
272
+static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
273
+{
274
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
275
+}
276
+
277
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
278
{
279
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
280
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/arm/sve.decode
283
+++ b/target/arm/sve.decode
284
@@ -XXX,XX +XXX,XX @@ FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
285
FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
286
FCVT_sd 01100101 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
287
288
+# SVE floating-point convert to integer
289
+FCVTZS_hh 01100101 01 011 01 0 101 ... ..... ..... @rd_pg_rn_e0
290
+FCVTZU_hh 01100101 01 011 01 1 101 ... ..... ..... @rd_pg_rn_e0
291
+FCVTZS_hs 01100101 01 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
292
+FCVTZU_hs 01100101 01 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
293
+FCVTZS_hd 01100101 01 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
294
+FCVTZU_hd 01100101 01 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
295
+FCVTZS_ss 01100101 10 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
296
+FCVTZU_ss 01100101 10 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
297
+FCVTZS_ds 01100101 11 011 00 0 101 ... ..... ..... @rd_pg_rn_e0
298
+FCVTZU_ds 01100101 11 011 00 1 101 ... ..... ..... @rd_pg_rn_e0
299
+FCVTZS_sd 01100101 11 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
300
+FCVTZU_sd 01100101 11 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
301
+FCVTZS_dd 01100101 11 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
302
+FCVTZU_dd 01100101 11 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
303
+
304
# SVE integer convert to floating-point
305
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
306
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
307
--
44
--
308
2.17.1
45
2.34.1
309
46
310
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-14-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
8
---
9
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
10
target/arm/sve_helper.c | 77 ++++++++++++++++++++++++++++
10
1 file changed, 22 insertions(+), 4 deletions(-)
11
target/arm/translate-sve.c | 100 +++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 57 +++++++++++++++++++++
13
4 files changed, 301 insertions(+)
14
11
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
14
--- a/hw/arm/stellaris.c
18
+++ b/target/arm/helper-sve.h
15
+++ b/hw/arm/stellaris.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
20
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
18
}
22
19
23
+DEF_HELPER_FLAGS_6(sve_ldbsu_zsu, TCG_CALL_NO_WG,
20
-/* I2C controller. */
24
+ void, env, ptr, ptr, ptr, tl, i32)
21
+/*
25
+DEF_HELPER_FLAGS_6(sve_ldhsu_zsu, TCG_CALL_NO_WG,
22
+ * I2C controller.
26
+ void, env, ptr, ptr, ptr, tl, i32)
23
+ * ??? For now we only implement the master interface.
27
+DEF_HELPER_FLAGS_6(sve_ldssu_zsu, TCG_CALL_NO_WG,
24
+ */
28
+ void, env, ptr, ptr, ptr, tl, i32)
25
29
+DEF_HELPER_FLAGS_6(sve_ldbss_zsu, TCG_CALL_NO_WG,
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
30
+ void, env, ptr, ptr, ptr, tl, i32)
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
31
+DEF_HELPER_FLAGS_6(sve_ldhss_zsu, TCG_CALL_NO_WG,
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
32
+ void, env, ptr, ptr, ptr, tl, i32)
29
stellaris_i2c_update(s);
30
}
31
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
34
{
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
33
+
36
+
34
+DEF_HELPER_FLAGS_6(sve_ldbsu_zss, TCG_CALL_NO_WG,
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
35
+ void, env, ptr, ptr, ptr, tl, i32)
38
i2c_end_transfer(s->bus);
36
+DEF_HELPER_FLAGS_6(sve_ldhsu_zss, TCG_CALL_NO_WG,
37
+ void, env, ptr, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_6(sve_ldssu_zss, TCG_CALL_NO_WG,
39
+ void, env, ptr, ptr, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_6(sve_ldbss_zss, TCG_CALL_NO_WG,
41
+ void, env, ptr, ptr, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_6(sve_ldhss_zss, TCG_CALL_NO_WG,
43
+ void, env, ptr, ptr, ptr, tl, i32)
44
+
45
+DEF_HELPER_FLAGS_6(sve_ldbdu_zsu, TCG_CALL_NO_WG,
46
+ void, env, ptr, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_6(sve_ldhdu_zsu, TCG_CALL_NO_WG,
48
+ void, env, ptr, ptr, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_6(sve_ldsdu_zsu, TCG_CALL_NO_WG,
50
+ void, env, ptr, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_6(sve_ldddu_zsu, TCG_CALL_NO_WG,
52
+ void, env, ptr, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_6(sve_ldbds_zsu, TCG_CALL_NO_WG,
54
+ void, env, ptr, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_6(sve_ldhds_zsu, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_6(sve_ldsds_zsu, TCG_CALL_NO_WG,
58
+ void, env, ptr, ptr, ptr, tl, i32)
59
+
60
+DEF_HELPER_FLAGS_6(sve_ldbdu_zss, TCG_CALL_NO_WG,
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_6(sve_ldhdu_zss, TCG_CALL_NO_WG,
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_6(sve_ldsdu_zss, TCG_CALL_NO_WG,
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_6(sve_ldddu_zss, TCG_CALL_NO_WG,
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+DEF_HELPER_FLAGS_6(sve_ldbds_zss, TCG_CALL_NO_WG,
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_6(sve_ldhds_zss, TCG_CALL_NO_WG,
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+DEF_HELPER_FLAGS_6(sve_ldsds_zss, TCG_CALL_NO_WG,
73
+ void, env, ptr, ptr, ptr, tl, i32)
74
+
75
+DEF_HELPER_FLAGS_6(sve_ldbdu_zd, TCG_CALL_NO_WG,
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_6(sve_ldhdu_zd, TCG_CALL_NO_WG,
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_6(sve_ldsdu_zd, TCG_CALL_NO_WG,
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+DEF_HELPER_FLAGS_6(sve_ldddu_zd, TCG_CALL_NO_WG,
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_6(sve_ldbds_zd, TCG_CALL_NO_WG,
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
88
+ void, env, ptr, ptr, ptr, tl, i32)
89
+
90
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
91
void, env, ptr, ptr, ptr, tl, i32)
92
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
98
}
99
}
100
101
+/* Loads with a vector index. */
102
+
103
+#define DO_LD1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
105
+ target_ulong base, uint32_t desc) \
106
+{ \
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
108
+ unsigned scale = simd_data(desc); \
109
+ uintptr_t ra = GETPC(); \
110
+ for (i = 0; i < oprsz; i++) { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ TYPEM m = 0; \
114
+ if (pg & 1) { \
115
+ target_ulong off = *(TYPEI *)(vm + H1_4(i)); \
116
+ m = FN(env, base + (off << scale), ra); \
117
+ } \
118
+ *(uint32_t *)(vd + H1_4(i)) = m; \
119
+ i += 4, pg >>= 4; \
120
+ } while (i & 15); \
121
+ } \
122
+}
39
+}
123
+
40
+
124
+#define DO_LD1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
41
+static void stellaris_i2c_reset_hold(Object *obj)
125
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
42
+{
126
+ target_ulong base, uint32_t desc) \
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
127
+{ \
44
128
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
45
s->msa = 0;
129
+ unsigned scale = simd_data(desc); \
46
s->mcs = 0;
130
+ uintptr_t ra = GETPC(); \
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
131
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
48
s->mimr = 0;
132
+ for (i = 0; i < oprsz; i++) { \
49
s->mris = 0;
133
+ TYPEM mm = 0; \
50
s->mcr = 0;
134
+ if (pg[H1(i)] & 1) { \
135
+ target_ulong off = (TYPEI)m[i]; \
136
+ mm = FN(env, base + (off << scale), ra); \
137
+ } \
138
+ d[i] = mm; \
139
+ } \
140
+}
51
+}
141
+
52
+
142
+DO_LD1_ZPZ_S(sve_ldbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
53
+static void stellaris_i2c_reset_exit(Object *obj)
143
+DO_LD1_ZPZ_S(sve_ldhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
54
+{
144
+DO_LD1_ZPZ_S(sve_ldssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
145
+DO_LD1_ZPZ_S(sve_ldbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
146
+DO_LD1_ZPZ_S(sve_ldhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
147
+
56
+
148
+DO_LD1_ZPZ_S(sve_ldbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
57
stellaris_i2c_update(s);
149
+DO_LD1_ZPZ_S(sve_ldhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
150
+DO_LD1_ZPZ_S(sve_ldssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
151
+DO_LD1_ZPZ_S(sve_ldbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
152
+DO_LD1_ZPZ_S(sve_ldhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
153
+
154
+DO_LD1_ZPZ_D(sve_ldbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
155
+DO_LD1_ZPZ_D(sve_ldhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
156
+DO_LD1_ZPZ_D(sve_ldsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
157
+DO_LD1_ZPZ_D(sve_ldddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
158
+DO_LD1_ZPZ_D(sve_ldbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
159
+DO_LD1_ZPZ_D(sve_ldhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
160
+DO_LD1_ZPZ_D(sve_ldsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
161
+
162
+DO_LD1_ZPZ_D(sve_ldbdu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
163
+DO_LD1_ZPZ_D(sve_ldhdu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
164
+DO_LD1_ZPZ_D(sve_ldsdu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
165
+DO_LD1_ZPZ_D(sve_ldddu_zss, int32_t, uint64_t, cpu_ldq_data_ra)
166
+DO_LD1_ZPZ_D(sve_ldbds_zss, int32_t, int8_t, cpu_ldub_data_ra)
167
+DO_LD1_ZPZ_D(sve_ldhds_zss, int32_t, int16_t, cpu_lduw_data_ra)
168
+DO_LD1_ZPZ_D(sve_ldsds_zss, int32_t, int32_t, cpu_ldl_data_ra)
169
+
170
+DO_LD1_ZPZ_D(sve_ldbdu_zd, uint64_t, uint8_t, cpu_ldub_data_ra)
171
+DO_LD1_ZPZ_D(sve_ldhdu_zd, uint64_t, uint16_t, cpu_lduw_data_ra)
172
+DO_LD1_ZPZ_D(sve_ldsdu_zd, uint64_t, uint32_t, cpu_ldl_data_ra)
173
+DO_LD1_ZPZ_D(sve_ldddu_zd, uint64_t, uint64_t, cpu_ldq_data_ra)
174
+DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
175
+DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
176
+DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
177
+
178
/* Stores with a vector index. */
179
180
#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
181
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate-sve.c
184
+++ b/target/arm/translate-sve.c
185
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
186
tcg_temp_free_i32(desc);
187
}
58
}
188
59
189
+/* Indexed by [ff][xs][u][msz]. */
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
190
+static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
191
+ { { { gen_helper_sve_ldbss_zsu,
62
"i2c", 0x1000);
192
+ gen_helper_sve_ldhss_zsu,
63
sysbus_init_mmio(sbd, &s->iomem);
193
+ NULL, },
64
- /* ??? For now we only implement the master interface. */
194
+ { gen_helper_sve_ldbsu_zsu,
65
- stellaris_i2c_reset(s);
195
+ gen_helper_sve_ldhsu_zsu,
66
}
196
+ gen_helper_sve_ldssu_zsu, } },
67
197
+ { { gen_helper_sve_ldbss_zss,
68
/* Analogue to Digital Converter. This is only partially implemented,
198
+ gen_helper_sve_ldhss_zss,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
199
+ NULL, },
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
200
+ { gen_helper_sve_ldbsu_zss,
201
+ gen_helper_sve_ldhsu_zss,
202
+ gen_helper_sve_ldssu_zss, } } },
203
+ /* TODO fill in first-fault handlers */
204
+};
205
+
206
+/* Note that we overload xs=2 to indicate 64-bit offset. */
207
+static gen_helper_gvec_mem_scatter * const gather_load_fn64[2][3][2][4] = {
208
+ { { { gen_helper_sve_ldbds_zsu,
209
+ gen_helper_sve_ldhds_zsu,
210
+ gen_helper_sve_ldsds_zsu,
211
+ NULL, },
212
+ { gen_helper_sve_ldbdu_zsu,
213
+ gen_helper_sve_ldhdu_zsu,
214
+ gen_helper_sve_ldsdu_zsu,
215
+ gen_helper_sve_ldddu_zsu, } },
216
+ { { gen_helper_sve_ldbds_zss,
217
+ gen_helper_sve_ldhds_zss,
218
+ gen_helper_sve_ldsds_zss,
219
+ NULL, },
220
+ { gen_helper_sve_ldbdu_zss,
221
+ gen_helper_sve_ldhdu_zss,
222
+ gen_helper_sve_ldsdu_zss,
223
+ gen_helper_sve_ldddu_zss, } },
224
+ { { gen_helper_sve_ldbds_zd,
225
+ gen_helper_sve_ldhds_zd,
226
+ gen_helper_sve_ldsds_zd,
227
+ NULL, },
228
+ { gen_helper_sve_ldbdu_zd,
229
+ gen_helper_sve_ldhdu_zd,
230
+ gen_helper_sve_ldsdu_zd,
231
+ gen_helper_sve_ldddu_zd, } } },
232
+ /* TODO fill in first-fault handlers */
233
+};
234
+
235
+static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a, uint32_t insn)
236
+{
237
+ gen_helper_gvec_mem_scatter *fn = NULL;
238
+
239
+ if (!sve_access_check(s)) {
240
+ return true;
241
+ }
242
+
243
+ switch (a->esz) {
244
+ case MO_32:
245
+ fn = gather_load_fn32[a->ff][a->xs][a->u][a->msz];
246
+ break;
247
+ case MO_64:
248
+ fn = gather_load_fn64[a->ff][a->xs][a->u][a->msz];
249
+ break;
250
+ }
251
+ assert(fn != NULL);
252
+
253
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
254
+ cpu_reg_sp(s, a->rn), fn);
255
+ return true;
256
+}
257
+
258
+static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
259
+{
260
+ gen_helper_gvec_mem_scatter *fn = NULL;
261
+ TCGv_i64 imm;
262
+
263
+ if (a->esz < a->msz || (a->esz == a->msz && !a->u)) {
264
+ return false;
265
+ }
266
+ if (!sve_access_check(s)) {
267
+ return true;
268
+ }
269
+
270
+ switch (a->esz) {
271
+ case MO_32:
272
+ fn = gather_load_fn32[a->ff][0][a->u][a->msz];
273
+ break;
274
+ case MO_64:
275
+ fn = gather_load_fn64[a->ff][2][a->u][a->msz];
276
+ break;
277
+ }
278
+ assert(fn != NULL);
279
+
280
+ /* Treat LD1_zpiz (zn[x] + imm) the same way as LD1_zprz (rn + zm[x])
281
+ * by loading the immediate into the scalar parameter.
282
+ */
283
+ imm = tcg_const_i64(a->imm << a->msz);
284
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
285
+ tcg_temp_free_i64(imm);
286
+ return true;
287
+}
288
+
289
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
290
{
71
{
291
/* Indexed by [xs][msz]. */
72
DeviceClass *dc = DEVICE_CLASS(klass);
292
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
293
index XXXXXXX..XXXXXXX 100644
74
294
--- a/target/arm/sve.decode
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
295
+++ b/target/arm/sve.decode
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
296
@@ -XXX,XX +XXX,XX @@
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
297
&rpri_load rd pg rn imm dtype nreg
78
dc->vmsd = &vmstate_stellaris_i2c;
298
&rprr_store rd pg rn rm msz esz nreg
79
}
299
&rpri_store rd pg rn imm msz esz nreg
300
+&rprr_gather_load rd pg rn rm esz msz u ff xs scale
301
+&rpri_gather_load rd pg rn imm esz msz u ff
302
&rprr_scatter_store rd pg rn rm esz msz xs scale
303
304
###########################################################################
305
@@ -XXX,XX +XXX,XX @@
306
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
307
&rpri_load dtype=%msz_dtype
308
309
+# Gather Loads.
310
+@rprr_g_load_u ....... .. . . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
311
+ &rprr_gather_load xs=2
312
+@rprr_g_load_xs_u ....... .. xs:1 . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
313
+ &rprr_gather_load
314
+@rprr_g_load_xs_u_sc ....... .. xs:1 scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
315
+ &rprr_gather_load
316
+@rprr_g_load_xs_sc ....... .. xs:1 scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
317
+ &rprr_gather_load
318
+@rprr_g_load_u_sc ....... .. . scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
319
+ &rprr_gather_load xs=2
320
+@rprr_g_load_sc ....... .. . scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
321
+ &rprr_gather_load xs=2
322
+@rpri_g_load ....... msz:2 .. imm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
323
+ &rpri_gather_load
324
+
325
# Stores; user must fill in ESZ, MSZ, NREG as needed.
326
@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
327
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
328
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
329
LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
330
&rpri_load dtype=%dtype_23_13 nreg=0
331
332
+# SVE 32-bit gather load (scalar plus 32-bit unscaled offsets)
333
+# SVE 32-bit gather load (scalar plus 32-bit scaled offsets)
334
+LD1_zprz 1000010 00 .0 ..... 0.. ... ..... ..... \
335
+ @rprr_g_load_xs_u esz=2 msz=0 scale=0
336
+LD1_zprz 1000010 01 .. ..... 0.. ... ..... ..... \
337
+ @rprr_g_load_xs_u_sc esz=2 msz=1
338
+LD1_zprz 1000010 10 .. ..... 01. ... ..... ..... \
339
+ @rprr_g_load_xs_sc esz=2 msz=2 u=1
340
+
341
+# SVE 32-bit gather load (vector plus immediate)
342
+LD1_zpiz 1000010 .. 01 ..... 1.. ... ..... ..... \
343
+ @rpri_g_load esz=2
344
+
345
### SVE Memory Contiguous Load Group
346
347
# SVE contiguous load (scalar plus scalar)
348
@@ -XXX,XX +XXX,XX @@ PRF_rr 1000010 -- 00 rm:5 110 --- ----- 0 ----
349
350
### SVE Memory 64-bit Gather Group
351
352
+# SVE 64-bit gather load (scalar plus 32-bit unpacked unscaled offsets)
353
+# SVE 64-bit gather load (scalar plus 32-bit unpacked scaled offsets)
354
+LD1_zprz 1100010 00 .0 ..... 0.. ... ..... ..... \
355
+ @rprr_g_load_xs_u esz=3 msz=0 scale=0
356
+LD1_zprz 1100010 01 .. ..... 0.. ... ..... ..... \
357
+ @rprr_g_load_xs_u_sc esz=3 msz=1
358
+LD1_zprz 1100010 10 .. ..... 0.. ... ..... ..... \
359
+ @rprr_g_load_xs_u_sc esz=3 msz=2
360
+LD1_zprz 1100010 11 .. ..... 01. ... ..... ..... \
361
+ @rprr_g_load_xs_sc esz=3 msz=3 u=1
362
+
363
+# SVE 64-bit gather load (scalar plus 64-bit unscaled offsets)
364
+# SVE 64-bit gather load (scalar plus 64-bit scaled offsets)
365
+LD1_zprz 1100010 00 10 ..... 1.. ... ..... ..... \
366
+ @rprr_g_load_u esz=3 msz=0 scale=0
367
+LD1_zprz 1100010 01 1. ..... 1.. ... ..... ..... \
368
+ @rprr_g_load_u_sc esz=3 msz=1
369
+LD1_zprz 1100010 10 1. ..... 1.. ... ..... ..... \
370
+ @rprr_g_load_u_sc esz=3 msz=2
371
+LD1_zprz 1100010 11 1. ..... 11. ... ..... ..... \
372
+ @rprr_g_load_sc esz=3 msz=3 u=1
373
+
374
+# SVE 64-bit gather load (vector plus immediate)
375
+LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
376
+ @rpri_g_load esz=3
377
+
378
# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
379
PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
380
80
381
--
81
--
382
2.17.1
82
2.34.1
383
83
384
84
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The qdev_get_gpio_in() function accept an int as second parameter.
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
4
5
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
This commit plug the devices which aren't part of the SoC;
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
they will be plugged into a SoC container in the next one.
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
hw/arm/fsl-imx7.c | 6 +++---
14
hw/arm/stellaris.c | 4 ++++
11
1 file changed, 3 insertions(+), 3 deletions(-)
15
1 file changed, 4 insertions(+)
12
16
13
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx7.c
19
--- a/hw/arm/stellaris.c
16
+++ b/hw/arm/fsl-imx7.c
20
+++ b/hw/arm/stellaris.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
18
FSL_IMX7_ECSPI4_ADDR,
22
&error_fatal);
19
};
23
20
24
ssddev = qdev_new("ssd0323");
21
- static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
22
+ static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
26
qdev_prop_set_uint8(ssddev, "cs", 1);
23
FSL_IMX7_ECSPI1_IRQ,
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
24
FSL_IMX7_ECSPI2_IRQ,
28
25
FSL_IMX7_ECSPI3_IRQ,
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
26
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
30
+ object_property_add_child(OBJECT(ms), "splitter",
27
FSL_IMX7_I2C4_ADDR,
31
+ OBJECT(gpio_d_splitter));
28
};
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
29
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
30
- static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
34
qdev_connect_gpio_out(
31
+ static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
32
FSL_IMX7_I2C1_IRQ,
36
DeviceState *gpad;
33
FSL_IMX7_I2C2_IRQ,
37
34
FSL_IMX7_I2C3_IRQ,
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
36
FSL_IMX7_USB3_ADDR,
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
37
};
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
38
42
}
39
- static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
40
+ static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
41
FSL_IMX7_USB1_IRQ,
42
FSL_IMX7_USB2_IRQ,
43
FSL_IMX7_USB3_IRQ,
44
--
43
--
45
2.17.1
44
2.34.1
46
45
47
46
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
5
6
Since we don't model the SoC, just use a QOM container.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
12
---
7
hw/arm/mcimx7d-sabre.c | 2 --
13
hw/arm/stellaris.c | 11 ++++++++++-
8
1 file changed, 2 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
9
15
10
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
11
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mcimx7d-sabre.c
18
--- a/hw/arm/stellaris.c
13
+++ b/hw/arm/mcimx7d-sabre.c
19
+++ b/hw/arm/stellaris.c
14
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
15
#include "hw/arm/fsl-imx7.h"
21
* 400fe000 system control
16
#include "hw/boards.h"
22
*/
17
#include "sysemu/sysemu.h"
23
18
-#include "sysemu/device_tree.h"
24
+ Object *soc_container;
19
#include "qemu/error-report.h"
25
DeviceState *gpio_dev[7], *nvic;
20
#include "sysemu/qtest.h"
26
qemu_irq gpio_in[7][8];
21
-#include "net/net.h"
27
qemu_irq gpio_out[7][8];
22
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
23
typedef struct {
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
24
FslIMX7State soc;
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
31
32
+ soc_container = object_new("container");
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
34
+
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
37
&error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
39
* need its sysclk output.
40
*/
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
44
/*
45
* Most devices come preprogrammed with a MAC address in the user data.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
48
49
nvic = qdev_new(TYPE_ARMV7M);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
57
sbd = SYS_BUS_DEVICE(dev);
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
59
qdev_connect_clock_in(dev, "clk",
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
61
sysbus_realize_and_unref(sbd, &error_fatal);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
66
-
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
68
qdev_connect_clock_in(dev, "WDOGCLK",
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
70
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
SysBusDevice *sbd;
73
74
dev = qdev_new("pl011_luminary");
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
76
sbd = SYS_BUS_DEVICE(dev);
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
78
sysbus_realize_and_unref(sbd, &error_fatal);
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
DeviceState *enet;
81
82
enet = qdev_new("stellaris_enet");
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
84
if (nd) {
85
qdev_set_nic_properties(enet, nd);
86
} else {
25
--
87
--
26
2.17.1
88
2.34.1
27
89
28
90
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
We support two different encodings for the AArch32 IMPDEF
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
2
5
3
This makes it match its AArch64 equivalent, PMINTENSET_EL1
6
When we implemented this we picked which encoding to
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
4
19
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
20
Make the decision of the encoding be based on whether
6
Message-id: 1529699547-17044-13-git-send-email-alindsay@codeaurora.org
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
31
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
8
---
35
---
9
target/arm/helper.c | 2 +-
36
target/arm/helper.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
11
38
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
17
.writefn = pmuserenr_write, .raw_writefn = raw_write },
44
* AArch64 cores we might need to add a specific feature flag
18
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
45
* to indicate cores with "flavour 2" CBAR.
19
.access = PL1_RW, .accessfn = access_tpm,
46
*/
20
- .type = ARM_CP_ALIAS,
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
21
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
22
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
23
.resetvalue = 0,
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
24
.writefn = pmintenset_write, .raw_writefn = raw_write },
51
| extract64(cpu->reset_cbar, 32, 12);
25
--
52
--
26
2.17.1
53
2.34.1
27
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The Cortex-R52 implements the Configuration Base Address Register
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
2
5
3
Enhance the existing helpers to support SVE, which takes the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
index from each 128-bit segment. The change has no effect
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
for AdvSIMD, since there is only one such segment.
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 1 +
11
1 file changed, 1 insertion(+)
6
12
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180627043328.11531-32-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 23 ++++++++++++++++++
14
target/arm/vec_helper.c | 50 +++++++++++++++++++++++---------------
15
target/arm/sve.decode | 6 +++++
16
3 files changed, 59 insertions(+), 20 deletions(-)
17
18
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-sve.c
15
--- a/target/arm/tcg/cpu32.c
21
+++ b/target/arm/translate-sve.c
16
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zpzzz(DisasContext *s,
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
23
return true;
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
24
}
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
25
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
26
+static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a, uint32_t insn)
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
27
+{
22
cpu->midr = 0x411fd133; /* r1p3 */
28
+ static gen_helper_gvec_3_ptr * const fns[2] = {
23
cpu->revidr = 0x00000000;
29
+ gen_helper_gvec_fcmlah_idx,
24
cpu->reset_fpsid = 0x41034023;
30
+ gen_helper_gvec_fcmlas_idx,
31
+ };
32
+
33
+ tcg_debug_assert(a->esz == 1 || a->esz == 2);
34
+ tcg_debug_assert(a->rd == a->ra);
35
+ if (sve_access_check(s)) {
36
+ unsigned vsz = vec_full_reg_size(s);
37
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
38
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
39
+ vec_full_reg_offset(s, a->rn),
40
+ vec_full_reg_offset(s, a->rm),
41
+ status, vsz, vsz,
42
+ a->index * 4 + a->rot,
43
+ fns[a->esz - 1]);
44
+ tcg_temp_free_ptr(status);
45
+ }
46
+ return true;
47
+}
48
+
49
/*
50
*** SVE Floating Point Unary Operations Predicated Group
51
*/
52
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/vec_helper.c
55
+++ b/target/arm/vec_helper.c
56
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
57
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
58
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
59
uint32_t neg_real = flip ^ neg_imag;
60
- uintptr_t i;
61
- float16 e1 = m[H2(2 * index + flip)];
62
- float16 e3 = m[H2(2 * index + 1 - flip)];
63
+ intptr_t elements = opr_sz / sizeof(float16);
64
+ intptr_t eltspersegment = 16 / sizeof(float16);
65
+ intptr_t i, j;
66
67
/* Shift boolean to the sign bit so we can xor to negate. */
68
neg_real <<= 15;
69
neg_imag <<= 15;
70
- e1 ^= neg_real;
71
- e3 ^= neg_imag;
72
73
- for (i = 0; i < opr_sz / 2; i += 2) {
74
- float16 e2 = n[H2(i + flip)];
75
- float16 e4 = e2;
76
+ for (i = 0; i < elements; i += eltspersegment) {
77
+ float16 mr = m[H2(i + 2 * index + 0)];
78
+ float16 mi = m[H2(i + 2 * index + 1)];
79
+ float16 e1 = neg_real ^ (flip ? mi : mr);
80
+ float16 e3 = neg_imag ^ (flip ? mr : mi);
81
82
- d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst);
83
- d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst);
84
+ for (j = i; j < i + eltspersegment; j += 2) {
85
+ float16 e2 = n[H2(j + flip)];
86
+ float16 e4 = e2;
87
+
88
+ d[H2(j)] = float16_muladd(e2, e1, d[H2(j)], 0, fpst);
89
+ d[H2(j + 1)] = float16_muladd(e4, e3, d[H2(j + 1)], 0, fpst);
90
+ }
91
}
92
clear_tail(d, opr_sz, simd_maxsz(desc));
93
}
94
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
95
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
96
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
97
uint32_t neg_real = flip ^ neg_imag;
98
- uintptr_t i;
99
- float32 e1 = m[H4(2 * index + flip)];
100
- float32 e3 = m[H4(2 * index + 1 - flip)];
101
+ intptr_t elements = opr_sz / sizeof(float32);
102
+ intptr_t eltspersegment = 16 / sizeof(float32);
103
+ intptr_t i, j;
104
105
/* Shift boolean to the sign bit so we can xor to negate. */
106
neg_real <<= 31;
107
neg_imag <<= 31;
108
- e1 ^= neg_real;
109
- e3 ^= neg_imag;
110
111
- for (i = 0; i < opr_sz / 4; i += 2) {
112
- float32 e2 = n[H4(i + flip)];
113
- float32 e4 = e2;
114
+ for (i = 0; i < elements; i += eltspersegment) {
115
+ float32 mr = m[H4(i + 2 * index + 0)];
116
+ float32 mi = m[H4(i + 2 * index + 1)];
117
+ float32 e1 = neg_real ^ (flip ? mi : mr);
118
+ float32 e3 = neg_imag ^ (flip ? mr : mi);
119
120
- d[H4(i)] = float32_muladd(e2, e1, d[H4(i)], 0, fpst);
121
- d[H4(i + 1)] = float32_muladd(e4, e3, d[H4(i + 1)], 0, fpst);
122
+ for (j = i; j < i + eltspersegment; j += 2) {
123
+ float32 e2 = n[H4(j + flip)];
124
+ float32 e4 = e2;
125
+
126
+ d[H4(j)] = float32_muladd(e2, e1, d[H4(j)], 0, fpst);
127
+ d[H4(j + 1)] = float32_muladd(e4, e3, d[H4(j + 1)], 0, fpst);
128
+ }
129
}
130
clear_tail(d, opr_sz, simd_maxsz(desc));
131
}
132
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/sve.decode
135
+++ b/target/arm/sve.decode
136
@@ -XXX,XX +XXX,XX @@ FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
137
FCMLA_zpzzz 01100100 esz:2 0 rm:5 0 rot:2 pg:3 rn:5 rd:5 \
138
ra=%reg_movprfx
139
140
+# SVE floating-point complex multiply-add (indexed)
141
+FCMLA_zzxz 01100100 10 1 index:2 rm:3 0001 rot:2 rn:5 rd:5 \
142
+ ra=%reg_movprfx esz=1
143
+FCMLA_zzxz 01100100 11 1 index:1 rm:4 0001 rot:2 rn:5 rd:5 \
144
+ ra=%reg_movprfx esz=2
145
+
146
### SVE FP Multiply-Add Indexed Group
147
148
# SVE floating-point multiply-add (indexed)
149
--
25
--
150
2.17.1
26
2.34.1
151
152
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also by enabling the AUXCR feature which defines the ACTLR
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
2
5
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-34-richard.henderson@linaro.org
7
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: 20240206132931.38376-4-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper.h | 5 ++
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 18 ++++++
11
1 file changed, 108 insertions(+)
11
target/arm/vec_helper.c | 124 +++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 6 ++
13
4 files changed, 153 insertions(+)
14
12
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
15
--- a/target/arm/tcg/cpu32.c
18
+++ b/target/arm/helper.h
16
+++ b/target/arm/tcg/cpu32.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
20
DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
21
DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(gvec_udot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(gvec_udot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
29
void, ptr, ptr, ptr, ptr, i32)
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
34
+++ b/target/arm/translate-sve.c
35
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
36
return true;
37
}
19
}
38
20
39
+static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a, uint32_t insn)
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
40
+{
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
42
+ { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
24
+ { .name = "IMP_ATCMREGIONR",
43
+ { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h }
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
44
+ };
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+
27
+ { .name = "IMP_BTCMREGIONR",
46
+ if (sve_access_check(s)) {
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
47
+ unsigned vsz = vec_full_reg_size(s);
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
30
+ { .name = "IMP_CTCMREGIONR",
49
+ vec_full_reg_offset(s, a->rn),
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
50
+ vec_full_reg_offset(s, a->rm),
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ vsz, vsz, a->index, fns[a->u][a->sz]);
33
+ { .name = "IMP_CSCTLR",
52
+ }
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
53
+ return true;
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+}
36
+ { .name = "IMP_BPCTLR",
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
39
+ { .name = "IMP_MEMPROTCLR",
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ { .name = "IMP_SLAVEPCTLR",
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ { .name = "IMP_PERIPHREGIONR",
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ { .name = "IMP_FLASHIFREGIONR",
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ { .name = "IMP_BUILDOPTR",
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+ { .name = "IMP_PINOPTR",
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
+ { .name = "IMP_QOSR",
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
60
+ { .name = "IMP_BUSTIMEOUTR",
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
+ { .name = "IMP_INTMONR",
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
+ { .name = "IMP_ICERR0",
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
+ { .name = "IMP_ICERR1",
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
+ { .name = "IMP_DCERR0",
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "IMP_DCERR1",
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
55
+
124
+
56
+
125
+
57
/*
126
static void cortex_r52_initfn(Object *obj)
58
*** SVE Floating Point Multiply-Add Indexed Group
127
{
59
*/
128
ARMCPU *cpu = ARM_CPU(obj);
60
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
61
index XXXXXXX..XXXXXXX 100644
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
62
--- a/target/arm/vec_helper.c
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
63
+++ b/target/arm/vec_helper.c
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
64
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
65
clear_tail(d, opr_sz, simd_maxsz(desc));
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
141
+
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
66
}
143
}
67
144
68
+void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
145
static void cortex_r5f_initfn(Object *obj)
69
+{
70
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
71
+ intptr_t index = simd_data(desc);
72
+ uint32_t *d = vd;
73
+ int8_t *n = vn;
74
+ int8_t *m_indexed = (int8_t *)vm + index * 4;
75
+
76
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
77
+ * Otherwise opr_sz is a multiple of 16.
78
+ */
79
+ segend = MIN(4, opr_sz_4);
80
+ i = 0;
81
+ do {
82
+ int8_t m0 = m_indexed[i * 4 + 0];
83
+ int8_t m1 = m_indexed[i * 4 + 1];
84
+ int8_t m2 = m_indexed[i * 4 + 2];
85
+ int8_t m3 = m_indexed[i * 4 + 3];
86
+
87
+ do {
88
+ d[i] += n[i * 4 + 0] * m0
89
+ + n[i * 4 + 1] * m1
90
+ + n[i * 4 + 2] * m2
91
+ + n[i * 4 + 3] * m3;
92
+ } while (++i < segend);
93
+ segend = i + 4;
94
+ } while (i < opr_sz_4);
95
+
96
+ clear_tail(d, opr_sz, simd_maxsz(desc));
97
+}
98
+
99
+void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
100
+{
101
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
102
+ intptr_t index = simd_data(desc);
103
+ uint32_t *d = vd;
104
+ uint8_t *n = vn;
105
+ uint8_t *m_indexed = (uint8_t *)vm + index * 4;
106
+
107
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
108
+ * Otherwise opr_sz is a multiple of 16.
109
+ */
110
+ segend = MIN(4, opr_sz_4);
111
+ i = 0;
112
+ do {
113
+ uint8_t m0 = m_indexed[i * 4 + 0];
114
+ uint8_t m1 = m_indexed[i * 4 + 1];
115
+ uint8_t m2 = m_indexed[i * 4 + 2];
116
+ uint8_t m3 = m_indexed[i * 4 + 3];
117
+
118
+ do {
119
+ d[i] += n[i * 4 + 0] * m0
120
+ + n[i * 4 + 1] * m1
121
+ + n[i * 4 + 2] * m2
122
+ + n[i * 4 + 3] * m3;
123
+ } while (++i < segend);
124
+ segend = i + 4;
125
+ } while (i < opr_sz_4);
126
+
127
+ clear_tail(d, opr_sz, simd_maxsz(desc));
128
+}
129
+
130
+void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
131
+{
132
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
133
+ intptr_t index = simd_data(desc);
134
+ uint64_t *d = vd;
135
+ int16_t *n = vn;
136
+ int16_t *m_indexed = (int16_t *)vm + index * 4;
137
+
138
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
139
+ * Process the entire segment all at once, writing back the results
140
+ * only after we've consumed all of the inputs.
141
+ */
142
+ for (i = 0; i < opr_sz_8 ; i += 2) {
143
+ uint64_t d0, d1;
144
+
145
+ d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
146
+ d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
147
+ d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
148
+ d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3];
149
+ d1 = n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
150
+ d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1];
151
+ d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2];
152
+ d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3];
153
+
154
+ d[i + 0] += d0;
155
+ d[i + 1] += d1;
156
+ }
157
+
158
+ clear_tail(d, opr_sz, simd_maxsz(desc));
159
+}
160
+
161
+void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
162
+{
163
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
164
+ intptr_t index = simd_data(desc);
165
+ uint64_t *d = vd;
166
+ uint16_t *n = vn;
167
+ uint16_t *m_indexed = (uint16_t *)vm + index * 4;
168
+
169
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
170
+ * Process the entire segment all at once, writing back the results
171
+ * only after we've consumed all of the inputs.
172
+ */
173
+ for (i = 0; i < opr_sz_8 ; i += 2) {
174
+ uint64_t d0, d1;
175
+
176
+ d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
177
+ d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1];
178
+ d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2];
179
+ d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3];
180
+ d1 = n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
181
+ d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1];
182
+ d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2];
183
+ d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3];
184
+
185
+ d[i + 0] += d0;
186
+ d[i + 1] += d1;
187
+ }
188
+
189
+ clear_tail(d, opr_sz, simd_maxsz(desc));
190
+}
191
+
192
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
193
void *vfpst, uint32_t desc)
194
{
195
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/sve.decode
198
+++ b/target/arm/sve.decode
199
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
200
# SVE integer dot product (unpredicated)
201
DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
202
203
+# SVE integer dot product (indexed)
204
+DOT_zzx 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
205
+ sz=0 ra=%reg_movprfx
206
+DOT_zzx 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
207
+ sz=1 ra=%reg_movprfx
208
+
209
# SVE floating-point complex add (predicated)
210
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
211
rn=%reg_movprfx
212
--
146
--
213
2.17.1
147
2.34.1
214
215
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
2
6
3
For aa64 advsimd, we had been passing the pre-indexed vector.
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
However, sve applies the index to each 128-bit segment, so we
8
out that real hardware permits this, with the same effect as if the
5
need to pass in the index separately.
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
6
17
7
For aa32 advsimd, the fp32 operation always has index 0, but
18
For convenience of being able to run guest code, permit
8
we failed to interpret the fp16 index correctly.
19
this UNPREDICTABLE access instead of UNDEFing it.
9
20
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20180627043328.11531-31-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
15
---
24
---
16
target/arm/translate-a64.c | 21 ++++++++++++---------
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
17
target/arm/translate.c | 32 +++++++++++++++++++++++---------
26
target/arm/tcg/translate.c | 19 +++++++++++------
18
target/arm/vec_helper.c | 10 ++++++----
27
2 files changed, 43 insertions(+), 19 deletions(-)
19
3 files changed, 41 insertions(+), 22 deletions(-)
20
28
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
22
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
31
--- a/target/arm/tcg/op_helper.c
24
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/tcg/op_helper.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
26
case 0x13: /* FCMLA #90 */
34
*/
27
case 0x15: /* FCMLA #180 */
35
int curmode = env->uncached_cpsr & CPSR_M;
28
case 0x17: /* FCMLA #270 */
36
29
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
37
- if (regno == 17) {
30
- vec_full_reg_offset(s, rn),
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
31
- vec_reg_offset(s, rm, index, size), fpst,
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
32
- is_q ? 16 : 8, vec_full_reg_size(s),
40
- goto undef;
33
- extract32(insn, 13, 2), /* rot */
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
34
- size == MO_64
42
+ /*
35
- ? gen_helper_gvec_fcmlas_idx
43
+ * Handle Hyp target regs first because some are special cases
36
- : gen_helper_gvec_fcmlah_idx);
44
+ * which don't want the usual "not accessible from tgtmode" check.
37
- tcg_temp_free_ptr(fpst);
45
+ */
38
+ {
46
+ switch (regno) {
39
+ int rot = extract32(insn, 13, 2);
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
40
+ int data = (index << 2) | rot;
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
41
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
49
+ goto undef;
42
+ vec_full_reg_offset(s, rn),
50
+ }
43
+ vec_full_reg_offset(s, rm), fpst,
51
+ break;
44
+ is_q ? 16 : 8, vec_full_reg_size(s), data,
52
+ case 13:
45
+ size == MO_64
53
+ if (curmode != ARM_CPU_MODE_MON) {
46
+ ? gen_helper_gvec_fcmlas_idx
54
+ goto undef;
47
+ : gen_helper_gvec_fcmlah_idx);
55
+ }
48
+ tcg_temp_free_ptr(fpst);
56
+ break;
49
+ }
57
+ default:
58
+ g_assert_not_reached();
59
}
50
return;
60
return;
51
}
61
}
52
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
63
}
64
}
65
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
68
- if (curmode != ARM_CPU_MODE_MON) {
69
- goto undef;
70
- }
71
- }
72
-
73
return;
74
75
undef:
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
77
78
switch (regno) {
79
case 16: /* SPSRs */
80
- env->banked_spsr[bank_number(tgtmode)] = value;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
83
+ env->spsr = value;
84
+ } else {
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
86
+ }
87
break;
88
case 17: /* ELR_Hyp */
89
env->elr_el[2] = value;
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
91
92
switch (regno) {
93
case 16: /* SPSRs */
94
- return env->banked_spsr[bank_number(tgtmode)];
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
97
+ return env->spsr;
98
+ } else {
99
+ return env->banked_spsr[bank_number(tgtmode)];
100
+ }
101
case 17: /* ELR_Hyp */
102
return env->elr_el[2];
103
case 13:
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
54
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.c
106
--- a/target/arm/tcg/translate.c
56
+++ b/target/arm/translate.c
107
+++ b/target/arm/tcg/translate.c
57
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
58
109
break;
59
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
110
case ARM_CPU_MODE_HYP:
60
{
111
/*
61
- int rd, rn, rm, rot, size, opr_sz;
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
62
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
63
+ int rd, rn, rm, opr_sz, data;
114
- * can be accessed also from Hyp mode, so forbid accesses from
64
TCGv_ptr fpst;
115
- * EL0 or EL1.
65
bool q;
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
66
117
+ * can forbid accesses from EL2 or below.
67
q = extract32(insn, 6, 1);
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
68
VFP_DREG_D(rd, insn);
119
+ * accesses from EL0 or EL1.
69
VFP_DREG_N(rn, insn);
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
70
- VFP_DREG_M(rm, insn);
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
71
if ((rd | rn) & q) {
122
+ * mode. However there is some real-world code that will do
72
return 1;
123
+ * it because at least some hardware happens to permit the
73
}
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
74
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
75
if ((insn & 0xff000f10) == 0xfe000800) {
126
+ * this (incorrect) guest code to run.
76
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
127
*/
77
- rot = extract32(insn, 20, 2);
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
78
- size = extract32(insn, 23, 1);
129
- (s->current_el < 3 && *regno != 17)) {
79
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
80
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
81
+ int rot = extract32(insn, 20, 2);
132
goto undef;
82
+ int size = extract32(insn, 23, 1);
83
+ int index;
84
+
85
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
86
return 1;
87
}
133
}
88
+ if (size == 0) {
134
break;
89
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
90
+ return 1;
91
+ }
92
+ /* For fp16, rm is just Vm, and index is M. */
93
+ rm = extract32(insn, 0, 4);
94
+ index = extract32(insn, 5, 1);
95
+ } else {
96
+ /* For fp32, rm is the usual M:Vm, and index is 0. */
97
+ VFP_DREG_M(rm, insn);
98
+ index = 0;
99
+ }
100
+ data = (index << 2) | rot;
101
+ fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
102
+ : gen_helper_gvec_fcmlah_idx);
103
} else {
104
return 1;
105
}
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
107
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
108
vfp_reg_offset(1, rn),
109
vfp_reg_offset(1, rm), fpst,
110
- opr_sz, opr_sz, rot,
111
- size ? gen_helper_gvec_fcmlas_idx
112
- : gen_helper_gvec_fcmlah_idx);
113
+ opr_sz, opr_sz, data, fn_gvec_ptr);
114
tcg_temp_free_ptr(fpst);
115
return 0;
116
}
117
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/vec_helper.c
120
+++ b/target/arm/vec_helper.c
121
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
122
float_status *fpst = vfpst;
123
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
124
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
125
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
126
uint32_t neg_real = flip ^ neg_imag;
127
uintptr_t i;
128
- float16 e1 = m[H2(flip)];
129
- float16 e3 = m[H2(1 - flip)];
130
+ float16 e1 = m[H2(2 * index + flip)];
131
+ float16 e3 = m[H2(2 * index + 1 - flip)];
132
133
/* Shift boolean to the sign bit so we can xor to negate. */
134
neg_real <<= 15;
135
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
136
float_status *fpst = vfpst;
137
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
138
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
139
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
140
uint32_t neg_real = flip ^ neg_imag;
141
uintptr_t i;
142
- float32 e1 = m[H4(flip)];
143
- float32 e3 = m[H4(1 - flip)];
144
+ float32 e1 = m[H4(2 * index + flip)];
145
+ float32 e3 = m[H4(2 * index + 1 - flip)];
146
147
/* Shift boolean to the sign bit so we can xor to negate. */
148
neg_real <<= 31;
149
--
135
--
150
2.17.1
136
2.34.1
151
152
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
We currently guard the CFG3 register read with
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
2
4
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
5
This register is present on all board types except AN524
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
and AN527; correct the condition.
7
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
6
---
13
---
7
hw/arm/fsl-imx7.c | 2 +-
14
hw/misc/mps2-scc.c | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
9
16
10
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
11
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/fsl-imx7.c
19
--- a/hw/misc/mps2-scc.c
13
+++ b/hw/arm/fsl-imx7.c
20
+++ b/hw/misc/mps2-scc.c
14
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
15
/*
22
r = s->cfg2;
16
* SRC
23
break;
17
*/
24
case A_CFG3:
18
- create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
19
+ create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
20
27
/* CFG3 reserved on AN524 */
21
/*
28
goto bad_offset;
22
* Watchdog
29
}
23
--
30
--
24
2.17.1
31
2.34.1
25
32
26
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The MPS SCC device has a lot of different flavours for the various
2
different MPS FPGA images, which look mostly similar but have
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Factor out the conditions into some functions which we can
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
give more descriptive names to.
5
Message-id: 20180627043328.11531-30-richard.henderson@linaro.org
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
7
---
14
---
8
target/arm/helper-sve.h | 4 +
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
9
target/arm/sve_helper.c | 162 +++++++++++++++++++++++++++++++++++++
16
1 file changed, 31 insertions(+), 14 deletions(-)
10
target/arm/translate-sve.c | 37 +++++++++
11
target/arm/sve.decode | 4 +
12
4 files changed, 207 insertions(+)
13
17
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
20
--- a/hw/misc/mps2-scc.c
17
+++ b/target/arm/helper-sve.h
21
+++ b/hw/misc/mps2-scc.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
23
return extract32(s->id, 4, 8);
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
22
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
23
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
+
26
DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
28
DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve_helper.c
32
+++ b/target/arm/sve_helper.c
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
34
} while (i != 0);
35
}
24
}
36
25
37
+/*
26
+/* Is CFG_REG2 present? */
38
+ * FP Complex Multiply
27
+static bool have_cfg2(MPS2SCC *s)
39
+ */
40
+
41
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 22 > 32);
42
+
43
+void HELPER(sve_fcmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
44
+{
28
+{
45
+ intptr_t j, i = simd_oprsz(desc);
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
46
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
47
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
48
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
49
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
50
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
51
+ bool flip = rot & 1;
52
+ float16 neg_imag, neg_real;
53
+ void *vd = &env->vfp.zregs[rd];
54
+ void *vn = &env->vfp.zregs[rn];
55
+ void *vm = &env->vfp.zregs[rm];
56
+ void *va = &env->vfp.zregs[ra];
57
+ uint64_t *g = vg;
58
+
59
+ neg_imag = float16_set_sign(0, (rot & 2) != 0);
60
+ neg_real = float16_set_sign(0, rot == 1 || rot == 2);
61
+
62
+ do {
63
+ uint64_t pg = g[(i - 1) >> 6];
64
+ do {
65
+ float16 e1, e2, e3, e4, nr, ni, mr, mi, d;
66
+
67
+ /* I holds the real index; J holds the imag index. */
68
+ j = i - sizeof(float16);
69
+ i -= 2 * sizeof(float16);
70
+
71
+ nr = *(float16 *)(vn + H1_2(i));
72
+ ni = *(float16 *)(vn + H1_2(j));
73
+ mr = *(float16 *)(vm + H1_2(i));
74
+ mi = *(float16 *)(vm + H1_2(j));
75
+
76
+ e2 = (flip ? ni : nr);
77
+ e1 = (flip ? mi : mr) ^ neg_real;
78
+ e4 = e2;
79
+ e3 = (flip ? mr : mi) ^ neg_imag;
80
+
81
+ if (likely((pg >> (i & 63)) & 1)) {
82
+ d = *(float16 *)(va + H1_2(i));
83
+ d = float16_muladd(e2, e1, d, 0, &env->vfp.fp_status_f16);
84
+ *(float16 *)(vd + H1_2(i)) = d;
85
+ }
86
+ if (likely((pg >> (j & 63)) & 1)) {
87
+ d = *(float16 *)(va + H1_2(j));
88
+ d = float16_muladd(e4, e3, d, 0, &env->vfp.fp_status_f16);
89
+ *(float16 *)(vd + H1_2(j)) = d;
90
+ }
91
+ } while (i & 63);
92
+ } while (i != 0);
93
+}
30
+}
94
+
31
+
95
+void HELPER(sve_fcmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
96
+{
34
+{
97
+ intptr_t j, i = simd_oprsz(desc);
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
98
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
99
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
100
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
101
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
102
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
103
+ bool flip = rot & 1;
104
+ float32 neg_imag, neg_real;
105
+ void *vd = &env->vfp.zregs[rd];
106
+ void *vn = &env->vfp.zregs[rn];
107
+ void *vm = &env->vfp.zregs[rm];
108
+ void *va = &env->vfp.zregs[ra];
109
+ uint64_t *g = vg;
110
+
111
+ neg_imag = float32_set_sign(0, (rot & 2) != 0);
112
+ neg_real = float32_set_sign(0, rot == 1 || rot == 2);
113
+
114
+ do {
115
+ uint64_t pg = g[(i - 1) >> 6];
116
+ do {
117
+ float32 e1, e2, e3, e4, nr, ni, mr, mi, d;
118
+
119
+ /* I holds the real index; J holds the imag index. */
120
+ j = i - sizeof(float32);
121
+ i -= 2 * sizeof(float32);
122
+
123
+ nr = *(float32 *)(vn + H1_2(i));
124
+ ni = *(float32 *)(vn + H1_2(j));
125
+ mr = *(float32 *)(vm + H1_2(i));
126
+ mi = *(float32 *)(vm + H1_2(j));
127
+
128
+ e2 = (flip ? ni : nr);
129
+ e1 = (flip ? mi : mr) ^ neg_real;
130
+ e4 = e2;
131
+ e3 = (flip ? mr : mi) ^ neg_imag;
132
+
133
+ if (likely((pg >> (i & 63)) & 1)) {
134
+ d = *(float32 *)(va + H1_2(i));
135
+ d = float32_muladd(e2, e1, d, 0, &env->vfp.fp_status);
136
+ *(float32 *)(vd + H1_2(i)) = d;
137
+ }
138
+ if (likely((pg >> (j & 63)) & 1)) {
139
+ d = *(float32 *)(va + H1_2(j));
140
+ d = float32_muladd(e4, e3, d, 0, &env->vfp.fp_status);
141
+ *(float32 *)(vd + H1_2(j)) = d;
142
+ }
143
+ } while (i & 63);
144
+ } while (i != 0);
145
+}
36
+}
146
+
37
+
147
+void HELPER(sve_fcmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
148
+{
40
+{
149
+ intptr_t j, i = simd_oprsz(desc);
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
150
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
151
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
152
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
153
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
154
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
155
+ bool flip = rot & 1;
156
+ float64 neg_imag, neg_real;
157
+ void *vd = &env->vfp.zregs[rd];
158
+ void *vn = &env->vfp.zregs[rn];
159
+ void *vm = &env->vfp.zregs[rm];
160
+ void *va = &env->vfp.zregs[ra];
161
+ uint64_t *g = vg;
162
+
163
+ neg_imag = float64_set_sign(0, (rot & 2) != 0);
164
+ neg_real = float64_set_sign(0, rot == 1 || rot == 2);
165
+
166
+ do {
167
+ uint64_t pg = g[(i - 1) >> 6];
168
+ do {
169
+ float64 e1, e2, e3, e4, nr, ni, mr, mi, d;
170
+
171
+ /* I holds the real index; J holds the imag index. */
172
+ j = i - sizeof(float64);
173
+ i -= 2 * sizeof(float64);
174
+
175
+ nr = *(float64 *)(vn + H1_2(i));
176
+ ni = *(float64 *)(vn + H1_2(j));
177
+ mr = *(float64 *)(vm + H1_2(i));
178
+ mi = *(float64 *)(vm + H1_2(j));
179
+
180
+ e2 = (flip ? ni : nr);
181
+ e1 = (flip ? mi : mr) ^ neg_real;
182
+ e4 = e2;
183
+ e3 = (flip ? mr : mi) ^ neg_imag;
184
+
185
+ if (likely((pg >> (i & 63)) & 1)) {
186
+ d = *(float64 *)(va + H1_2(i));
187
+ d = float64_muladd(e2, e1, d, 0, &env->vfp.fp_status);
188
+ *(float64 *)(vd + H1_2(i)) = d;
189
+ }
190
+ if (likely((pg >> (j & 63)) & 1)) {
191
+ d = *(float64 *)(va + H1_2(j));
192
+ d = float64_muladd(e4, e3, d, 0, &env->vfp.fp_status);
193
+ *(float64 *)(vd + H1_2(j)) = d;
194
+ }
195
+ } while (i & 63);
196
+ } while (i != 0);
197
+}
42
+}
198
+
43
+
199
/*
44
+/* Is CFG_REG6 present? */
200
* Load contiguous data, protected by a governing predicate.
45
+static bool have_cfg6(MPS2SCC *s)
201
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/target/arm/translate-sve.c
205
+++ b/target/arm/translate-sve.c
206
@@ -XXX,XX +XXX,XX @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
207
208
#undef DO_FMLA
209
210
+static bool trans_FCMLA_zpzzz(DisasContext *s,
211
+ arg_FCMLA_zpzzz *a, uint32_t insn)
212
+{
46
+{
213
+ static gen_helper_sve_fmla * const fns[3] = {
47
+ return scc_partno(s) == 0x524;
214
+ gen_helper_sve_fcmla_zpzzz_h,
215
+ gen_helper_sve_fcmla_zpzzz_s,
216
+ gen_helper_sve_fcmla_zpzzz_d,
217
+ };
218
+
219
+ if (a->esz == 0) {
220
+ return false;
221
+ }
222
+ if (sve_access_check(s)) {
223
+ unsigned vsz = vec_full_reg_size(s);
224
+ unsigned desc;
225
+ TCGv_i32 t_desc;
226
+ TCGv_ptr pg = tcg_temp_new_ptr();
227
+
228
+ /* We would need 7 operands to pass these arguments "properly".
229
+ * So we encode all the register numbers into the descriptor.
230
+ */
231
+ desc = deposit32(a->rd, 5, 5, a->rn);
232
+ desc = deposit32(desc, 10, 5, a->rm);
233
+ desc = deposit32(desc, 15, 5, a->ra);
234
+ desc = deposit32(desc, 20, 2, a->rot);
235
+ desc = sextract32(desc, 0, 22);
236
+ desc = simd_desc(vsz, vsz, desc);
237
+
238
+ t_desc = tcg_const_i32(desc);
239
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
240
+ fns[a->esz - 1](cpu_env, pg, t_desc);
241
+ tcg_temp_free_i32(t_desc);
242
+ tcg_temp_free_ptr(pg);
243
+ }
244
+ return true;
245
+}
48
+}
246
+
49
+
247
/*
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
248
*** SVE Floating Point Unary Operations Predicated Group
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
249
*/
52
*/
250
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
251
index XXXXXXX..XXXXXXX 100644
54
r = s->cfg1;
252
--- a/target/arm/sve.decode
55
break;
253
+++ b/target/arm/sve.decode
56
case A_CFG2:
254
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
255
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
58
- /* CFG2 reserved on other boards */
256
rn=%reg_movprfx
59
+ if (!have_cfg2(s)) {
257
60
goto bad_offset;
258
+# SVE floating-point complex multiply-add (predicated)
61
}
259
+FCMLA_zpzzz 01100100 esz:2 0 rm:5 0 rot:2 pg:3 rn:5 rd:5 \
62
r = s->cfg2;
260
+ ra=%reg_movprfx
63
break;
261
+
64
case A_CFG3:
262
### SVE FP Multiply-Add Indexed Group
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
263
66
- /* CFG3 reserved on AN524 */
264
# SVE floating-point multiply-add (indexed)
67
+ if (!have_cfg3(s)) {
68
goto bad_offset;
69
}
70
/* These are user-settable DIP switches on the board. We don't
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
72
r = s->cfg4;
73
break;
74
case A_CFG5:
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
76
- /* CFG5 reserved on other boards */
77
+ if (!have_cfg5(s)) {
78
goto bad_offset;
79
}
80
r = s->cfg5;
81
break;
82
case A_CFG6:
83
- if (scc_partno(s) != 0x524) {
84
- /* CFG6 reserved on other boards */
85
+ if (!have_cfg6(s)) {
86
goto bad_offset;
87
}
88
r = s->cfg6;
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
90
}
91
break;
92
case A_CFG2:
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
94
- /* CFG2 reserved on other boards */
95
+ if (!have_cfg2(s)) {
96
goto bad_offset;
97
}
98
/* AN524: QSPI Select signal */
99
s->cfg2 = value;
100
break;
101
case A_CFG5:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
103
- /* CFG5 reserved on other boards */
104
+ if (!have_cfg5(s)) {
105
goto bad_offset;
106
}
107
/* AN524: ACLK frequency in Hz */
108
s->cfg5 = value;
109
break;
110
case A_CFG6:
111
- if (scc_partno(s) != 0x524) {
112
- /* CFG6 reserved on other boards */
113
+ if (!have_cfg6(s)) {
114
goto bad_offset;
115
}
116
/* AN524: Clock divider for BRAM */
265
--
117
--
266
2.17.1
118
2.34.1
267
119
268
120
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
2
minor differences in the behaviour of the CFG registers depending on
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
the image. In many cases we don't really care about the functionality
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
controlled by these registers and a reads-as-written or similar
5
Message-id: 20180627043328.11531-26-richard.henderson@linaro.org
5
behaviour is sufficient for the moment.
6
7
For the AN536 the required behaviour is:
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
34
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
7
---
39
---
8
target/arm/helper-sve.h | 14 +++++++
40
include/hw/misc/mps2-scc.h | 1 +
9
target/arm/sve_helper.c | 8 ++++
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
10
target/arm/translate-sve.c | 77 ++++++++++++++++++++++++++++++++++++++
42
2 files changed, 92 insertions(+), 10 deletions(-)
11
target/arm/sve.decode | 9 +++++
43
12
4 files changed, 108 insertions(+)
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
46
--- a/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/helper-sve.h
47
+++ b/include/hw/misc/mps2-scc.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvtzu_sd, TCG_CALL_NO_RWG,
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
DEF_HELPER_FLAGS_5(sve_fcvtzu_dd, TCG_CALL_NO_RWG,
49
uint32_t cfg4;
20
void, ptr, ptr, ptr, ptr, i32)
50
uint32_t cfg5;
21
51
uint32_t cfg6;
22
+DEF_HELPER_FLAGS_5(sve_frint_h, TCG_CALL_NO_RWG,
52
+ uint32_t cfg7;
23
+ void, ptr, ptr, ptr, ptr, i32)
53
uint32_t cfgdata_rtn;
24
+DEF_HELPER_FLAGS_5(sve_frint_s, TCG_CALL_NO_RWG,
54
uint32_t cfgdata_out;
25
+ void, ptr, ptr, ptr, ptr, i32)
55
uint32_t cfgctrl;
26
+DEF_HELPER_FLAGS_5(sve_frint_d, TCG_CALL_NO_RWG,
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_5(sve_frintx_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_frintx_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_frintx_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
37
void, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
58
--- a/hw/misc/mps2-scc.c
42
+++ b/target/arm/sve_helper.c
59
+++ b/hw/misc/mps2-scc.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_fcvtzu_sd, uint64_t, , vfp_float32_to_uint64_rtz)
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
44
DO_ZPZ_FP(sve_fcvtzu_ds, uint64_t, , helper_vfp_touizd)
61
REG32(CFG4, 0x10)
45
DO_ZPZ_FP(sve_fcvtzu_dd, uint64_t, , vfp_float64_to_uint64_rtz)
62
REG32(CFG5, 0x14)
46
63
REG32(CFG6, 0x18)
47
+DO_ZPZ_FP(sve_frint_h, uint16_t, H1_2, helper_advsimd_rinth)
64
+REG32(CFG7, 0x1c)
48
+DO_ZPZ_FP(sve_frint_s, uint32_t, H1_4, helper_rints)
65
REG32(CFGDATA_RTN, 0xa0)
49
+DO_ZPZ_FP(sve_frint_d, uint64_t, , helper_rintd)
66
REG32(CFGDATA_OUT, 0xa4)
50
+
67
REG32(CFGCTRL, 0xa8)
51
+DO_ZPZ_FP(sve_frintx_h, uint16_t, H1_2, float16_round_to_int)
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
52
+DO_ZPZ_FP(sve_frintx_s, uint32_t, H1_4, float32_round_to_int)
69
/* Is CFG_REG2 present? */
53
+DO_ZPZ_FP(sve_frintx_d, uint64_t, , float64_round_to_int)
70
static bool have_cfg2(MPS2SCC *s)
54
+
71
{
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
74
+ scc_partno(s) == 0x536;
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
75
}
59
index XXXXXXX..XXXXXXX 100644
76
60
--- a/target/arm/translate-sve.c
77
/* Is CFG_REG3 present? */
61
+++ b/target/arm/translate-sve.c
78
static bool have_cfg3(MPS2SCC *s)
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
79
{
63
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
64
}
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
65
82
+ scc_partno(s) != 0x536;
66
+static gen_helper_gvec_3_ptr * const frint_fns[3] = {
83
}
67
+ gen_helper_sve_frint_h,
84
68
+ gen_helper_sve_frint_s,
85
/* Is CFG_REG5 present? */
69
+ gen_helper_sve_frint_d
86
static bool have_cfg5(MPS2SCC *s)
87
{
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
90
+ scc_partno(s) == 0x536;
91
}
92
93
/* Is CFG_REG6 present? */
94
static bool have_cfg6(MPS2SCC *s)
95
{
96
- return scc_partno(s) == 0x524;
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
98
+}
99
+
100
+/* Is CFG_REG7 present? */
101
+static bool have_cfg7(MPS2SCC *s)
102
+{
103
+ return scc_partno(s) == 0x536;
104
+}
105
+
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
107
+static bool cfg0_is_remap(MPS2SCC *s)
108
+{
109
+ return scc_partno(s) != 0x536;
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
117
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
120
if (!have_cfg3(s)) {
121
goto bad_offset;
122
}
123
- /* These are user-settable DIP switches on the board. We don't
124
+ /*
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
233
+ }
70
+};
234
+};
71
+
235
+
72
+static bool trans_FRINTI(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
236
static const VMStateDescription mps2_scc_vmstate = {
73
+{
237
.name = "mps2-scc",
74
+ if (a->esz == 0) {
238
.version_id = 3,
75
+ return false;
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
76
+ }
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
77
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16,
241
0, vmstate_info_uint32, uint32_t),
78
+ frint_fns[a->esz - 1]);
242
VMSTATE_END_OF_LIST()
79
+}
243
+ },
80
+
244
+ .subsections = (const VMStateDescription * const []) {
81
+static bool trans_FRINTX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
245
+ &vmstate_cfg7,
82
+{
246
+ NULL
83
+ static gen_helper_gvec_3_ptr * const fns[3] = {
247
}
84
+ gen_helper_sve_frintx_h,
248
};
85
+ gen_helper_sve_frintx_s,
249
86
+ gen_helper_sve_frintx_d
87
+ };
88
+ if (a->esz == 0) {
89
+ return false;
90
+ }
91
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
92
+}
93
+
94
+static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, int mode)
95
+{
96
+ if (a->esz == 0) {
97
+ return false;
98
+ }
99
+ if (sve_access_check(s)) {
100
+ unsigned vsz = vec_full_reg_size(s);
101
+ TCGv_i32 tmode = tcg_const_i32(mode);
102
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
103
+
104
+ gen_helper_set_rmode(tmode, tmode, status);
105
+
106
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
107
+ vec_full_reg_offset(s, a->rn),
108
+ pred_full_reg_offset(s, a->pg),
109
+ status, vsz, vsz, 0, frint_fns[a->esz - 1]);
110
+
111
+ gen_helper_set_rmode(tmode, tmode, status);
112
+ tcg_temp_free_i32(tmode);
113
+ tcg_temp_free_ptr(status);
114
+ }
115
+ return true;
116
+}
117
+
118
+static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
119
+{
120
+ return do_frint_mode(s, a, float_round_nearest_even);
121
+}
122
+
123
+static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
124
+{
125
+ return do_frint_mode(s, a, float_round_up);
126
+}
127
+
128
+static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
129
+{
130
+ return do_frint_mode(s, a, float_round_down);
131
+}
132
+
133
+static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
134
+{
135
+ return do_frint_mode(s, a, float_round_to_zero);
136
+}
137
+
138
+static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
139
+{
140
+ return do_frint_mode(s, a, float_round_ties_away);
141
+}
142
+
143
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
144
{
145
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
146
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/sve.decode
149
+++ b/target/arm/sve.decode
150
@@ -XXX,XX +XXX,XX @@ FCVTZU_sd 01100101 11 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
151
FCVTZS_dd 01100101 11 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
152
FCVTZU_dd 01100101 11 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
153
154
+# SVE floating-point round to integral value
155
+FRINTN 01100101 .. 000 000 101 ... ..... ..... @rd_pg_rn
156
+FRINTP 01100101 .. 000 001 101 ... ..... ..... @rd_pg_rn
157
+FRINTM 01100101 .. 000 010 101 ... ..... ..... @rd_pg_rn
158
+FRINTZ 01100101 .. 000 011 101 ... ..... ..... @rd_pg_rn
159
+FRINTA 01100101 .. 000 100 101 ... ..... ..... @rd_pg_rn
160
+FRINTX 01100101 .. 000 110 101 ... ..... ..... @rd_pg_rn
161
+FRINTI 01100101 .. 000 111 101 ... ..... ..... @rd_pg_rn
162
+
163
# SVE integer convert to floating-point
164
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
165
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
166
--
250
--
167
2.17.1
251
2.34.1
168
252
169
253
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
2
the existing FPGA images we already model, this board uses a Cortex-R
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
family CPU, and it does not use any equivalent to the M-profile
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
Message-id: 20180627043328.11531-19-richard.henderson@linaro.org
5
It's therefore more convenient for us to model it as a completely
6
separate C file.
7
8
This commit adds the basic skeleton of the board model, and the
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
15
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
7
---
19
---
8
target/arm/helper.h | 14 +++++++++++
20
MAINTAINERS | 3 +-
9
target/arm/translate-sve.c | 50 ++++++++++++++++++++++++++++++++++++++
21
configs/devices/arm-softmmu/default.mak | 1 +
10
target/arm/vec_helper.c | 48 ++++++++++++++++++++++++++++++++++++
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
11
target/arm/sve.decode | 19 +++++++++++++++
23
hw/arm/Kconfig | 5 +
12
4 files changed, 131 insertions(+)
24
hw/arm/meson.build | 1 +
13
25
5 files changed, 248 insertions(+), 1 deletion(-)
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
create mode 100644 hw/arm/mps3r.c
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
30
--- a/MAINTAINERS
17
+++ b/target/arm/helper.h
31
+++ b/MAINTAINERS
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
19
DEF_HELPER_FLAGS_5(gvec_ftsmul_d, TCG_CALL_NO_RWG,
33
F: hw/pci-host/designware.c
20
void, ptr, ptr, ptr, ptr, i32)
34
F: include/hw/pci-host/designware.h
21
35
22
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_h, TCG_CALL_NO_RWG,
36
-MPS2
23
+ void, ptr, ptr, ptr, ptr, i32)
37
+MPS2 / MPS3
24
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_s, TCG_CALL_NO_RWG,
38
M: Peter Maydell <peter.maydell@linaro.org>
25
+ void, ptr, ptr, ptr, ptr, i32)
39
L: qemu-arm@nongnu.org
26
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_d, TCG_CALL_NO_RWG,
40
S: Maintained
27
+ void, ptr, ptr, ptr, ptr, i32)
41
F: hw/arm/mps2.c
28
+
42
F: hw/arm/mps2-tz.c
29
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_h, TCG_CALL_NO_RWG,
43
+F: hw/arm/mps3r.c
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
44
F: hw/misc/mps2-*.c
31
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
45
F: include/hw/misc/mps2-*.h
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
46
F: hw/arm/armsse.c
33
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
#ifdef TARGET_AARCH64
37
#include "helper-a64.h"
38
#include "helper-sve.h"
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
40
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-sve.c
49
--- a/configs/devices/arm-softmmu/default.mak
42
+++ b/target/arm/translate-sve.c
50
+++ b/configs/devices/arm-softmmu/default.mak
43
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
44
52
# CONFIG_INTEGRATOR=n
45
#undef DO_ZZI
53
# CONFIG_FSL_IMX31=n
46
54
# CONFIG_MUSICPAL=n
55
+# CONFIG_MPS3R=n
56
# CONFIG_MUSCA=n
57
# CONFIG_CHEETAH=n
58
# CONFIG_SX1=n
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/hw/arm/mps3r.c
64
@@ -XXX,XX +XXX,XX @@
47
+/*
65
+/*
48
+ *** SVE Floating Point Multiply-Add Indexed Group
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
68
+ *
69
+ * Copyright (c) 2017 Linaro Limited
70
+ * Written by Peter Maydell
71
+ *
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
49
+ */
75
+ */
50
+
76
+
51
+static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a, uint32_t insn)
77
+/*
52
+{
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
53
+ static gen_helper_gvec_4_ptr * const fns[3] = {
79
+ * which use the Cortex-R CPUs. We model these separately from the
54
+ gen_helper_gvec_fmla_idx_h,
80
+ * M-profile images, because on M-profile the FPGA image is based on
55
+ gen_helper_gvec_fmla_idx_s,
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
56
+ gen_helper_gvec_fmla_idx_d,
82
+ * the R-profile FPGA images don't have that abstraction layer.
83
+ *
84
+ * We model the following FPGA images here:
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
57
+ };
276
+ };
58
+
277
+
59
+ if (sve_access_check(s)) {
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
60
+ unsigned vsz = vec_full_reg_size(s);
279
+ mc->default_cpus = 2;
61
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
280
+ mc->min_cpus = mc->default_cpus;
62
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
281
+ mc->max_cpus = mc->default_cpus;
63
+ vec_full_reg_offset(s, a->rn),
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
64
+ vec_full_reg_offset(s, a->rm),
283
+ mc->valid_cpu_types = valid_cpu_types;
65
+ vec_full_reg_offset(s, a->ra),
284
+ mmc->raminfo = an536_raminfo;
66
+ status, vsz, vsz, (a->index << 1) | a->sub,
285
+ mps3r_set_default_ram_info(mmc);
67
+ fns[a->esz - 1]);
286
+}
68
+ tcg_temp_free_ptr(status);
287
+
69
+ }
288
+static const TypeInfo mps3r_machine_types[] = {
70
+ return true;
289
+ {
71
+}
290
+ .name = TYPE_MPS3R_MACHINE,
72
+
291
+ .parent = TYPE_MACHINE,
73
+/*
292
+ .abstract = true,
74
+ *** SVE Floating Point Multiply Indexed Group
293
+ .instance_size = sizeof(MPS3RMachineState),
75
+ */
294
+ .class_size = sizeof(MPS3RMachineClass),
76
+
295
+ .class_init = mps3r_class_init,
77
+static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
296
+ }, {
78
+{
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
79
+ static gen_helper_gvec_3_ptr * const fns[3] = {
298
+ .parent = TYPE_MPS3R_MACHINE,
80
+ gen_helper_gvec_fmul_idx_h,
299
+ .class_init = mps3r_an536_class_init,
81
+ gen_helper_gvec_fmul_idx_s,
300
+ },
82
+ gen_helper_gvec_fmul_idx_d,
301
+};
83
+ };
302
+
84
+
303
+DEFINE_TYPES(mps3r_machine_types);
85
+ if (sve_access_check(s)) {
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
86
+ unsigned vsz = vec_full_reg_size(s);
87
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
88
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
89
+ vec_full_reg_offset(s, a->rn),
90
+ vec_full_reg_offset(s, a->rm),
91
+ status, vsz, vsz, a->index, fns[a->esz - 1]);
92
+ tcg_temp_free_ptr(status);
93
+ }
94
+ return true;
95
+}
96
+
97
/*
98
*** SVE Floating Point Accumulating Reduction Group
99
*/
100
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
101
index XXXXXXX..XXXXXXX 100644
305
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/vec_helper.c
306
--- a/hw/arm/Kconfig
103
+++ b/target/arm/vec_helper.c
307
+++ b/hw/arm/Kconfig
104
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
105
309
select PFLASH_CFI01
106
#endif
310
select SMC91C111
107
#undef DO_3OP
311
108
+
312
+config MPS3R
109
+/* For the indexed ops, SVE applies the index per 128-bit vector segment.
313
+ bool
110
+ * For AdvSIMD, there is of course only one such vector segment.
314
+ default y
111
+ */
315
+ depends on TCG && ARM
112
+
316
+
113
+#define DO_MUL_IDX(NAME, TYPE, H) \
317
config MUSCA
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
318
bool
115
+{ \
319
default y
116
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
117
+ intptr_t idx = simd_data(desc); \
118
+ TYPE *d = vd, *n = vn, *m = vm; \
119
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
120
+ TYPE mm = m[H(i + idx)]; \
121
+ for (j = 0; j < segment; j++) { \
122
+ d[i + j] = TYPE##_mul(n[i + j], mm, stat); \
123
+ } \
124
+ } \
125
+}
126
+
127
+DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
128
+DO_MUL_IDX(gvec_fmul_idx_s, float32, H4)
129
+DO_MUL_IDX(gvec_fmul_idx_d, float64, )
130
+
131
+#undef DO_MUL_IDX
132
+
133
+#define DO_FMLA_IDX(NAME, TYPE, H) \
134
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \
135
+ void *stat, uint32_t desc) \
136
+{ \
137
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
138
+ TYPE op1_neg = extract32(desc, SIMD_DATA_SHIFT, 1); \
139
+ intptr_t idx = desc >> (SIMD_DATA_SHIFT + 1); \
140
+ TYPE *d = vd, *n = vn, *m = vm, *a = va; \
141
+ op1_neg <<= (8 * sizeof(TYPE) - 1); \
142
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
143
+ TYPE mm = m[H(i + idx)]; \
144
+ for (j = 0; j < segment; j++) { \
145
+ d[i + j] = TYPE##_muladd(n[i + j] ^ op1_neg, \
146
+ mm, a[i + j], 0, stat); \
147
+ } \
148
+ } \
149
+}
150
+
151
+DO_FMLA_IDX(gvec_fmla_idx_h, float16, H2)
152
+DO_FMLA_IDX(gvec_fmla_idx_s, float32, H4)
153
+DO_FMLA_IDX(gvec_fmla_idx_d, float64, )
154
+
155
+#undef DO_FMLA_IDX
156
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
157
index XXXXXXX..XXXXXXX 100644
321
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/sve.decode
322
--- a/hw/arm/meson.build
159
+++ b/target/arm/sve.decode
323
+++ b/hw/arm/meson.build
160
@@ -XXX,XX +XXX,XX @@
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
161
%imm9_16_10 16:s6 10:3
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
162
%size_23 23:2
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
163
%dtype_23_13 23:2 13:2
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
164
+%index3_22_19 22:1 19:2
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
165
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
166
# A combination of tsz:imm3 -- extract esize.
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
167
%tszimm_esz 22:2 5:5 !function=tszimm_esz
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
168
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
169
# SVE integer multiply immediate (unpredicated)
170
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
171
172
+### SVE FP Multiply-Add Indexed Group
173
+
174
+# SVE floating-point multiply-add (indexed)
175
+FMLA_zzxz 01100100 0.1 .. rm:3 00000 sub:1 rn:5 rd:5 \
176
+ ra=%reg_movprfx index=%index3_22_19 esz=1
177
+FMLA_zzxz 01100100 101 index:2 rm:3 00000 sub:1 rn:5 rd:5 \
178
+ ra=%reg_movprfx esz=2
179
+FMLA_zzxz 01100100 111 index:1 rm:4 00000 sub:1 rn:5 rd:5 \
180
+ ra=%reg_movprfx esz=3
181
+
182
+### SVE FP Multiply Indexed Group
183
+
184
+# SVE floating-point multiply (indexed)
185
+FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
186
+ index=%index3_22_19 esz=1
187
+FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
188
+FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
189
+
190
### SVE FP Accumulating Reduction Group
191
192
# SVE floating-point serial reduction (predicated)
193
--
332
--
194
2.17.1
333
2.34.1
195
334
196
335
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
the mps3-an536 board.
2
3
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-sve.h | 5 +++
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/sve_helper.c | 41 +++++++++++++++++++++++++
8
1 file changed, 177 insertions(+), 3 deletions(-)
10
target/arm/translate-sve.c | 62 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 5 +++
12
4 files changed, 113 insertions(+)
13
9
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
12
--- a/hw/arm/mps3r.c
17
+++ b/target/arm/helper-sve.h
13
+++ b/hw/arm/mps3r.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
14
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
15
#include "qemu/osdep.h"
20
DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
16
#include "qemu/units.h"
21
17
#include "qapi/error.h"
22
+DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
+#include "qapi/qmp/qlist.h"
23
+DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
#include "exec/address-spaces.h"
24
+DEF_HELPER_FLAGS_4(sve_movz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
#include "cpu.h"
25
+DEF_HELPER_FLAGS_4(sve_movz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
#include "hw/boards.h"
26
+
22
+#include "hw/qdev-properties.h"
27
DEF_HELPER_FLAGS_4(sve_asr_zpzi_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
#include "hw/arm/boot.h"
28
DEF_HELPER_FLAGS_4(sve_asr_zpzi_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+#include "hw/arm/bsa.h"
29
DEF_HELPER_FLAGS_4(sve_asr_zpzi_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+#include "hw/intc/arm_gicv3.h"
30
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
26
31
index XXXXXXX..XXXXXXX 100644
27
/* Define the layout of RAM and ROM in a board */
32
--- a/target/arm/sve_helper.c
28
typedef struct RAMInfo {
33
+++ b/target/arm/sve_helper.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
34
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
30
#define IS_ROM 2
35
}
31
32
#define MPS3R_RAM_MAX 9
33
+#define MPS3R_CPU_MAX 2
34
+
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
36
}
61
}
37
62
38
+/* Copy Zn into Zd, and store zero into inactive elements. */
63
+/*
39
+void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
40
+{
78
+{
41
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
79
+ /*
42
+ uint64_t *d = vd, *n = vn;
80
+ * Power the secondary CPU off. This means we don't need to write any
43
+ uint8_t *pg = vg;
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
44
+ for (i = 0; i < opr_sz; i += 1) {
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
45
+ d[i] = n[i] & expand_pred_b(pg[H1(i)]);
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
85
+ */
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
90
+ }
46
+ }
91
+ }
47
+}
92
+}
48
+
93
+
49
+void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
95
+ const struct arm_boot_info *info)
50
+{
96
+{
51
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
97
+ /* We don't need to do anything here because the CPU will be off */
52
+ uint64_t *d = vd, *n = vn;
98
+}
53
+ uint8_t *pg = vg;
99
+
54
+ for (i = 0; i < opr_sz; i += 1) {
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
55
+ d[i] = n[i] & expand_pred_h(pg[H1(i)]);
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
56
+ }
161
+ }
57
+}
162
+}
58
+
163
+
59
+void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
164
static void mps3r_common_init(MachineState *machine)
60
+{
165
{
61
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
62
+ uint64_t *d = vd, *n = vn;
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
63
+ uint8_t *pg = vg;
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
64
+ for (i = 0; i < opr_sz; i += 1) {
169
memory_region_add_subregion(sysmem, ri->base, mr);
65
+ d[i] = n[i] & expand_pred_s(pg[H1(i)]);
170
}
171
+
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
177
+
178
+ /*
179
+ * Each CPU has some private RAM/peripherals, so create the container
180
+ * which will house those, with the whole-machine system memory being
181
+ * used where there's no CPU-specific device. Note that we need the
182
+ * sysmem_alias aliases because we can't put one MR (the original
183
+ * 'sysmem') into more than one other MR.
184
+ */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
186
+ sysmem_name, UINT64_MAX);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
66
+ }
205
+ }
67
+}
206
+
68
+
207
+ create_gic(mms, sysmem);
69
+void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, uint32_t desc)
208
+
70
+{
209
+ mms->bootinfo.ram_size = machine->ram_size;
71
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
210
+ mms->bootinfo.board_id = -1;
72
+ uint64_t *d = vd, *n = vn;
211
+ mms->bootinfo.loader_start = mmc->loader_start;
73
+ uint8_t *pg = vg;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
74
+ for (i = 0; i < opr_sz; i += 1) {
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
75
+ d[i] = n[1] & -(uint64_t)(pg[H1(i)] & 1);
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
76
+ }
77
+}
78
+
79
/* Three-operand expander, immediate operand, controlled by a predicate.
80
*/
81
#define DO_ZPZI(NAME, TYPE, H, OP) \
82
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/translate-sve.c
85
+++ b/target/arm/translate-sve.c
86
@@ -XXX,XX +XXX,XX @@ static bool do_clr_zp(DisasContext *s, int rd, int pg, int esz)
87
return true;
88
}
215
}
89
216
90
+/* Copy Zn into Zd, storing zeros into inactive elements. */
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
91
+static void do_movz_zpz(DisasContext *s, int rd, int rn, int pg, int esz)
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
92
+{
219
/* Found the entry for "system memory" */
93
+ static gen_helper_gvec_3 * const fns[4] = {
220
mc->default_ram_size = p->size;
94
+ gen_helper_sve_movz_b, gen_helper_sve_movz_h,
221
mc->default_ram_id = p->name;
95
+ gen_helper_sve_movz_s, gen_helper_sve_movz_d,
222
+ mmc->loader_start = p->base;
96
+ };
223
return;
97
+ unsigned vsz = vec_full_reg_size(s);
224
}
98
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
225
}
99
+ vec_full_reg_offset(s, rn),
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
100
+ pred_full_reg_offset(s, pg),
227
};
101
+ vsz, vsz, 0, fns[esz]);
228
102
+}
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
103
+
230
- mc->default_cpus = 2;
104
static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
231
- mc->min_cpus = mc->default_cpus;
105
gen_helper_gvec_3 *fn)
232
- mc->max_cpus = mc->default_cpus;
106
{
233
+ /*
107
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
234
+ * In the real FPGA image there are always two cores, but the standard
108
return true;
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
109
}
236
+ * that the second core is held in reset and halted. Many images built for
110
237
+ * the board do not expect the second core to run at startup (especially
111
+/* Load and broadcast element. */
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
112
+static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
113
+{
240
+ *
114
+ if (!sve_access_check(s)) {
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
115
+ return true;
242
+ * with the default being -smp 1. This seems a more intuitive UI for
116
+ }
243
+ * QEMU users than, for instance, having a machine property to allow
117
+
244
+ * the user to set the initial value of the SYSCON 0x000 register.
118
+ unsigned vsz = vec_full_reg_size(s);
245
+ */
119
+ unsigned psz = pred_full_reg_size(s);
246
+ mc->default_cpus = 1;
120
+ unsigned esz = dtype_esz[a->dtype];
247
+ mc->min_cpus = 1;
121
+ TCGLabel *over = gen_new_label();
248
+ mc->max_cpus = 2;
122
+ TCGv_i64 temp;
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
123
+
250
mc->valid_cpu_types = valid_cpu_types;
124
+ /* If the guarding predicate has no bits set, no load occurs. */
251
mmc->raminfo = an536_raminfo;
125
+ if (psz <= 8) {
126
+ /* Reduce the pred_esz_masks value simply to reduce the
127
+ * size of the code generated here.
128
+ */
129
+ uint64_t psz_mask = MAKE_64BIT_MASK(0, psz * 8);
130
+ temp = tcg_temp_new_i64();
131
+ tcg_gen_ld_i64(temp, cpu_env, pred_full_reg_offset(s, a->pg));
132
+ tcg_gen_andi_i64(temp, temp, pred_esz_masks[esz] & psz_mask);
133
+ tcg_gen_brcondi_i64(TCG_COND_EQ, temp, 0, over);
134
+ tcg_temp_free_i64(temp);
135
+ } else {
136
+ TCGv_i32 t32 = tcg_temp_new_i32();
137
+ find_last_active(s, t32, esz, a->pg);
138
+ tcg_gen_brcondi_i32(TCG_COND_LT, t32, 0, over);
139
+ tcg_temp_free_i32(t32);
140
+ }
141
+
142
+ /* Load the data. */
143
+ temp = tcg_temp_new_i64();
144
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
145
+ tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
146
+ s->be_data | dtype_mop[a->dtype]);
147
+
148
+ /* Broadcast to *all* elements. */
149
+ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
150
+ vsz, vsz, temp);
151
+ tcg_temp_free_i64(temp);
152
+
153
+ /* Zero the inactive elements. */
154
+ gen_set_label(over);
155
+ do_movz_zpz(s, a->rd, a->rd, a->pg, esz);
156
+ return true;
157
+}
158
+
159
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
160
int msz, int esz, int nreg)
161
{
162
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
163
index XXXXXXX..XXXXXXX 100644
164
--- a/target/arm/sve.decode
165
+++ b/target/arm/sve.decode
166
@@ -XXX,XX +XXX,XX @@
167
%imm8_16_10 16:5 10:3
168
%imm9_16_10 16:s6 10:3
169
%size_23 23:2
170
+%dtype_23_13 23:2 13:2
171
172
# A combination of tsz:imm3 -- extract esize.
173
%tszimm_esz 22:2 5:5 !function=tszimm_esz
174
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
175
# SVE load vector register
176
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
177
178
+# SVE load and broadcast element
179
+LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
180
+ &rpri_load dtype=%dtype_23_13 nreg=0
181
+
182
### SVE Memory Contiguous Load Group
183
184
# SVE contiguous load (scalar plus scalar)
185
--
252
--
186
2.17.1
253
2.34.1
187
188
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
This board has a lot of UARTs: there is one UART per CPU in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Connect and wire them all up; this involves some OR gates where
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
multiple overflow interrupts are wired into one GIC input.
5
Message-id: 20180627043328.11531-29-richard.henderson@linaro.org
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
7
---
13
---
8
target/arm/helper-sve.h | 7 +++
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 100 +++++++++++++++++++++++++++++++++++++
15
1 file changed, 94 insertions(+)
10
target/arm/translate-sve.c | 24 +++++++++
11
target/arm/sve.decode | 4 ++
12
4 files changed, 135 insertions(+)
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
19
--- a/hw/arm/mps3r.c
17
+++ b/target/arm/helper-sve.h
20
+++ b/hw/arm/mps3r.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
22
#include "qapi/qmp/qlist.h"
20
void, ptr, ptr, ptr, ptr, ptr, i32)
23
#include "exec/address-spaces.h"
21
24
#include "cpu.h"
22
+DEF_HELPER_FLAGS_6(sve_fcadd_h, TCG_CALL_NO_RWG,
25
+#include "sysemu/sysemu.h"
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
#include "hw/boards.h"
24
+DEF_HELPER_FLAGS_6(sve_fcadd_s, TCG_CALL_NO_RWG,
27
+#include "hw/or-irq.h"
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
#include "hw/qdev-properties.h"
26
+DEF_HELPER_FLAGS_6(sve_fcadd_d, TCG_CALL_NO_RWG,
29
#include "hw/arm/boot.h"
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
28
+
64
+
29
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
65
static const RAMInfo an536_raminfo[] = {
30
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
66
{
31
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
67
.name = "ATCM",
32
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/sve_helper.c
35
+++ b/target/arm/sve_helper.c
36
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
37
}
69
}
38
}
70
}
39
71
40
+/*
72
+/*
41
+ * FP Complex Add
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
42
+ */
75
+ */
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
80
+{
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
82
+ SysBusDevice *sbd;
43
+
83
+
44
+void HELPER(sve_fcadd_h)(void *vd, void *vn, void *vm, void *vg,
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
45
+ void *vs, uint32_t desc)
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
46
+{
86
+ TYPE_CMSDK_APB_UART);
47
+ intptr_t j, i = simd_oprsz(desc);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
48
+ uint64_t *g = vg;
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
49
+ float16 neg_imag = float16_set_sign(0, simd_data(desc));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
50
+ float16 neg_real = float16_chs(neg_imag);
90
+ sysbus_realize(sbd, &error_fatal);
51
+
91
+ memory_region_add_subregion(mem, baseaddr,
52
+ do {
92
+ sysbus_mmio_get_region(sbd, 0));
53
+ uint64_t pg = g[(i - 1) >> 6];
93
+ sysbus_connect_irq(sbd, 0, txirq);
54
+ do {
94
+ sysbus_connect_irq(sbd, 1, rxirq);
55
+ float16 e0, e1, e2, e3;
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
56
+
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
57
+ /* I holds the real index; J holds the imag index. */
97
+ sysbus_connect_irq(sbd, 4, combirq);
58
+ j = i - sizeof(float16);
59
+ i -= 2 * sizeof(float16);
60
+
61
+ e0 = *(float16 *)(vn + H1_2(i));
62
+ e1 = *(float16 *)(vm + H1_2(j)) ^ neg_real;
63
+ e2 = *(float16 *)(vn + H1_2(j));
64
+ e3 = *(float16 *)(vm + H1_2(i)) ^ neg_imag;
65
+
66
+ if (likely((pg >> (i & 63)) & 1)) {
67
+ *(float16 *)(vd + H1_2(i)) = float16_add(e0, e1, vs);
68
+ }
69
+ if (likely((pg >> (j & 63)) & 1)) {
70
+ *(float16 *)(vd + H1_2(j)) = float16_add(e2, e3, vs);
71
+ }
72
+ } while (i & 63);
73
+ } while (i != 0);
74
+}
98
+}
75
+
99
+
76
+void HELPER(sve_fcadd_s)(void *vd, void *vn, void *vm, void *vg,
100
static void mps3r_common_init(MachineState *machine)
77
+ void *vs, uint32_t desc)
101
{
78
+{
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
79
+ intptr_t j, i = simd_oprsz(desc);
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
80
+ uint64_t *g = vg;
104
MemoryRegion *sysmem = get_system_memory();
81
+ float32 neg_imag = float32_set_sign(0, simd_data(desc));
105
+ DeviceState *gicdev;
82
+ float32 neg_real = float32_chs(neg_imag);
106
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
110
}
111
112
create_gic(mms, sysmem);
113
+ gicdev = DEVICE(&mms->gic);
83
+
114
+
84
+ do {
115
+ /*
85
+ uint64_t pg = g[(i - 1) >> 6];
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
86
+ do {
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
87
+ float32 e0, e1, e2, e3;
118
+ */
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
88
+
123
+
89
+ /* I holds the real index; J holds the imag index. */
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
90
+ j = i - sizeof(float32);
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
91
+ i -= 2 * sizeof(float32);
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
92
+
132
+
93
+ e0 = *(float32 *)(vn + H1_2(i));
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
94
+ e1 = *(float32 *)(vm + H1_2(j)) ^ neg_real;
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
95
+ e2 = *(float32 *)(vn + H1_2(j));
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
96
+ e3 = *(float32 *)(vm + H1_2(i)) ^ neg_imag;
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
97
+
151
+
98
+ if (likely((pg >> (i & 63)) & 1)) {
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
99
+ *(float32 *)(vd + H1_2(i)) = float32_add(e0, e1, vs);
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
100
+ }
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
101
+ if (likely((pg >> (j & 63)) & 1)) {
102
+ *(float32 *)(vd + H1_2(j)) = float32_add(e2, e3, vs);
103
+ }
104
+ } while (i & 63);
105
+ } while (i != 0);
106
+}
107
+
155
+
108
+void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
109
+ void *vs, uint32_t desc)
157
+ qdev_get_gpio_in(gicdev, txirq),
110
+{
158
+ qdev_get_gpio_in(gicdev, rxirq),
111
+ intptr_t j, i = simd_oprsz(desc);
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
112
+ uint64_t *g = vg;
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
113
+ float64 neg_imag = float64_set_sign(0, simd_data(desc));
161
+ qdev_get_gpio_in(gicdev, combirq));
114
+ float64 neg_real = float64_chs(neg_imag);
115
+
116
+ do {
117
+ uint64_t pg = g[(i - 1) >> 6];
118
+ do {
119
+ float64 e0, e1, e2, e3;
120
+
121
+ /* I holds the real index; J holds the imag index. */
122
+ j = i - sizeof(float64);
123
+ i -= 2 * sizeof(float64);
124
+
125
+ e0 = *(float64 *)(vn + H1_2(i));
126
+ e1 = *(float64 *)(vm + H1_2(j)) ^ neg_real;
127
+ e2 = *(float64 *)(vn + H1_2(j));
128
+ e3 = *(float64 *)(vm + H1_2(i)) ^ neg_imag;
129
+
130
+ if (likely((pg >> (i & 63)) & 1)) {
131
+ *(float64 *)(vd + H1_2(i)) = float64_add(e0, e1, vs);
132
+ }
133
+ if (likely((pg >> (j & 63)) & 1)) {
134
+ *(float64 *)(vd + H1_2(j)) = float64_add(e2, e3, vs);
135
+ }
136
+ } while (i & 63);
137
+ } while (i != 0);
138
+}
139
+
140
/*
141
* Load contiguous data, protected by a governing predicate.
142
*/
143
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-sve.c
146
+++ b/target/arm/translate-sve.c
147
@@ -XXX,XX +XXX,XX @@ DO_FPCMP(FACGT, facgt)
148
149
#undef DO_FPCMP
150
151
+static bool trans_FCADD(DisasContext *s, arg_FCADD *a, uint32_t insn)
152
+{
153
+ static gen_helper_gvec_4_ptr * const fns[3] = {
154
+ gen_helper_sve_fcadd_h,
155
+ gen_helper_sve_fcadd_s,
156
+ gen_helper_sve_fcadd_d
157
+ };
158
+
159
+ if (a->esz == 0) {
160
+ return false;
161
+ }
162
+ }
162
+ if (sve_access_check(s)) {
163
163
+ unsigned vsz = vec_full_reg_size(s);
164
mms->bootinfo.ram_size = machine->ram_size;
164
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
165
mms->bootinfo.board_id = -1;
165
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
166
+ vec_full_reg_offset(s, a->rn),
167
+ vec_full_reg_offset(s, a->rm),
168
+ pred_full_reg_offset(s, a->pg),
169
+ status, vsz, vsz, a->rot, fns[a->esz - 1]);
170
+ tcg_temp_free_ptr(status);
171
+ }
172
+ return true;
173
+}
174
+
175
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
176
177
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
178
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/sve.decode
181
+++ b/target/arm/sve.decode
182
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
183
# SVE integer multiply immediate (unpredicated)
184
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
185
186
+# SVE floating-point complex add (predicated)
187
+FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
188
+ rn=%reg_movprfx
189
+
190
### SVE FP Multiply-Add Indexed Group
191
192
# SVE floating-point multiply-add (indexed)
193
--
166
--
194
2.17.1
167
2.34.1
195
168
196
169
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
board. These are all simple devices that just need to be created and
3
wired up.
2
4
3
This helper allows to retrieve the paths of nodes whose name
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
match node-name or node-name@unit-address patterns.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
8
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
5
11
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
7
Message-id: 1530044492-24921-2-git-send-email-eric.auger@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/sysemu/device_tree.h | 16 +++++++++++
12
device_tree.c | 55 ++++++++++++++++++++++++++++++++++++
13
2 files changed, 71 insertions(+)
14
15
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/include/sysemu/device_tree.h
14
--- a/hw/arm/mps3r.c
18
+++ b/include/sysemu/device_tree.h
15
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
16
@@ -XXX,XX +XXX,XX @@
20
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
17
#include "sysemu/sysemu.h"
21
Error **errp);
18
#include "hw/boards.h"
22
19
#include "hw/or-irq.h"
23
+/**
20
+#include "hw/qdev-clock.h"
24
+ * qemu_fdt_node_unit_path: return the paths of nodes matching a given
21
#include "hw/qdev-properties.h"
25
+ * node-name, ie. node-name and node-name@unit-address
22
#include "hw/arm/boot.h"
26
+ * @fdt: pointer to the dt blob
23
#include "hw/arm/bsa.h"
27
+ * @name: node name
24
#include "hw/char/cmsdk-apb-uart.h"
28
+ * @errp: handle to an error object
25
+#include "hw/i2c/arm_sbcon_i2c.h"
29
+ *
26
#include "hw/intc/arm_gicv3.h"
30
+ * returns a newly allocated NULL-terminated array of node paths.
27
+#include "hw/misc/unimp.h"
31
+ * Use g_strfreev() to free it. If one or more nodes were found, the
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
32
+ * array contains the path of each node and the last element equals to
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
33
+ * NULL. If there is no error but no matching node was found, the
30
34
+ * returned array contains a single element equal to NULL. If an error
31
/* Define the layout of RAM and ROM in a board */
35
+ * was encountered when parsing the blob, the function returns NULL
32
typedef struct RAMInfo {
36
+ */
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
37
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
38
+
50
+
39
int qemu_fdt_setprop(void *fdt, const char *node_path,
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
40
const char *property, const void *val, int size);
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
41
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
53
memory_region_add_subregion(sysmem, ri->base, mr);
42
diff --git a/device_tree.c b/device_tree.c
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
43
index XXXXXXX..XXXXXXX 100644
55
qdev_get_gpio_in(gicdev, combirq));
44
--- a/device_tree.c
56
}
45
+++ b/device_tree.c
57
46
@@ -XXX,XX +XXX,XX @@ static int findnode_nofail(void *fdt, const char *node_path)
58
+ for (int i = 0; i < 4; i++) {
47
return offset;
59
+ /* CMSDK GPIO controllers */
48
}
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
49
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
50
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
51
+{
52
+ char *prefix = g_strdup_printf("%s@", name);
53
+ unsigned int path_len = 16, n = 0;
54
+ GSList *path_list = NULL, *iter;
55
+ const char *iter_name;
56
+ int offset, len, ret;
57
+ char **path_array;
58
+
59
+ offset = fdt_next_node(fdt, -1, NULL);
60
+
61
+ while (offset >= 0) {
62
+ iter_name = fdt_get_name(fdt, offset, &len);
63
+ if (!iter_name) {
64
+ offset = len;
65
+ break;
66
+ }
67
+ if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
68
+ char *path;
69
+
70
+ path = g_malloc(path_len);
71
+ while ((ret = fdt_get_path(fdt, offset, path, path_len))
72
+ == -FDT_ERR_NOSPACE) {
73
+ path_len += 16;
74
+ path = g_realloc(path, path_len);
75
+ }
76
+ path_list = g_slist_prepend(path_list, path);
77
+ n++;
78
+ }
79
+ offset = fdt_next_node(fdt, offset, NULL);
80
+ }
81
+ g_free(prefix);
82
+
83
+ if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
84
+ error_setg(errp, "%s: abort parsing dt for %s node units: %s",
85
+ __func__, name, fdt_strerror(offset));
86
+ for (iter = path_list; iter; iter = iter->next) {
87
+ g_free(iter->data);
88
+ }
89
+ g_slist_free(path_list);
90
+ return NULL;
91
+ }
62
+ }
92
+
63
+
93
+ path_array = g_new(char *, n + 1);
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
94
+ path_array[n--] = NULL;
65
+ TYPE_CMSDK_APB_WATCHDOG);
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
69
+ qdev_get_gpio_in(gicdev, 0));
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
95
+
71
+
96
+ for (iter = path_list; iter; iter = iter->next) {
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
97
+ path_array[n--] = iter->data;
73
+ TYPE_CMSDK_APB_DUALTIMER);
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
98
+ }
103
+ }
99
+
104
+
100
+ g_slist_free(path_list);
105
mms->bootinfo.ram_size = machine->ram_size;
101
+
106
mms->bootinfo.board_id = -1;
102
+ return path_array;
107
mms->bootinfo.loader_start = mmc->loader_start;
103
+}
104
+
105
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
106
Error **errp)
107
{
108
--
108
--
109
2.17.1
109
2.34.1
110
110
111
111
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
When running dtc on the guest /proc/device-tree we get the
4
following warnings: "Warning (unit_address_vs_reg): Node <name>
5
has a reg or ranges property, but no unit name", with name:
6
/intc, /intc/its, /intc/v2m.
7
8
Nodes should have a name in the form <name>[@<unit-address>] where
9
unit-address is the primary address used to access the device, listed
10
in the node's reg property. This fix seems to make dtc happy.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1530044492-24921-3-git-send-email-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/virt.c | 63 +++++++++++++++++++++++++++++++--------------------
18
1 file changed, 39 insertions(+), 24 deletions(-)
19
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt.c
23
+++ b/hw/arm/virt.c
24
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
25
26
static void fdt_add_its_gic_node(VirtMachineState *vms)
27
{
28
+ char *nodename;
29
+
30
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
31
- qemu_fdt_add_subnode(vms->fdt, "/intc/its");
32
- qemu_fdt_setprop_string(vms->fdt, "/intc/its", "compatible",
33
+ nodename = g_strdup_printf("/intc/its@%" PRIx64,
34
+ vms->memmap[VIRT_GIC_ITS].base);
35
+ qemu_fdt_add_subnode(vms->fdt, nodename);
36
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
37
"arm,gic-v3-its");
38
- qemu_fdt_setprop(vms->fdt, "/intc/its", "msi-controller", NULL, 0);
39
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/its", "reg",
40
+ qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
41
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
42
2, vms->memmap[VIRT_GIC_ITS].base,
43
2, vms->memmap[VIRT_GIC_ITS].size);
44
- qemu_fdt_setprop_cell(vms->fdt, "/intc/its", "phandle", vms->msi_phandle);
45
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
46
+ g_free(nodename);
47
}
48
49
static void fdt_add_v2m_gic_node(VirtMachineState *vms)
50
{
51
+ char *nodename;
52
+
53
+ nodename = g_strdup_printf("/intc/v2m@%" PRIx64,
54
+ vms->memmap[VIRT_GIC_V2M].base);
55
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
56
- qemu_fdt_add_subnode(vms->fdt, "/intc/v2m");
57
- qemu_fdt_setprop_string(vms->fdt, "/intc/v2m", "compatible",
58
+ qemu_fdt_add_subnode(vms->fdt, nodename);
59
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
60
"arm,gic-v2m-frame");
61
- qemu_fdt_setprop(vms->fdt, "/intc/v2m", "msi-controller", NULL, 0);
62
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/v2m", "reg",
63
+ qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
64
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
65
2, vms->memmap[VIRT_GIC_V2M].base,
66
2, vms->memmap[VIRT_GIC_V2M].size);
67
- qemu_fdt_setprop_cell(vms->fdt, "/intc/v2m", "phandle", vms->msi_phandle);
68
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
69
+ g_free(nodename);
70
}
71
72
static void fdt_add_gic_node(VirtMachineState *vms)
73
{
74
+ char *nodename;
75
+
76
vms->gic_phandle = qemu_fdt_alloc_phandle(vms->fdt);
77
qemu_fdt_setprop_cell(vms->fdt, "/", "interrupt-parent", vms->gic_phandle);
78
79
- qemu_fdt_add_subnode(vms->fdt, "/intc");
80
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#interrupt-cells", 3);
81
- qemu_fdt_setprop(vms->fdt, "/intc", "interrupt-controller", NULL, 0);
82
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#address-cells", 0x2);
83
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#size-cells", 0x2);
84
- qemu_fdt_setprop(vms->fdt, "/intc", "ranges", NULL, 0);
85
+ nodename = g_strdup_printf("/intc@%" PRIx64,
86
+ vms->memmap[VIRT_GIC_DIST].base);
87
+ qemu_fdt_add_subnode(vms->fdt, nodename);
88
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 3);
89
+ qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0);
90
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 0x2);
91
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0x2);
92
+ qemu_fdt_setprop(vms->fdt, nodename, "ranges", NULL, 0);
93
if (vms->gic_version == 3) {
94
int nb_redist_regions = virt_gicv3_redist_region_count(vms);
95
96
- qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
97
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
98
"arm,gic-v3");
99
100
- qemu_fdt_setprop_cell(vms->fdt, "/intc",
101
+ qemu_fdt_setprop_cell(vms->fdt, nodename,
102
"#redistributor-regions", nb_redist_regions);
103
104
if (nb_redist_regions == 1) {
105
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
106
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
107
2, vms->memmap[VIRT_GIC_DIST].base,
108
2, vms->memmap[VIRT_GIC_DIST].size,
109
2, vms->memmap[VIRT_GIC_REDIST].base,
110
2, vms->memmap[VIRT_GIC_REDIST].size);
111
} else {
112
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
113
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
114
2, vms->memmap[VIRT_GIC_DIST].base,
115
2, vms->memmap[VIRT_GIC_DIST].size,
116
2, vms->memmap[VIRT_GIC_REDIST].base,
117
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
118
}
119
120
if (vms->virt) {
121
- qemu_fdt_setprop_cells(vms->fdt, "/intc", "interrupts",
122
+ qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts",
123
GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_IRQ,
124
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
125
}
126
} else {
127
/* 'cortex-a15-gic' means 'GIC v2' */
128
- qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
129
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
130
"arm,cortex-a15-gic");
131
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
132
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
133
2, vms->memmap[VIRT_GIC_DIST].base,
134
2, vms->memmap[VIRT_GIC_DIST].size,
135
2, vms->memmap[VIRT_GIC_CPU].base,
136
2, vms->memmap[VIRT_GIC_CPU].size);
137
}
138
139
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "phandle", vms->gic_phandle);
140
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->gic_phandle);
141
+ g_free(nodename);
142
}
143
144
static void fdt_add_pmu_nodes(const VirtMachineState *vms)
145
--
146
2.17.1
147
148
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180627043328.11531-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 35 +++++++++
10
target/arm/sve_helper.c | 153 +++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 121 +++++++++++++++++++++++++++++
12
target/arm/sve.decode | 34 +++++++++
13
4 files changed, 343 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
22
void, ptr, ptr, ptr, ptr, i32)
23
+
24
+DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(sve_ld4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve_ld1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_ld2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(sve_ld3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+DEF_HELPER_FLAGS_4(sve_ld4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
+
34
+DEF_HELPER_FLAGS_4(sve_ld1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_ld2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_ld3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+DEF_HELPER_FLAGS_4(sve_ld4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
38
+
39
+DEF_HELPER_FLAGS_4(sve_ld1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_ld2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_ld3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_4(sve_ld4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_ld1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_ld1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_4(sve_ld1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(sve_ld1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_ld1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_4(sve_ld1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+
51
+DEF_HELPER_FLAGS_4(sve_ld1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_4(sve_ld1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(sve_ld1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+
56
+DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
63
64
return predtest_ones(d, oprsz, esz_mask);
65
}
66
+
67
+/*
68
+ * Load contiguous data, protected by a governing predicate.
69
+ */
70
+#define DO_LD1(NAME, FN, TYPEE, TYPEM, H) \
71
+static void do_##NAME(CPUARMState *env, void *vd, void *vg, \
72
+ target_ulong addr, intptr_t oprsz, \
73
+ uintptr_t ra) \
74
+{ \
75
+ intptr_t i = 0; \
76
+ do { \
77
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
78
+ do { \
79
+ TYPEM m = 0; \
80
+ if (pg & 1) { \
81
+ m = FN(env, addr, ra); \
82
+ } \
83
+ *(TYPEE *)(vd + H(i)) = m; \
84
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
85
+ addr += sizeof(TYPEM); \
86
+ } while (i & 15); \
87
+ } while (i < oprsz); \
88
+} \
89
+void HELPER(NAME)(CPUARMState *env, void *vg, \
90
+ target_ulong addr, uint32_t desc) \
91
+{ \
92
+ do_##NAME(env, &env->vfp.zregs[simd_data(desc)], vg, \
93
+ addr, simd_oprsz(desc), GETPC()); \
94
+}
95
+
96
+#define DO_LD2(NAME, FN, TYPEE, TYPEM, H) \
97
+void HELPER(NAME)(CPUARMState *env, void *vg, \
98
+ target_ulong addr, uint32_t desc) \
99
+{ \
100
+ intptr_t i, oprsz = simd_oprsz(desc); \
101
+ intptr_t ra = GETPC(); \
102
+ unsigned rd = simd_data(desc); \
103
+ void *d1 = &env->vfp.zregs[rd]; \
104
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
105
+ for (i = 0; i < oprsz; ) { \
106
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
107
+ do { \
108
+ TYPEM m1 = 0, m2 = 0; \
109
+ if (pg & 1) { \
110
+ m1 = FN(env, addr, ra); \
111
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
112
+ } \
113
+ *(TYPEE *)(d1 + H(i)) = m1; \
114
+ *(TYPEE *)(d2 + H(i)) = m2; \
115
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
116
+ addr += 2 * sizeof(TYPEM); \
117
+ } while (i & 15); \
118
+ } \
119
+}
120
+
121
+#define DO_LD3(NAME, FN, TYPEE, TYPEM, H) \
122
+void HELPER(NAME)(CPUARMState *env, void *vg, \
123
+ target_ulong addr, uint32_t desc) \
124
+{ \
125
+ intptr_t i, oprsz = simd_oprsz(desc); \
126
+ intptr_t ra = GETPC(); \
127
+ unsigned rd = simd_data(desc); \
128
+ void *d1 = &env->vfp.zregs[rd]; \
129
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
130
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
131
+ for (i = 0; i < oprsz; ) { \
132
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
133
+ do { \
134
+ TYPEM m1 = 0, m2 = 0, m3 = 0; \
135
+ if (pg & 1) { \
136
+ m1 = FN(env, addr, ra); \
137
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
138
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
139
+ } \
140
+ *(TYPEE *)(d1 + H(i)) = m1; \
141
+ *(TYPEE *)(d2 + H(i)) = m2; \
142
+ *(TYPEE *)(d3 + H(i)) = m3; \
143
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
144
+ addr += 3 * sizeof(TYPEM); \
145
+ } while (i & 15); \
146
+ } \
147
+}
148
+
149
+#define DO_LD4(NAME, FN, TYPEE, TYPEM, H) \
150
+void HELPER(NAME)(CPUARMState *env, void *vg, \
151
+ target_ulong addr, uint32_t desc) \
152
+{ \
153
+ intptr_t i, oprsz = simd_oprsz(desc); \
154
+ intptr_t ra = GETPC(); \
155
+ unsigned rd = simd_data(desc); \
156
+ void *d1 = &env->vfp.zregs[rd]; \
157
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
158
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
159
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
160
+ for (i = 0; i < oprsz; ) { \
161
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
162
+ do { \
163
+ TYPEM m1 = 0, m2 = 0, m3 = 0, m4 = 0; \
164
+ if (pg & 1) { \
165
+ m1 = FN(env, addr, ra); \
166
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
167
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
168
+ m4 = FN(env, addr + 3 * sizeof(TYPEM), ra); \
169
+ } \
170
+ *(TYPEE *)(d1 + H(i)) = m1; \
171
+ *(TYPEE *)(d2 + H(i)) = m2; \
172
+ *(TYPEE *)(d3 + H(i)) = m3; \
173
+ *(TYPEE *)(d4 + H(i)) = m4; \
174
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
175
+ addr += 4 * sizeof(TYPEM); \
176
+ } while (i & 15); \
177
+ } \
178
+}
179
+
180
+DO_LD1(sve_ld1bhu_r, cpu_ldub_data_ra, uint16_t, uint8_t, H1_2)
181
+DO_LD1(sve_ld1bhs_r, cpu_ldsb_data_ra, uint16_t, int8_t, H1_2)
182
+DO_LD1(sve_ld1bsu_r, cpu_ldub_data_ra, uint32_t, uint8_t, H1_4)
183
+DO_LD1(sve_ld1bss_r, cpu_ldsb_data_ra, uint32_t, int8_t, H1_4)
184
+DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
185
+DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
186
+
187
+DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
188
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
189
+DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
190
+DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
191
+
192
+DO_LD1(sve_ld1sdu_r, cpu_ldl_data_ra, uint64_t, uint32_t, )
193
+DO_LD1(sve_ld1sds_r, cpu_ldl_data_ra, uint64_t, int32_t, )
194
+
195
+DO_LD1(sve_ld1bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
196
+DO_LD2(sve_ld2bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
197
+DO_LD3(sve_ld3bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
198
+DO_LD4(sve_ld4bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
199
+
200
+DO_LD1(sve_ld1hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
201
+DO_LD2(sve_ld2hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
202
+DO_LD3(sve_ld3hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
203
+DO_LD4(sve_ld4hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
204
+
205
+DO_LD1(sve_ld1ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
206
+DO_LD2(sve_ld2ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
207
+DO_LD3(sve_ld3ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
208
+DO_LD4(sve_ld4ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
209
+
210
+DO_LD1(sve_ld1dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
211
+DO_LD2(sve_ld2dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
212
+DO_LD3(sve_ld3dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
213
+DO_LD4(sve_ld4dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
214
+
215
+#undef DO_LD1
216
+#undef DO_LD2
217
+#undef DO_LD3
218
+#undef DO_LD4
219
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/arm/translate-sve.c
222
+++ b/target/arm/translate-sve.c
223
@@ -XXX,XX +XXX,XX @@ typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
224
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
225
TCGv_ptr, TCGv_ptr, TCGv_i32);
226
227
+typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32);
228
+
229
/*
230
* Helpers for extracting complex instruction fields.
231
*/
232
@@ -XXX,XX +XXX,XX @@ static inline int expand_imm_sh8u(int x)
233
return (uint8_t)x << (x & 0x100 ? 8 : 0);
234
}
235
236
+/* Convert a 2-bit memory size (msz) to a 4-bit data type (dtype)
237
+ * with unsigned data. C.f. SVE Memory Contiguous Load Group.
238
+ */
239
+static inline int msz_dtype(int msz)
240
+{
241
+ static const uint8_t dtype[4] = { 0, 5, 10, 15 };
242
+ return dtype[msz];
243
+}
244
+
245
/*
246
* Include the generated decoder.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
249
}
250
return true;
251
}
252
+
253
+/*
254
+ *** SVE Memory - Contiguous Load Group
255
+ */
256
+
257
+/* The memory mode of the dtype. */
258
+static const TCGMemOp dtype_mop[16] = {
259
+ MO_UB, MO_UB, MO_UB, MO_UB,
260
+ MO_SL, MO_UW, MO_UW, MO_UW,
261
+ MO_SW, MO_SW, MO_UL, MO_UL,
262
+ MO_SB, MO_SB, MO_SB, MO_Q
263
+};
264
+
265
+#define dtype_msz(x) (dtype_mop[x] & MO_SIZE)
266
+
267
+/* The vector element size of dtype. */
268
+static const uint8_t dtype_esz[16] = {
269
+ 0, 1, 2, 3,
270
+ 3, 1, 2, 3,
271
+ 3, 2, 2, 3,
272
+ 3, 2, 1, 3
273
+};
274
+
275
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
276
+ gen_helper_gvec_mem *fn)
277
+{
278
+ unsigned vsz = vec_full_reg_size(s);
279
+ TCGv_ptr t_pg;
280
+ TCGv_i32 desc;
281
+
282
+ /* For e.g. LD4, there are not enough arguments to pass all 4
283
+ * registers as pointers, so encode the regno into the data field.
284
+ * For consistency, do this even for LD1.
285
+ */
286
+ desc = tcg_const_i32(simd_desc(vsz, vsz, zt));
287
+ t_pg = tcg_temp_new_ptr();
288
+
289
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
290
+ fn(cpu_env, t_pg, addr, desc);
291
+
292
+ tcg_temp_free_ptr(t_pg);
293
+ tcg_temp_free_i32(desc);
294
+}
295
+
296
+static void do_ld_zpa(DisasContext *s, int zt, int pg,
297
+ TCGv_i64 addr, int dtype, int nreg)
298
+{
299
+ static gen_helper_gvec_mem * const fns[16][4] = {
300
+ { gen_helper_sve_ld1bb_r, gen_helper_sve_ld2bb_r,
301
+ gen_helper_sve_ld3bb_r, gen_helper_sve_ld4bb_r },
302
+ { gen_helper_sve_ld1bhu_r, NULL, NULL, NULL },
303
+ { gen_helper_sve_ld1bsu_r, NULL, NULL, NULL },
304
+ { gen_helper_sve_ld1bdu_r, NULL, NULL, NULL },
305
+
306
+ { gen_helper_sve_ld1sds_r, NULL, NULL, NULL },
307
+ { gen_helper_sve_ld1hh_r, gen_helper_sve_ld2hh_r,
308
+ gen_helper_sve_ld3hh_r, gen_helper_sve_ld4hh_r },
309
+ { gen_helper_sve_ld1hsu_r, NULL, NULL, NULL },
310
+ { gen_helper_sve_ld1hdu_r, NULL, NULL, NULL },
311
+
312
+ { gen_helper_sve_ld1hds_r, NULL, NULL, NULL },
313
+ { gen_helper_sve_ld1hss_r, NULL, NULL, NULL },
314
+ { gen_helper_sve_ld1ss_r, gen_helper_sve_ld2ss_r,
315
+ gen_helper_sve_ld3ss_r, gen_helper_sve_ld4ss_r },
316
+ { gen_helper_sve_ld1sdu_r, NULL, NULL, NULL },
317
+
318
+ { gen_helper_sve_ld1bds_r, NULL, NULL, NULL },
319
+ { gen_helper_sve_ld1bss_r, NULL, NULL, NULL },
320
+ { gen_helper_sve_ld1bhs_r, NULL, NULL, NULL },
321
+ { gen_helper_sve_ld1dd_r, gen_helper_sve_ld2dd_r,
322
+ gen_helper_sve_ld3dd_r, gen_helper_sve_ld4dd_r },
323
+ };
324
+ gen_helper_gvec_mem *fn = fns[dtype][nreg];
325
+
326
+ /* While there are holes in the table, they are not
327
+ * accessible via the instruction encoding.
328
+ */
329
+ assert(fn != NULL);
330
+ do_mem_zpa(s, zt, pg, addr, fn);
331
+}
332
+
333
+static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
334
+{
335
+ if (a->rm == 31) {
336
+ return false;
337
+ }
338
+ if (sve_access_check(s)) {
339
+ TCGv_i64 addr = new_tmp_a64(s);
340
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
341
+ (a->nreg + 1) << dtype_msz(a->dtype));
342
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
343
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
344
+ }
345
+ return true;
346
+}
347
+
348
+static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
349
+{
350
+ if (sve_access_check(s)) {
351
+ int vsz = vec_full_reg_size(s);
352
+ int elements = vsz >> dtype_esz[a->dtype];
353
+ TCGv_i64 addr = new_tmp_a64(s);
354
+
355
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
356
+ (a->imm * elements * (a->nreg + 1))
357
+ << dtype_msz(a->dtype));
358
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
359
+ }
360
+ return true;
361
+}
362
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
363
index XXXXXXX..XXXXXXX 100644
364
--- a/target/arm/sve.decode
365
+++ b/target/arm/sve.decode
366
@@ -XXX,XX +XXX,XX @@
367
# Unsigned 8-bit immediate, optionally shifted left by 8.
368
%sh8_i8u 5:9 !function=expand_imm_sh8u
369
370
+# Unsigned load of msz into esz=2, represented as a dtype.
371
+%msz_dtype 23:2 !function=msz_dtype
372
+
373
# Either a copy of rd (at bit 0), or a different source
374
# as propagated via the MOVPRFX instruction.
375
%reg_movprfx 0:5
376
@@ -XXX,XX +XXX,XX @@
377
&incdec2_cnt rd rn pat esz imm d u
378
&incdec_pred rd pg esz d u
379
&incdec2_pred rd rn pg esz d u
380
+&rprr_load rd pg rn rm dtype nreg
381
+&rpri_load rd pg rn imm dtype nreg
382
383
###########################################################################
384
# Named instruction formats. These are generally used to
385
@@ -XXX,XX +XXX,XX @@
386
@incdec2_pred ........ esz:2 .... .. ..... .. pg:4 rd:5 \
387
&incdec2_pred rn=%reg_movprfx
388
389
+# Loads; user must fill in NREG.
390
+@rprr_load_dt ....... dtype:4 rm:5 ... pg:3 rn:5 rd:5 &rprr_load
391
+@rpri_load_dt ....... dtype:4 . imm:s4 ... pg:3 rn:5 rd:5 &rpri_load
392
+
393
+@rprr_load_msz ....... .... rm:5 ... pg:3 rn:5 rd:5 \
394
+ &rprr_load dtype=%msz_dtype
395
+@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
396
+ &rpri_load dtype=%msz_dtype
397
+
398
###########################################################################
399
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
400
401
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
402
403
# SVE load vector register
404
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
405
+
406
+### SVE Memory Contiguous Load Group
407
+
408
+# SVE contiguous load (scalar plus scalar)
409
+LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
410
+
411
+# SVE contiguous load (scalar plus immediate)
412
+LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
413
+
414
+# SVE contiguous non-temporal load (scalar plus scalar)
415
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
416
+# SVE load multiple structures (scalar plus scalar)
417
+# LD2B, LD2H, LD2W, LD2D; etc.
418
+LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
419
+
420
+# SVE contiguous non-temporal load (scalar plus immediate)
421
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
422
+# SVE load multiple structures (scalar plus immediate)
423
+# LD2B, LD2H, LD2W, LD2D; etc.
424
+LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
425
--
426
2.17.1
427
428
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 40 ++++++++++
10
target/arm/sve_helper.c | 157 +++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 69 ++++++++++++++++
12
target/arm/sve.decode | 6 ++
13
4 files changed, 272 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
23
+
24
+DEF_HELPER_FLAGS_4(sve_ldff1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_ldff1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_ldff1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(sve_ldff1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
+DEF_HELPER_FLAGS_4(sve_ldff1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(sve_ldff1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_ldff1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+
32
+DEF_HELPER_FLAGS_4(sve_ldff1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
+DEF_HELPER_FLAGS_4(sve_ldff1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_4(sve_ldff1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_ldff1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_ldff1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve_ldff1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_4(sve_ldff1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_ldff1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+
42
+DEF_HELPER_FLAGS_4(sve_ldff1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_ldnf1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_ldnf1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_4(sve_ldnf1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(sve_ldnf1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_ldnf1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_4(sve_ldnf1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+DEF_HELPER_FLAGS_4(sve_ldnf1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
+
52
+DEF_HELPER_FLAGS_4(sve_ldnf1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(sve_ldnf1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_4(sve_ldnf1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_4(sve_ldnf1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
56
+DEF_HELPER_FLAGS_4(sve_ldnf1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
57
+
58
+DEF_HELPER_FLAGS_4(sve_ldnf1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
59
+DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
61
+
62
+DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
63
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/sve_helper.c
66
+++ b/target/arm/sve_helper.c
67
@@ -XXX,XX +XXX,XX @@ DO_LD4(sve_ld4dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
68
#undef DO_LD2
69
#undef DO_LD3
70
#undef DO_LD4
71
+
72
+/*
73
+ * Load contiguous data, first-fault and no-fault.
74
+ */
75
+
76
+#ifdef CONFIG_USER_ONLY
77
+
78
+/* Fault on byte I. All bits in FFR from I are cleared. The vector
79
+ * result from I is CONSTRAINED UNPREDICTABLE; we choose the MERGE
80
+ * option, which leaves subsequent data unchanged.
81
+ */
82
+static void record_fault(CPUARMState *env, uintptr_t i, uintptr_t oprsz)
83
+{
84
+ uint64_t *ffr = env->vfp.pregs[FFR_PRED_NUM].p;
85
+
86
+ if (i & 63) {
87
+ ffr[i / 64] &= MAKE_64BIT_MASK(0, i & 63);
88
+ i = ROUND_UP(i, 64);
89
+ }
90
+ for (; i < oprsz; i += 64) {
91
+ ffr[i / 64] = 0;
92
+ }
93
+}
94
+
95
+/* Hold the mmap lock during the operation so that there is no race
96
+ * between page_check_range and the load operation. We expect the
97
+ * usual case to have no faults at all, so we check the whole range
98
+ * first and if successful defer to the normal load operation.
99
+ *
100
+ * TODO: Change mmap_lock to a rwlock so that multiple readers
101
+ * can run simultaneously. This will probably help other uses
102
+ * within QEMU as well.
103
+ */
104
+#define DO_LDFF1(PART, FN, TYPEE, TYPEM, H) \
105
+static void do_sve_ldff1##PART(CPUARMState *env, void *vd, void *vg, \
106
+ target_ulong addr, intptr_t oprsz, \
107
+ bool first, uintptr_t ra) \
108
+{ \
109
+ intptr_t i = 0; \
110
+ do { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ TYPEM m = 0; \
114
+ if (pg & 1) { \
115
+ if (!first && \
116
+ unlikely(page_check_range(addr, sizeof(TYPEM), \
117
+ PAGE_READ))) { \
118
+ record_fault(env, i, oprsz); \
119
+ return; \
120
+ } \
121
+ m = FN(env, addr, ra); \
122
+ first = false; \
123
+ } \
124
+ *(TYPEE *)(vd + H(i)) = m; \
125
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
126
+ addr += sizeof(TYPEM); \
127
+ } while (i & 15); \
128
+ } while (i < oprsz); \
129
+} \
130
+void HELPER(sve_ldff1##PART)(CPUARMState *env, void *vg, \
131
+ target_ulong addr, uint32_t desc) \
132
+{ \
133
+ intptr_t oprsz = simd_oprsz(desc); \
134
+ unsigned rd = simd_data(desc); \
135
+ void *vd = &env->vfp.zregs[rd]; \
136
+ mmap_lock(); \
137
+ if (likely(page_check_range(addr, oprsz, PAGE_READ) == 0)) { \
138
+ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \
139
+ } else { \
140
+ do_sve_ldff1##PART(env, vd, vg, addr, oprsz, true, GETPC()); \
141
+ } \
142
+ mmap_unlock(); \
143
+}
144
+
145
+/* No-fault loads are like first-fault loads without the
146
+ * first faulting special case.
147
+ */
148
+#define DO_LDNF1(PART) \
149
+void HELPER(sve_ldnf1##PART)(CPUARMState *env, void *vg, \
150
+ target_ulong addr, uint32_t desc) \
151
+{ \
152
+ intptr_t oprsz = simd_oprsz(desc); \
153
+ unsigned rd = simd_data(desc); \
154
+ void *vd = &env->vfp.zregs[rd]; \
155
+ mmap_lock(); \
156
+ if (likely(page_check_range(addr, oprsz, PAGE_READ) == 0)) { \
157
+ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \
158
+ } else { \
159
+ do_sve_ldff1##PART(env, vd, vg, addr, oprsz, false, GETPC()); \
160
+ } \
161
+ mmap_unlock(); \
162
+}
163
+
164
+#else
165
+
166
+/* TODO: System mode is not yet supported.
167
+ * This would probably use tlb_vaddr_to_host.
168
+ */
169
+#define DO_LDFF1(PART, FN, TYPEE, TYPEM, H) \
170
+void HELPER(sve_ldff1##PART)(CPUARMState *env, void *vg, \
171
+ target_ulong addr, uint32_t desc) \
172
+{ \
173
+ g_assert_not_reached(); \
174
+}
175
+
176
+#define DO_LDNF1(PART) \
177
+void HELPER(sve_ldnf1##PART)(CPUARMState *env, void *vg, \
178
+ target_ulong addr, uint32_t desc) \
179
+{ \
180
+ g_assert_not_reached(); \
181
+}
182
+
183
+#endif
184
+
185
+DO_LDFF1(bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
186
+DO_LDFF1(bhu_r, cpu_ldub_data_ra, uint16_t, uint8_t, H1_2)
187
+DO_LDFF1(bhs_r, cpu_ldsb_data_ra, uint16_t, int8_t, H1_2)
188
+DO_LDFF1(bsu_r, cpu_ldub_data_ra, uint32_t, uint8_t, H1_4)
189
+DO_LDFF1(bss_r, cpu_ldsb_data_ra, uint32_t, int8_t, H1_4)
190
+DO_LDFF1(bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
191
+DO_LDFF1(bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
192
+
193
+DO_LDFF1(hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
194
+DO_LDFF1(hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
195
+DO_LDFF1(hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
196
+DO_LDFF1(hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
197
+DO_LDFF1(hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
198
+
199
+DO_LDFF1(ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
200
+DO_LDFF1(sdu_r, cpu_ldl_data_ra, uint64_t, uint32_t, )
201
+DO_LDFF1(sds_r, cpu_ldl_data_ra, uint64_t, int32_t, )
202
+
203
+DO_LDFF1(dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
204
+
205
+#undef DO_LDFF1
206
+
207
+DO_LDNF1(bb_r)
208
+DO_LDNF1(bhu_r)
209
+DO_LDNF1(bhs_r)
210
+DO_LDNF1(bsu_r)
211
+DO_LDNF1(bss_r)
212
+DO_LDNF1(bdu_r)
213
+DO_LDNF1(bds_r)
214
+
215
+DO_LDNF1(hh_r)
216
+DO_LDNF1(hsu_r)
217
+DO_LDNF1(hss_r)
218
+DO_LDNF1(hdu_r)
219
+DO_LDNF1(hds_r)
220
+
221
+DO_LDNF1(ss_r)
222
+DO_LDNF1(sdu_r)
223
+DO_LDNF1(sds_r)
224
+
225
+DO_LDNF1(dd_r)
226
+
227
+#undef DO_LDNF1
228
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
229
index XXXXXXX..XXXXXXX 100644
230
--- a/target/arm/translate-sve.c
231
+++ b/target/arm/translate-sve.c
232
@@ -XXX,XX +XXX,XX @@ static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
233
}
234
return true;
235
}
236
+
237
+static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
238
+{
239
+ static gen_helper_gvec_mem * const fns[16] = {
240
+ gen_helper_sve_ldff1bb_r,
241
+ gen_helper_sve_ldff1bhu_r,
242
+ gen_helper_sve_ldff1bsu_r,
243
+ gen_helper_sve_ldff1bdu_r,
244
+
245
+ gen_helper_sve_ldff1sds_r,
246
+ gen_helper_sve_ldff1hh_r,
247
+ gen_helper_sve_ldff1hsu_r,
248
+ gen_helper_sve_ldff1hdu_r,
249
+
250
+ gen_helper_sve_ldff1hds_r,
251
+ gen_helper_sve_ldff1hss_r,
252
+ gen_helper_sve_ldff1ss_r,
253
+ gen_helper_sve_ldff1sdu_r,
254
+
255
+ gen_helper_sve_ldff1bds_r,
256
+ gen_helper_sve_ldff1bss_r,
257
+ gen_helper_sve_ldff1bhs_r,
258
+ gen_helper_sve_ldff1dd_r,
259
+ };
260
+
261
+ if (sve_access_check(s)) {
262
+ TCGv_i64 addr = new_tmp_a64(s);
263
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
264
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
265
+ do_mem_zpa(s, a->rd, a->pg, addr, fns[a->dtype]);
266
+ }
267
+ return true;
268
+}
269
+
270
+static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
271
+{
272
+ static gen_helper_gvec_mem * const fns[16] = {
273
+ gen_helper_sve_ldnf1bb_r,
274
+ gen_helper_sve_ldnf1bhu_r,
275
+ gen_helper_sve_ldnf1bsu_r,
276
+ gen_helper_sve_ldnf1bdu_r,
277
+
278
+ gen_helper_sve_ldnf1sds_r,
279
+ gen_helper_sve_ldnf1hh_r,
280
+ gen_helper_sve_ldnf1hsu_r,
281
+ gen_helper_sve_ldnf1hdu_r,
282
+
283
+ gen_helper_sve_ldnf1hds_r,
284
+ gen_helper_sve_ldnf1hss_r,
285
+ gen_helper_sve_ldnf1ss_r,
286
+ gen_helper_sve_ldnf1sdu_r,
287
+
288
+ gen_helper_sve_ldnf1bds_r,
289
+ gen_helper_sve_ldnf1bss_r,
290
+ gen_helper_sve_ldnf1bhs_r,
291
+ gen_helper_sve_ldnf1dd_r,
292
+ };
293
+
294
+ if (sve_access_check(s)) {
295
+ int vsz = vec_full_reg_size(s);
296
+ int elements = vsz >> dtype_esz[a->dtype];
297
+ int off = (a->imm * elements) << dtype_msz(a->dtype);
298
+ TCGv_i64 addr = new_tmp_a64(s);
299
+
300
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), off);
301
+ do_mem_zpa(s, a->rd, a->pg, addr, fns[a->dtype]);
302
+ }
303
+ return true;
304
+}
305
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
306
index XXXXXXX..XXXXXXX 100644
307
--- a/target/arm/sve.decode
308
+++ b/target/arm/sve.decode
309
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
310
# SVE contiguous load (scalar plus scalar)
311
LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
312
313
+# SVE contiguous first-fault load (scalar plus scalar)
314
+LDFF1_zprr 1010010 .... ..... 011 ... ..... ..... @rprr_load_dt nreg=0
315
+
316
# SVE contiguous load (scalar plus immediate)
317
LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
318
319
+# SVE contiguous non-fault load (scalar plus immediate)
320
+LDNF1_zpri 1010010 .... 1.... 101 ... ..... ..... @rpri_load_dt nreg=0
321
+
322
# SVE contiguous non-temporal load (scalar plus scalar)
323
# LDNT1B, LDNT1H, LDNT1W, LDNT1D
324
# SVE load multiple structures (scalar plus scalar)
325
--
326
2.17.1
327
328
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 29 +++++
9
target/arm/sve_helper.c | 211 +++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 65 ++++++++++++
11
target/arm/sve.decode | 38 +++++++
12
4 files changed, 343 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
+
23
+DEF_HELPER_FLAGS_4(sve_st1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
+DEF_HELPER_FLAGS_4(sve_st2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_st3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_st4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+
28
+DEF_HELPER_FLAGS_4(sve_st1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(sve_st2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_st3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(sve_st4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+
33
+DEF_HELPER_FLAGS_4(sve_st1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_4(sve_st2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_st3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_st4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve_st1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_4(sve_st2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_st3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_st4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+
43
+DEF_HELPER_FLAGS_4(sve_st1bh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
44
+DEF_HELPER_FLAGS_4(sve_st1bs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_st1bd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+
47
+DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+
50
+DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve_helper.c
54
+++ b/target/arm/sve_helper.c
55
@@ -XXX,XX +XXX,XX @@ DO_LDNF1(sds_r)
56
DO_LDNF1(dd_r)
57
58
#undef DO_LDNF1
59
+
60
+/*
61
+ * Store contiguous data, protected by a governing predicate.
62
+ */
63
+#define DO_ST1(NAME, FN, TYPEE, TYPEM, H) \
64
+void HELPER(NAME)(CPUARMState *env, void *vg, \
65
+ target_ulong addr, uint32_t desc) \
66
+{ \
67
+ intptr_t i, oprsz = simd_oprsz(desc); \
68
+ intptr_t ra = GETPC(); \
69
+ unsigned rd = simd_data(desc); \
70
+ void *vd = &env->vfp.zregs[rd]; \
71
+ for (i = 0; i < oprsz; ) { \
72
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
73
+ do { \
74
+ if (pg & 1) { \
75
+ TYPEM m = *(TYPEE *)(vd + H(i)); \
76
+ FN(env, addr, m, ra); \
77
+ } \
78
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
79
+ addr += sizeof(TYPEM); \
80
+ } while (i & 15); \
81
+ } \
82
+}
83
+
84
+#define DO_ST1_D(NAME, FN, TYPEM) \
85
+void HELPER(NAME)(CPUARMState *env, void *vg, \
86
+ target_ulong addr, uint32_t desc) \
87
+{ \
88
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
89
+ intptr_t ra = GETPC(); \
90
+ unsigned rd = simd_data(desc); \
91
+ uint64_t *d = &env->vfp.zregs[rd].d[0]; \
92
+ uint8_t *pg = vg; \
93
+ for (i = 0; i < oprsz; i += 1) { \
94
+ if (pg[H1(i)] & 1) { \
95
+ FN(env, addr, d[i], ra); \
96
+ } \
97
+ addr += sizeof(TYPEM); \
98
+ } \
99
+}
100
+
101
+#define DO_ST2(NAME, FN, TYPEE, TYPEM, H) \
102
+void HELPER(NAME)(CPUARMState *env, void *vg, \
103
+ target_ulong addr, uint32_t desc) \
104
+{ \
105
+ intptr_t i, oprsz = simd_oprsz(desc); \
106
+ intptr_t ra = GETPC(); \
107
+ unsigned rd = simd_data(desc); \
108
+ void *d1 = &env->vfp.zregs[rd]; \
109
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
110
+ for (i = 0; i < oprsz; ) { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ if (pg & 1) { \
114
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
115
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
116
+ FN(env, addr, m1, ra); \
117
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
118
+ } \
119
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
120
+ addr += 2 * sizeof(TYPEM); \
121
+ } while (i & 15); \
122
+ } \
123
+}
124
+
125
+#define DO_ST3(NAME, FN, TYPEE, TYPEM, H) \
126
+void HELPER(NAME)(CPUARMState *env, void *vg, \
127
+ target_ulong addr, uint32_t desc) \
128
+{ \
129
+ intptr_t i, oprsz = simd_oprsz(desc); \
130
+ intptr_t ra = GETPC(); \
131
+ unsigned rd = simd_data(desc); \
132
+ void *d1 = &env->vfp.zregs[rd]; \
133
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
134
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
135
+ for (i = 0; i < oprsz; ) { \
136
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
137
+ do { \
138
+ if (pg & 1) { \
139
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
140
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
141
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
142
+ FN(env, addr, m1, ra); \
143
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
144
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
145
+ } \
146
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
147
+ addr += 3 * sizeof(TYPEM); \
148
+ } while (i & 15); \
149
+ } \
150
+}
151
+
152
+#define DO_ST4(NAME, FN, TYPEE, TYPEM, H) \
153
+void HELPER(NAME)(CPUARMState *env, void *vg, \
154
+ target_ulong addr, uint32_t desc) \
155
+{ \
156
+ intptr_t i, oprsz = simd_oprsz(desc); \
157
+ intptr_t ra = GETPC(); \
158
+ unsigned rd = simd_data(desc); \
159
+ void *d1 = &env->vfp.zregs[rd]; \
160
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
161
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
162
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
163
+ for (i = 0; i < oprsz; ) { \
164
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
165
+ do { \
166
+ if (pg & 1) { \
167
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
168
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
169
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
170
+ TYPEM m4 = *(TYPEE *)(d4 + H(i)); \
171
+ FN(env, addr, m1, ra); \
172
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
173
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
174
+ FN(env, addr + 3 * sizeof(TYPEM), m4, ra); \
175
+ } \
176
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
177
+ addr += 4 * sizeof(TYPEM); \
178
+ } while (i & 15); \
179
+ } \
180
+}
181
+
182
+DO_ST1(sve_st1bh_r, cpu_stb_data_ra, uint16_t, uint8_t, H1_2)
183
+DO_ST1(sve_st1bs_r, cpu_stb_data_ra, uint32_t, uint8_t, H1_4)
184
+DO_ST1_D(sve_st1bd_r, cpu_stb_data_ra, uint8_t)
185
+
186
+DO_ST1(sve_st1hs_r, cpu_stw_data_ra, uint32_t, uint16_t, H1_4)
187
+DO_ST1_D(sve_st1hd_r, cpu_stw_data_ra, uint16_t)
188
+
189
+DO_ST1_D(sve_st1sd_r, cpu_stl_data_ra, uint32_t)
190
+
191
+DO_ST1(sve_st1bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
192
+DO_ST2(sve_st2bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
193
+DO_ST3(sve_st3bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
194
+DO_ST4(sve_st4bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
195
+
196
+DO_ST1(sve_st1hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
197
+DO_ST2(sve_st2hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
198
+DO_ST3(sve_st3hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
199
+DO_ST4(sve_st4hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
200
+
201
+DO_ST1(sve_st1ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
202
+DO_ST2(sve_st2ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
203
+DO_ST3(sve_st3ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
204
+DO_ST4(sve_st4ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
205
+
206
+DO_ST1_D(sve_st1dd_r, cpu_stq_data_ra, uint64_t)
207
+
208
+void HELPER(sve_st2dd_r)(CPUARMState *env, void *vg,
209
+ target_ulong addr, uint32_t desc)
210
+{
211
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
212
+ intptr_t ra = GETPC();
213
+ unsigned rd = simd_data(desc);
214
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
215
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
216
+ uint8_t *pg = vg;
217
+
218
+ for (i = 0; i < oprsz; i += 1) {
219
+ if (pg[H1(i)] & 1) {
220
+ cpu_stq_data_ra(env, addr, d1[i], ra);
221
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
222
+ }
223
+ addr += 2 * 8;
224
+ }
225
+}
226
+
227
+void HELPER(sve_st3dd_r)(CPUARMState *env, void *vg,
228
+ target_ulong addr, uint32_t desc)
229
+{
230
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
231
+ intptr_t ra = GETPC();
232
+ unsigned rd = simd_data(desc);
233
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
234
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
235
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
236
+ uint8_t *pg = vg;
237
+
238
+ for (i = 0; i < oprsz; i += 1) {
239
+ if (pg[H1(i)] & 1) {
240
+ cpu_stq_data_ra(env, addr, d1[i], ra);
241
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
242
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
243
+ }
244
+ addr += 3 * 8;
245
+ }
246
+}
247
+
248
+void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
249
+ target_ulong addr, uint32_t desc)
250
+{
251
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
252
+ intptr_t ra = GETPC();
253
+ unsigned rd = simd_data(desc);
254
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
255
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
256
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
257
+ uint64_t *d4 = &env->vfp.zregs[(rd + 3) & 31].d[0];
258
+ uint8_t *pg = vg;
259
+
260
+ for (i = 0; i < oprsz; i += 1) {
261
+ if (pg[H1(i)] & 1) {
262
+ cpu_stq_data_ra(env, addr, d1[i], ra);
263
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
264
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
265
+ cpu_stq_data_ra(env, addr + 24, d4[i], ra);
266
+ }
267
+ addr += 4 * 8;
268
+ }
269
+}
270
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/target/arm/translate-sve.c
273
+++ b/target/arm/translate-sve.c
274
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
275
}
276
return true;
277
}
278
+
279
+static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
280
+ int msz, int esz, int nreg)
281
+{
282
+ static gen_helper_gvec_mem * const fn_single[4][4] = {
283
+ { gen_helper_sve_st1bb_r, gen_helper_sve_st1bh_r,
284
+ gen_helper_sve_st1bs_r, gen_helper_sve_st1bd_r },
285
+ { NULL, gen_helper_sve_st1hh_r,
286
+ gen_helper_sve_st1hs_r, gen_helper_sve_st1hd_r },
287
+ { NULL, NULL,
288
+ gen_helper_sve_st1ss_r, gen_helper_sve_st1sd_r },
289
+ { NULL, NULL, NULL, gen_helper_sve_st1dd_r },
290
+ };
291
+ static gen_helper_gvec_mem * const fn_multiple[3][4] = {
292
+ { gen_helper_sve_st2bb_r, gen_helper_sve_st2hh_r,
293
+ gen_helper_sve_st2ss_r, gen_helper_sve_st2dd_r },
294
+ { gen_helper_sve_st3bb_r, gen_helper_sve_st3hh_r,
295
+ gen_helper_sve_st3ss_r, gen_helper_sve_st3dd_r },
296
+ { gen_helper_sve_st4bb_r, gen_helper_sve_st4hh_r,
297
+ gen_helper_sve_st4ss_r, gen_helper_sve_st4dd_r },
298
+ };
299
+ gen_helper_gvec_mem *fn;
300
+
301
+ if (nreg == 0) {
302
+ /* ST1 */
303
+ fn = fn_single[msz][esz];
304
+ } else {
305
+ /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
306
+ assert(msz == esz);
307
+ fn = fn_multiple[nreg - 1][msz];
308
+ }
309
+ assert(fn != NULL);
310
+ do_mem_zpa(s, zt, pg, addr, fn);
311
+}
312
+
313
+static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a, uint32_t insn)
314
+{
315
+ if (a->rm == 31 || a->msz > a->esz) {
316
+ return false;
317
+ }
318
+ if (sve_access_check(s)) {
319
+ TCGv_i64 addr = new_tmp_a64(s);
320
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
321
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
322
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
323
+ }
324
+ return true;
325
+}
326
+
327
+static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a, uint32_t insn)
328
+{
329
+ if (a->msz > a->esz) {
330
+ return false;
331
+ }
332
+ if (sve_access_check(s)) {
333
+ int vsz = vec_full_reg_size(s);
334
+ int elements = vsz >> a->esz;
335
+ TCGv_i64 addr = new_tmp_a64(s);
336
+
337
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
338
+ (a->imm * elements * (a->nreg + 1)) << a->msz);
339
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
340
+ }
341
+ return true;
342
+}
343
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/arm/sve.decode
346
+++ b/target/arm/sve.decode
347
@@ -XXX,XX +XXX,XX @@
348
%imm7_22_16 22:2 16:5
349
%imm8_16_10 16:5 10:3
350
%imm9_16_10 16:s6 10:3
351
+%size_23 23:2
352
353
# A combination of tsz:imm3 -- extract esize.
354
%tszimm_esz 22:2 5:5 !function=tszimm_esz
355
@@ -XXX,XX +XXX,XX @@
356
&incdec2_pred rd rn pg esz d u
357
&rprr_load rd pg rn rm dtype nreg
358
&rpri_load rd pg rn imm dtype nreg
359
+&rprr_store rd pg rn rm msz esz nreg
360
+&rpri_store rd pg rn imm msz esz nreg
361
362
###########################################################################
363
# Named instruction formats. These are generally used to
364
@@ -XXX,XX +XXX,XX @@
365
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
366
&rpri_load dtype=%msz_dtype
367
368
+# Stores; user must fill in ESZ, MSZ, NREG as needed.
369
+@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
370
+@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
371
+@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
372
+ &rprr_store nreg=0
373
+
374
###########################################################################
375
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
376
377
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
378
# SVE load multiple structures (scalar plus immediate)
379
# LD2B, LD2H, LD2W, LD2D; etc.
380
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
381
+
382
+### SVE Memory Store Group
383
+
384
+# SVE contiguous store (scalar plus immediate)
385
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
386
+ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
387
+ @rpri_store_msz nreg=0
388
+
389
+# SVE contiguous store (scalar plus scalar)
390
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
391
+# Enumerate msz lest we conflict with STR_zri.
392
+ST_zprr 1110010 00 .. ..... 010 ... ..... ..... \
393
+ @rprr_store_esz_n0 msz=0
394
+ST_zprr 1110010 01 .. ..... 010 ... ..... ..... \
395
+ @rprr_store_esz_n0 msz=1
396
+ST_zprr 1110010 10 .. ..... 010 ... ..... ..... \
397
+ @rprr_store_esz_n0 msz=2
398
+ST_zprr 1110010 11 11 ..... 010 ... ..... ..... \
399
+ @rprr_store msz=3 esz=3 nreg=0
400
+
401
+# SVE contiguous non-temporal store (scalar plus immediate) (nreg == 0)
402
+# SVE store multiple structures (scalar plus immediate) (nreg != 0)
403
+ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
404
+ @rpri_store_msz esz=%size_23
405
+
406
+# SVE contiguous non-temporal store (scalar plus scalar) (nreg == 0)
407
+# SVE store multiple structures (scalar plus scalar) (nreg != 0)
408
+ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
409
+ @rprr_store esz=%size_23
410
--
411
2.17.1
412
413
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-sve.c | 52 ++++++++++++++++++++++++++++++++++++++
9
target/arm/sve.decode | 9 +++++++
10
2 files changed, 61 insertions(+)
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
17
return true;
18
}
19
20
+static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int msz)
21
+{
22
+ static gen_helper_gvec_mem * const fns[4] = {
23
+ gen_helper_sve_ld1bb_r, gen_helper_sve_ld1hh_r,
24
+ gen_helper_sve_ld1ss_r, gen_helper_sve_ld1dd_r,
25
+ };
26
+ unsigned vsz = vec_full_reg_size(s);
27
+ TCGv_ptr t_pg;
28
+ TCGv_i32 desc;
29
+
30
+ /* Load the first quadword using the normal predicated load helpers. */
31
+ desc = tcg_const_i32(simd_desc(16, 16, zt));
32
+ t_pg = tcg_temp_new_ptr();
33
+
34
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
35
+ fns[msz](cpu_env, t_pg, addr, desc);
36
+
37
+ tcg_temp_free_ptr(t_pg);
38
+ tcg_temp_free_i32(desc);
39
+
40
+ /* Replicate that first quadword. */
41
+ if (vsz > 16) {
42
+ unsigned dofs = vec_full_reg_offset(s, zt);
43
+ tcg_gen_gvec_dup_mem(4, dofs + 16, dofs, vsz - 16, vsz - 16);
44
+ }
45
+}
46
+
47
+static bool trans_LD1RQ_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
48
+{
49
+ if (a->rm == 31) {
50
+ return false;
51
+ }
52
+ if (sve_access_check(s)) {
53
+ int msz = dtype_msz(a->dtype);
54
+ TCGv_i64 addr = new_tmp_a64(s);
55
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), msz);
56
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
57
+ do_ldrq(s, a->rd, a->pg, addr, msz);
58
+ }
59
+ return true;
60
+}
61
+
62
+static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
63
+{
64
+ if (sve_access_check(s)) {
65
+ TCGv_i64 addr = new_tmp_a64(s);
66
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 16);
67
+ do_ldrq(s, a->rd, a->pg, addr, dtype_msz(a->dtype));
68
+ }
69
+ return true;
70
+}
71
+
72
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
73
int msz, int esz, int nreg)
74
{
75
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/sve.decode
78
+++ b/target/arm/sve.decode
79
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
80
# LD2B, LD2H, LD2W, LD2D; etc.
81
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
82
83
+# SVE load and broadcast quadword (scalar plus scalar)
84
+LD1RQ_zprr 1010010 .. 00 ..... 000 ... ..... ..... \
85
+ @rprr_load_msz nreg=0
86
+
87
+# SVE load and broadcast quadword (scalar plus immediate)
88
+# LD1RQB, LD1RQH, LD1RQS, LD1RQD
89
+LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
90
+ @rpri_load_msz nreg=0
91
+
92
### SVE Memory Store Group
93
94
# SVE contiguous store (scalar plus immediate)
95
--
96
2.17.1
97
98
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
[PMM: fixed typo]
6
Message-id: 20180627043328.11531-6-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 30 +++++++++++++
10
target/arm/sve_helper.c | 38 ++++++++++++++++
11
target/arm/translate-sve.c | 90 ++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 22 ++++++++++
13
4 files changed, 180 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve_scvt_dh, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve_scvt_ss, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_scvt_sd, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_scvt_ds, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve_scvt_dd, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_5(sve_ucvt_hh, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve_ucvt_sh, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve_ucvt_dh, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve_ucvt_ss, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve_ucvt_sd, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
49
+ void, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
+
53
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
56
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve_helper.c
59
+++ b/target/arm/sve_helper.c
60
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
61
return predtest_ones(d, oprsz, esz_mask);
62
}
63
64
+/* Fully general two-operand expander, controlled by a predicate,
65
+ * With the extra float_status parameter.
66
+ */
67
+#define DO_ZPZ_FP(NAME, TYPE, H, OP) \
68
+void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
69
+{ \
70
+ intptr_t i = simd_oprsz(desc); \
71
+ uint64_t *g = vg; \
72
+ do { \
73
+ uint64_t pg = g[(i - 1) >> 6]; \
74
+ do { \
75
+ i -= sizeof(TYPE); \
76
+ if (likely((pg >> (i & 63)) & 1)) { \
77
+ TYPE nn = *(TYPE *)(vn + H(i)); \
78
+ *(TYPE *)(vd + H(i)) = OP(nn, status); \
79
+ } \
80
+ } while (i & 63); \
81
+ } while (i != 0); \
82
+}
83
+
84
+DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
85
+DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
86
+DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
87
+DO_ZPZ_FP(sve_scvt_sd, uint64_t, , int32_to_float64)
88
+DO_ZPZ_FP(sve_scvt_dh, uint64_t, , int64_to_float16)
89
+DO_ZPZ_FP(sve_scvt_ds, uint64_t, , int64_to_float32)
90
+DO_ZPZ_FP(sve_scvt_dd, uint64_t, , int64_to_float64)
91
+
92
+DO_ZPZ_FP(sve_ucvt_hh, uint16_t, H1_2, uint16_to_float16)
93
+DO_ZPZ_FP(sve_ucvt_sh, uint32_t, H1_4, uint32_to_float16)
94
+DO_ZPZ_FP(sve_ucvt_ss, uint32_t, H1_4, uint32_to_float32)
95
+DO_ZPZ_FP(sve_ucvt_sd, uint64_t, , uint32_to_float64)
96
+DO_ZPZ_FP(sve_ucvt_dh, uint64_t, , uint64_to_float16)
97
+DO_ZPZ_FP(sve_ucvt_ds, uint64_t, , uint64_to_float32)
98
+DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
99
+
100
+#undef DO_ZPZ_FP
101
+
102
/*
103
* Load contiguous data, protected by a governing predicate.
104
*/
105
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate-sve.c
108
+++ b/target/arm/translate-sve.c
109
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
110
111
#undef DO_FP3
112
113
+
114
+/*
115
+ *** SVE Floating Point Unary Operations Predicated Group
116
+ */
117
+
118
+static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
119
+ bool is_fp16, gen_helper_gvec_3_ptr *fn)
120
+{
121
+ if (sve_access_check(s)) {
122
+ unsigned vsz = vec_full_reg_size(s);
123
+ TCGv_ptr status = get_fpstatus_ptr(is_fp16);
124
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
125
+ vec_full_reg_offset(s, rn),
126
+ pred_full_reg_offset(s, pg),
127
+ status, vsz, vsz, 0, fn);
128
+ tcg_temp_free_ptr(status);
129
+ }
130
+ return true;
131
+}
132
+
133
+static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
134
+{
135
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
136
+}
137
+
138
+static bool trans_SCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
139
+{
140
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_sh);
141
+}
142
+
143
+static bool trans_SCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
144
+{
145
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_dh);
146
+}
147
+
148
+static bool trans_SCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
149
+{
150
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ss);
151
+}
152
+
153
+static bool trans_SCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
154
+{
155
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ds);
156
+}
157
+
158
+static bool trans_SCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
159
+{
160
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_sd);
161
+}
162
+
163
+static bool trans_SCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
164
+{
165
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_dd);
166
+}
167
+
168
+static bool trans_UCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
169
+{
170
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_hh);
171
+}
172
+
173
+static bool trans_UCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
174
+{
175
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_sh);
176
+}
177
+
178
+static bool trans_UCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
179
+{
180
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_dh);
181
+}
182
+
183
+static bool trans_UCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
184
+{
185
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ss);
186
+}
187
+
188
+static bool trans_UCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
189
+{
190
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ds);
191
+}
192
+
193
+static bool trans_UCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
194
+{
195
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_sd);
196
+}
197
+
198
+static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
199
+{
200
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_dd);
201
+}
202
+
203
/*
204
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
205
*/
206
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/sve.decode
209
+++ b/target/arm/sve.decode
210
@@ -XXX,XX +XXX,XX @@
211
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
212
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
213
214
+# One register operand, with governing predicate, no vector element size
215
+@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
216
+
217
# Two register operands with a 6-bit signed immediate.
218
@rd_rn_i6 ........ ... rn:5 ..... imm:s6 rd:5 &rri
219
220
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
221
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
222
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
223
224
+### SVE FP Unary Operations Predicated Group
225
+
226
+# SVE integer convert to floating-point
227
+SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
228
+SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
229
+SCVTF_dh 01100101 01 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
230
+SCVTF_ss 01100101 10 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
231
+SCVTF_sd 01100101 11 010 00 0 101 ... ..... ..... @rd_pg_rn_e0
232
+SCVTF_ds 01100101 11 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
233
+SCVTF_dd 01100101 11 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
234
+
235
+UCVTF_hh 01100101 01 010 01 1 101 ... ..... ..... @rd_pg_rn_e0
236
+UCVTF_sh 01100101 01 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
237
+UCVTF_dh 01100101 01 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
238
+UCVTF_ss 01100101 10 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
239
+UCVTF_sd 01100101 11 010 00 1 101 ... ..... ..... @rd_pg_rn_e0
240
+UCVTF_ds 01100101 11 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
241
+UCVTF_dd 01100101 11 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
242
+
243
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
244
245
# SVE load predicate register
246
--
247
2.17.1
248
249
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 77 +++++++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 89 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 46 ++++++++++++++++++++
11
target/arm/sve.decode | 17 ++++++++
12
4 files changed, 229 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fadd_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fsub_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fsub_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fsub_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fmul_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fmul_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fmul_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fdiv_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fdiv_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fdiv_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fmin_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fmin_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fmin_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_fmax_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_fmax_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_fmax_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_fminnum_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_fminnum_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, ptr, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_fminnum_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, ptr, ptr, i32)
70
+
71
+DEF_HELPER_FLAGS_6(sve_fmaxnum_h, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, ptr, ptr, i32)
73
+DEF_HELPER_FLAGS_6(sve_fmaxnum_s, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, ptr, ptr, i32)
75
+DEF_HELPER_FLAGS_6(sve_fmaxnum_d, TCG_CALL_NO_RWG,
76
+ void, ptr, ptr, ptr, ptr, ptr, i32)
77
+
78
+DEF_HELPER_FLAGS_6(sve_fabd_h, TCG_CALL_NO_RWG,
79
+ void, ptr, ptr, ptr, ptr, ptr, i32)
80
+DEF_HELPER_FLAGS_6(sve_fabd_s, TCG_CALL_NO_RWG,
81
+ void, ptr, ptr, ptr, ptr, ptr, i32)
82
+DEF_HELPER_FLAGS_6(sve_fabd_d, TCG_CALL_NO_RWG,
83
+ void, ptr, ptr, ptr, ptr, ptr, i32)
84
+
85
+DEF_HELPER_FLAGS_6(sve_fscalbn_h, TCG_CALL_NO_RWG,
86
+ void, ptr, ptr, ptr, ptr, ptr, i32)
87
+DEF_HELPER_FLAGS_6(sve_fscalbn_s, TCG_CALL_NO_RWG,
88
+ void, ptr, ptr, ptr, ptr, ptr, i32)
89
+DEF_HELPER_FLAGS_6(sve_fscalbn_d, TCG_CALL_NO_RWG,
90
+ void, ptr, ptr, ptr, ptr, ptr, i32)
91
+
92
+DEF_HELPER_FLAGS_6(sve_fmulx_h, TCG_CALL_NO_RWG,
93
+ void, ptr, ptr, ptr, ptr, ptr, i32)
94
+DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG,
95
+ void, ptr, ptr, ptr, ptr, ptr, i32)
96
+DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG,
97
+ void, ptr, ptr, ptr, ptr, ptr, i32)
98
+
99
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
100
void, ptr, ptr, ptr, ptr, i32)
101
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
102
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/sve_helper.c
105
+++ b/target/arm/sve_helper.c
106
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
107
return predtest_ones(d, oprsz, esz_mask);
108
}
109
110
+/* Fully general three-operand expander, controlled by a predicate,
111
+ * With the extra float_status parameter.
112
+ */
113
+#define DO_ZPZZ_FP(NAME, TYPE, H, OP) \
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
115
+ void *status, uint32_t desc) \
116
+{ \
117
+ intptr_t i = simd_oprsz(desc); \
118
+ uint64_t *g = vg; \
119
+ do { \
120
+ uint64_t pg = g[(i - 1) >> 6]; \
121
+ do { \
122
+ i -= sizeof(TYPE); \
123
+ if (likely((pg >> (i & 63)) & 1)) { \
124
+ TYPE nn = *(TYPE *)(vn + H(i)); \
125
+ TYPE mm = *(TYPE *)(vm + H(i)); \
126
+ *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \
127
+ } \
128
+ } while (i & 63); \
129
+ } while (i != 0); \
130
+}
131
+
132
+DO_ZPZZ_FP(sve_fadd_h, uint16_t, H1_2, float16_add)
133
+DO_ZPZZ_FP(sve_fadd_s, uint32_t, H1_4, float32_add)
134
+DO_ZPZZ_FP(sve_fadd_d, uint64_t, , float64_add)
135
+
136
+DO_ZPZZ_FP(sve_fsub_h, uint16_t, H1_2, float16_sub)
137
+DO_ZPZZ_FP(sve_fsub_s, uint32_t, H1_4, float32_sub)
138
+DO_ZPZZ_FP(sve_fsub_d, uint64_t, , float64_sub)
139
+
140
+DO_ZPZZ_FP(sve_fmul_h, uint16_t, H1_2, float16_mul)
141
+DO_ZPZZ_FP(sve_fmul_s, uint32_t, H1_4, float32_mul)
142
+DO_ZPZZ_FP(sve_fmul_d, uint64_t, , float64_mul)
143
+
144
+DO_ZPZZ_FP(sve_fdiv_h, uint16_t, H1_2, float16_div)
145
+DO_ZPZZ_FP(sve_fdiv_s, uint32_t, H1_4, float32_div)
146
+DO_ZPZZ_FP(sve_fdiv_d, uint64_t, , float64_div)
147
+
148
+DO_ZPZZ_FP(sve_fmin_h, uint16_t, H1_2, float16_min)
149
+DO_ZPZZ_FP(sve_fmin_s, uint32_t, H1_4, float32_min)
150
+DO_ZPZZ_FP(sve_fmin_d, uint64_t, , float64_min)
151
+
152
+DO_ZPZZ_FP(sve_fmax_h, uint16_t, H1_2, float16_max)
153
+DO_ZPZZ_FP(sve_fmax_s, uint32_t, H1_4, float32_max)
154
+DO_ZPZZ_FP(sve_fmax_d, uint64_t, , float64_max)
155
+
156
+DO_ZPZZ_FP(sve_fminnum_h, uint16_t, H1_2, float16_minnum)
157
+DO_ZPZZ_FP(sve_fminnum_s, uint32_t, H1_4, float32_minnum)
158
+DO_ZPZZ_FP(sve_fminnum_d, uint64_t, , float64_minnum)
159
+
160
+DO_ZPZZ_FP(sve_fmaxnum_h, uint16_t, H1_2, float16_maxnum)
161
+DO_ZPZZ_FP(sve_fmaxnum_s, uint32_t, H1_4, float32_maxnum)
162
+DO_ZPZZ_FP(sve_fmaxnum_d, uint64_t, , float64_maxnum)
163
+
164
+static inline float16 abd_h(float16 a, float16 b, float_status *s)
165
+{
166
+ return float16_abs(float16_sub(a, b, s));
167
+}
168
+
169
+static inline float32 abd_s(float32 a, float32 b, float_status *s)
170
+{
171
+ return float32_abs(float32_sub(a, b, s));
172
+}
173
+
174
+static inline float64 abd_d(float64 a, float64 b, float_status *s)
175
+{
176
+ return float64_abs(float64_sub(a, b, s));
177
+}
178
+
179
+DO_ZPZZ_FP(sve_fabd_h, uint16_t, H1_2, abd_h)
180
+DO_ZPZZ_FP(sve_fabd_s, uint32_t, H1_4, abd_s)
181
+DO_ZPZZ_FP(sve_fabd_d, uint64_t, , abd_d)
182
+
183
+static inline float64 scalbn_d(float64 a, int64_t b, float_status *s)
184
+{
185
+ int b_int = MIN(MAX(b, INT_MIN), INT_MAX);
186
+ return float64_scalbn(a, b_int, s);
187
+}
188
+
189
+DO_ZPZZ_FP(sve_fscalbn_h, int16_t, H1_2, float16_scalbn)
190
+DO_ZPZZ_FP(sve_fscalbn_s, int32_t, H1_4, float32_scalbn)
191
+DO_ZPZZ_FP(sve_fscalbn_d, int64_t, , scalbn_d)
192
+
193
+DO_ZPZZ_FP(sve_fmulx_h, uint16_t, H1_2, helper_advsimd_mulxh)
194
+DO_ZPZZ_FP(sve_fmulx_s, uint32_t, H1_4, helper_vfp_mulxs)
195
+DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd)
196
+
197
+#undef DO_ZPZZ_FP
198
+
199
/* Fully general two-operand expander, controlled by a predicate,
200
* With the extra float_status parameter.
201
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/target/arm/translate-sve.c
205
+++ b/target/arm/translate-sve.c
206
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
207
208
#undef DO_FP3
209
210
+/*
211
+ *** SVE Floating Point Arithmetic - Predicated Group
212
+ */
213
+
214
+static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
215
+ gen_helper_gvec_4_ptr *fn)
216
+{
217
+ if (fn == NULL) {
218
+ return false;
219
+ }
220
+ if (sve_access_check(s)) {
221
+ unsigned vsz = vec_full_reg_size(s);
222
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
223
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
224
+ vec_full_reg_offset(s, a->rn),
225
+ vec_full_reg_offset(s, a->rm),
226
+ pred_full_reg_offset(s, a->pg),
227
+ status, vsz, vsz, 0, fn);
228
+ tcg_temp_free_ptr(status);
229
+ }
230
+ return true;
231
+}
232
+
233
+#define DO_FP3(NAME, name) \
234
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a, uint32_t insn) \
235
+{ \
236
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
237
+ NULL, gen_helper_sve_##name##_h, \
238
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
239
+ }; \
240
+ return do_zpzz_fp(s, a, fns[a->esz]); \
241
+}
242
+
243
+DO_FP3(FADD_zpzz, fadd)
244
+DO_FP3(FSUB_zpzz, fsub)
245
+DO_FP3(FMUL_zpzz, fmul)
246
+DO_FP3(FMIN_zpzz, fmin)
247
+DO_FP3(FMAX_zpzz, fmax)
248
+DO_FP3(FMINNM_zpzz, fminnum)
249
+DO_FP3(FMAXNM_zpzz, fmaxnum)
250
+DO_FP3(FABD, fabd)
251
+DO_FP3(FSCALE, fscalbn)
252
+DO_FP3(FDIV, fdiv)
253
+DO_FP3(FMULX, fmulx)
254
+
255
+#undef DO_FP3
256
257
/*
258
*** SVE Floating Point Unary Operations Predicated Group
259
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/arm/sve.decode
262
+++ b/target/arm/sve.decode
263
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
264
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
265
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
266
267
+### SVE FP Arithmetic Predicated Group
268
+
269
+# SVE floating-point arithmetic (predicated)
270
+FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
271
+FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
272
+FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
273
+FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR
274
+FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
275
+FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
276
+FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
277
+FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
278
+FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm
279
+FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm
280
+FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
281
+FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
282
+FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
283
+
284
### SVE FP Unary Operations Predicated Group
285
286
# SVE integer convert to floating-point
287
--
288
2.17.1
289
290
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-8-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 16 ++++
10
target/arm/sve_helper.c | 158 +++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 49 ++++++++++++
12
target/arm/sve.decode | 18 +++++
13
4 files changed, 241 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
28
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
29
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
33
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
37
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
38
+
39
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve_helper.c
45
+++ b/target/arm/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
47
48
#undef DO_ZPZ_FP
49
50
+/* 4-operand predicated multiply-add. This requires 7 operands to pass
51
+ * "properly", so we need to encode some of the registers into DESC.
52
+ */
53
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 20 > 32);
54
+
55
+static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
56
+ uint16_t neg1, uint16_t neg3)
57
+{
58
+ intptr_t i = simd_oprsz(desc);
59
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
60
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
61
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
62
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
63
+ void *vd = &env->vfp.zregs[rd];
64
+ void *vn = &env->vfp.zregs[rn];
65
+ void *vm = &env->vfp.zregs[rm];
66
+ void *va = &env->vfp.zregs[ra];
67
+ uint64_t *g = vg;
68
+
69
+ do {
70
+ uint64_t pg = g[(i - 1) >> 6];
71
+ do {
72
+ i -= 2;
73
+ if (likely((pg >> (i & 63)) & 1)) {
74
+ float16 e1, e2, e3, r;
75
+
76
+ e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
77
+ e2 = *(uint16_t *)(vm + H1_2(i));
78
+ e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
79
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
80
+ *(uint16_t *)(vd + H1_2(i)) = r;
81
+ }
82
+ } while (i & 63);
83
+ } while (i != 0);
84
+}
85
+
86
+void HELPER(sve_fmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
87
+{
88
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0);
89
+}
90
+
91
+void HELPER(sve_fmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
92
+{
93
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0);
94
+}
95
+
96
+void HELPER(sve_fnmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
97
+{
98
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0x8000);
99
+}
100
+
101
+void HELPER(sve_fnmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
102
+{
103
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0x8000);
104
+}
105
+
106
+static void do_fmla_zpzzz_s(CPUARMState *env, void *vg, uint32_t desc,
107
+ uint32_t neg1, uint32_t neg3)
108
+{
109
+ intptr_t i = simd_oprsz(desc);
110
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
111
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
112
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
113
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
114
+ void *vd = &env->vfp.zregs[rd];
115
+ void *vn = &env->vfp.zregs[rn];
116
+ void *vm = &env->vfp.zregs[rm];
117
+ void *va = &env->vfp.zregs[ra];
118
+ uint64_t *g = vg;
119
+
120
+ do {
121
+ uint64_t pg = g[(i - 1) >> 6];
122
+ do {
123
+ i -= 4;
124
+ if (likely((pg >> (i & 63)) & 1)) {
125
+ float32 e1, e2, e3, r;
126
+
127
+ e1 = *(uint32_t *)(vn + H1_4(i)) ^ neg1;
128
+ e2 = *(uint32_t *)(vm + H1_4(i));
129
+ e3 = *(uint32_t *)(va + H1_4(i)) ^ neg3;
130
+ r = float32_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
131
+ *(uint32_t *)(vd + H1_4(i)) = r;
132
+ }
133
+ } while (i & 63);
134
+ } while (i != 0);
135
+}
136
+
137
+void HELPER(sve_fmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
138
+{
139
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0);
140
+}
141
+
142
+void HELPER(sve_fmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
143
+{
144
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0);
145
+}
146
+
147
+void HELPER(sve_fnmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
148
+{
149
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0x80000000);
150
+}
151
+
152
+void HELPER(sve_fnmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
153
+{
154
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0x80000000);
155
+}
156
+
157
+static void do_fmla_zpzzz_d(CPUARMState *env, void *vg, uint32_t desc,
158
+ uint64_t neg1, uint64_t neg3)
159
+{
160
+ intptr_t i = simd_oprsz(desc);
161
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
162
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
163
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
164
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
165
+ void *vd = &env->vfp.zregs[rd];
166
+ void *vn = &env->vfp.zregs[rn];
167
+ void *vm = &env->vfp.zregs[rm];
168
+ void *va = &env->vfp.zregs[ra];
169
+ uint64_t *g = vg;
170
+
171
+ do {
172
+ uint64_t pg = g[(i - 1) >> 6];
173
+ do {
174
+ i -= 8;
175
+ if (likely((pg >> (i & 63)) & 1)) {
176
+ float64 e1, e2, e3, r;
177
+
178
+ e1 = *(uint64_t *)(vn + i) ^ neg1;
179
+ e2 = *(uint64_t *)(vm + i);
180
+ e3 = *(uint64_t *)(va + i) ^ neg3;
181
+ r = float64_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
182
+ *(uint64_t *)(vd + i) = r;
183
+ }
184
+ } while (i & 63);
185
+ } while (i != 0);
186
+}
187
+
188
+void HELPER(sve_fmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
189
+{
190
+ do_fmla_zpzzz_d(env, vg, desc, 0, 0);
191
+}
192
+
193
+void HELPER(sve_fmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
194
+{
195
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, 0);
196
+}
197
+
198
+void HELPER(sve_fnmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
199
+{
200
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, INT64_MIN);
201
+}
202
+
203
+void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
204
+{
205
+ do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
206
+}
207
+
208
/*
209
* Load contiguous data, protected by a governing predicate.
210
*/
211
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate-sve.c
214
+++ b/target/arm/translate-sve.c
215
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
216
217
#undef DO_FP3
218
219
+typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
220
+
221
+static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
222
+{
223
+ if (fn == NULL) {
224
+ return false;
225
+ }
226
+ if (!sve_access_check(s)) {
227
+ return true;
228
+ }
229
+
230
+ unsigned vsz = vec_full_reg_size(s);
231
+ unsigned desc;
232
+ TCGv_i32 t_desc;
233
+ TCGv_ptr pg = tcg_temp_new_ptr();
234
+
235
+ /* We would need 7 operands to pass these arguments "properly".
236
+ * So we encode all the register numbers into the descriptor.
237
+ */
238
+ desc = deposit32(a->rd, 5, 5, a->rn);
239
+ desc = deposit32(desc, 10, 5, a->rm);
240
+ desc = deposit32(desc, 15, 5, a->ra);
241
+ desc = simd_desc(vsz, vsz, desc);
242
+
243
+ t_desc = tcg_const_i32(desc);
244
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
245
+ fn(cpu_env, pg, t_desc);
246
+ tcg_temp_free_i32(t_desc);
247
+ tcg_temp_free_ptr(pg);
248
+ return true;
249
+}
250
+
251
+#define DO_FMLA(NAME, name) \
252
+static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a, uint32_t insn) \
253
+{ \
254
+ static gen_helper_sve_fmla * const fns[4] = { \
255
+ NULL, gen_helper_sve_##name##_h, \
256
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
257
+ }; \
258
+ return do_fmla(s, a, fns[a->esz]); \
259
+}
260
+
261
+DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
262
+DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
263
+DO_FMLA(FNMLA_zpzzz, fnmla_zpzzz)
264
+DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
265
+
266
+#undef DO_FMLA
267
+
268
/*
269
*** SVE Floating Point Unary Operations Predicated Group
270
*/
271
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
272
index XXXXXXX..XXXXXXX 100644
273
--- a/target/arm/sve.decode
274
+++ b/target/arm/sve.decode
275
@@ -XXX,XX +XXX,XX @@
276
&rprrr_esz ra=%reg_movprfx
277
@rdn_pg_ra_rm ........ esz:2 . rm:5 ... pg:3 ra:5 rd:5 \
278
&rprrr_esz rn=%reg_movprfx
279
+@rdn_pg_rm_ra ........ esz:2 . ra:5 ... pg:3 rm:5 rd:5 \
280
+ &rprrr_esz rn=%reg_movprfx
281
282
# One register operand, with governing predicate, vector element size
283
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
284
@@ -XXX,XX +XXX,XX @@ FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
285
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
286
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
287
288
+### SVE FP Multiply-Add Group
289
+
290
+# SVE floating-point multiply-accumulate writing addend
291
+FMLA_zpzzz 01100101 .. 1 ..... 000 ... ..... ..... @rda_pg_rn_rm
292
+FMLS_zpzzz 01100101 .. 1 ..... 001 ... ..... ..... @rda_pg_rn_rm
293
+FNMLA_zpzzz 01100101 .. 1 ..... 010 ... ..... ..... @rda_pg_rn_rm
294
+FNMLS_zpzzz 01100101 .. 1 ..... 011 ... ..... ..... @rda_pg_rn_rm
295
+
296
+# SVE floating-point multiply-accumulate writing multiplicand
297
+# Alter the operand extraction order and reuse the helpers from above.
298
+# FMAD, FMSB, FNMAD, FNMS
299
+FMLA_zpzzz 01100101 .. 1 ..... 100 ... ..... ..... @rdn_pg_rm_ra
300
+FMLS_zpzzz 01100101 .. 1 ..... 101 ... ..... ..... @rdn_pg_rm_ra
301
+FNMLA_zpzzz 01100101 .. 1 ..... 110 ... ..... ..... @rdn_pg_rm_ra
302
+FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
303
+
304
### SVE FP Unary Operations Predicated Group
305
306
# SVE integer convert to floating-point
307
--
308
2.17.1
309
310
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 41 +++++++++++++++++++++
9
target/arm/sve_helper.c | 61 +++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 39 ++++++++++++++++++++
12
4 files changed, 216 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
+
23
+DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_6(sve_stss_zsu, TCG_CALL_NO_WG,
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+
30
+DEF_HELPER_FLAGS_6(sve_stbs_zss, TCG_CALL_NO_WG,
31
+ void, env, ptr, ptr, ptr, tl, i32)
32
+DEF_HELPER_FLAGS_6(sve_sths_zss, TCG_CALL_NO_WG,
33
+ void, env, ptr, ptr, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_6(sve_stss_zss, TCG_CALL_NO_WG,
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+
37
+DEF_HELPER_FLAGS_6(sve_stbd_zsu, TCG_CALL_NO_WG,
38
+ void, env, ptr, ptr, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_6(sve_sthd_zsu, TCG_CALL_NO_WG,
40
+ void, env, ptr, ptr, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_6(sve_stsd_zsu, TCG_CALL_NO_WG,
42
+ void, env, ptr, ptr, ptr, tl, i32)
43
+DEF_HELPER_FLAGS_6(sve_stdd_zsu, TCG_CALL_NO_WG,
44
+ void, env, ptr, ptr, ptr, tl, i32)
45
+
46
+DEF_HELPER_FLAGS_6(sve_stbd_zss, TCG_CALL_NO_WG,
47
+ void, env, ptr, ptr, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_6(sve_sthd_zss, TCG_CALL_NO_WG,
49
+ void, env, ptr, ptr, ptr, tl, i32)
50
+DEF_HELPER_FLAGS_6(sve_stsd_zss, TCG_CALL_NO_WG,
51
+ void, env, ptr, ptr, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_6(sve_stdd_zss, TCG_CALL_NO_WG,
53
+ void, env, ptr, ptr, ptr, tl, i32)
54
+
55
+DEF_HELPER_FLAGS_6(sve_stbd_zd, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_6(sve_sthd_zd, TCG_CALL_NO_WG,
58
+ void, env, ptr, ptr, ptr, tl, i32)
59
+DEF_HELPER_FLAGS_6(sve_stsd_zd, TCG_CALL_NO_WG,
60
+ void, env, ptr, ptr, ptr, tl, i32)
61
+DEF_HELPER_FLAGS_6(sve_stdd_zd, TCG_CALL_NO_WG,
62
+ void, env, ptr, ptr, ptr, tl, i32)
63
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/sve_helper.c
66
+++ b/target/arm/sve_helper.c
67
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
68
addr += 4 * 8;
69
}
70
}
71
+
72
+/* Stores with a vector index. */
73
+
74
+#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
75
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
76
+ target_ulong base, uint32_t desc) \
77
+{ \
78
+ intptr_t i, oprsz = simd_oprsz(desc); \
79
+ unsigned scale = simd_data(desc); \
80
+ uintptr_t ra = GETPC(); \
81
+ for (i = 0; i < oprsz; ) { \
82
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
83
+ do { \
84
+ if (likely(pg & 1)) { \
85
+ target_ulong off = *(TYPEI *)(vm + H1_4(i)); \
86
+ uint32_t d = *(uint32_t *)(vd + H1_4(i)); \
87
+ FN(env, base + (off << scale), d, ra); \
88
+ } \
89
+ i += sizeof(uint32_t), pg >>= sizeof(uint32_t); \
90
+ } while (i & 15); \
91
+ } \
92
+}
93
+
94
+#define DO_ST1_ZPZ_D(NAME, TYPEI, FN) \
95
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
96
+ target_ulong base, uint32_t desc) \
97
+{ \
98
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
99
+ unsigned scale = simd_data(desc); \
100
+ uintptr_t ra = GETPC(); \
101
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
102
+ for (i = 0; i < oprsz; i++) { \
103
+ if (likely(pg[H1(i)] & 1)) { \
104
+ target_ulong off = (target_ulong)(TYPEI)m[i] << scale; \
105
+ FN(env, base + off, d[i], ra); \
106
+ } \
107
+ } \
108
+}
109
+
110
+DO_ST1_ZPZ_S(sve_stbs_zsu, uint32_t, cpu_stb_data_ra)
111
+DO_ST1_ZPZ_S(sve_sths_zsu, uint32_t, cpu_stw_data_ra)
112
+DO_ST1_ZPZ_S(sve_stss_zsu, uint32_t, cpu_stl_data_ra)
113
+
114
+DO_ST1_ZPZ_S(sve_stbs_zss, int32_t, cpu_stb_data_ra)
115
+DO_ST1_ZPZ_S(sve_sths_zss, int32_t, cpu_stw_data_ra)
116
+DO_ST1_ZPZ_S(sve_stss_zss, int32_t, cpu_stl_data_ra)
117
+
118
+DO_ST1_ZPZ_D(sve_stbd_zsu, uint32_t, cpu_stb_data_ra)
119
+DO_ST1_ZPZ_D(sve_sthd_zsu, uint32_t, cpu_stw_data_ra)
120
+DO_ST1_ZPZ_D(sve_stsd_zsu, uint32_t, cpu_stl_data_ra)
121
+DO_ST1_ZPZ_D(sve_stdd_zsu, uint32_t, cpu_stq_data_ra)
122
+
123
+DO_ST1_ZPZ_D(sve_stbd_zss, int32_t, cpu_stb_data_ra)
124
+DO_ST1_ZPZ_D(sve_sthd_zss, int32_t, cpu_stw_data_ra)
125
+DO_ST1_ZPZ_D(sve_stsd_zss, int32_t, cpu_stl_data_ra)
126
+DO_ST1_ZPZ_D(sve_stdd_zss, int32_t, cpu_stq_data_ra)
127
+
128
+DO_ST1_ZPZ_D(sve_stbd_zd, uint64_t, cpu_stb_data_ra)
129
+DO_ST1_ZPZ_D(sve_sthd_zd, uint64_t, cpu_stw_data_ra)
130
+DO_ST1_ZPZ_D(sve_stsd_zd, uint64_t, cpu_stl_data_ra)
131
+DO_ST1_ZPZ_D(sve_stdd_zd, uint64_t, cpu_stq_data_ra)
132
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-sve.c
135
+++ b/target/arm/translate-sve.c
136
@@ -XXX,XX +XXX,XX @@ typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
137
TCGv_ptr, TCGv_ptr, TCGv_i32);
138
139
typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32);
140
+typedef void gen_helper_gvec_mem_scatter(TCGv_env, TCGv_ptr, TCGv_ptr,
141
+ TCGv_ptr, TCGv_i64, TCGv_i32);
142
143
/*
144
* Helpers for extracting complex instruction fields.
145
@@ -XXX,XX +XXX,XX @@ static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a, uint32_t insn)
146
}
147
return true;
148
}
149
+
150
+/*
151
+ *** SVE gather loads / scatter stores
152
+ */
153
+
154
+static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
155
+ TCGv_i64 scalar, gen_helper_gvec_mem_scatter *fn)
156
+{
157
+ unsigned vsz = vec_full_reg_size(s);
158
+ TCGv_i32 desc = tcg_const_i32(simd_desc(vsz, vsz, scale));
159
+ TCGv_ptr t_zm = tcg_temp_new_ptr();
160
+ TCGv_ptr t_pg = tcg_temp_new_ptr();
161
+ TCGv_ptr t_zt = tcg_temp_new_ptr();
162
+
163
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
164
+ tcg_gen_addi_ptr(t_zm, cpu_env, vec_full_reg_offset(s, zm));
165
+ tcg_gen_addi_ptr(t_zt, cpu_env, vec_full_reg_offset(s, zt));
166
+ fn(cpu_env, t_zt, t_pg, t_zm, scalar, desc);
167
+
168
+ tcg_temp_free_ptr(t_zt);
169
+ tcg_temp_free_ptr(t_zm);
170
+ tcg_temp_free_ptr(t_pg);
171
+ tcg_temp_free_i32(desc);
172
+}
173
+
174
+static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
175
+{
176
+ /* Indexed by [xs][msz]. */
177
+ static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
178
+ { gen_helper_sve_stbs_zsu,
179
+ gen_helper_sve_sths_zsu,
180
+ gen_helper_sve_stss_zsu, },
181
+ { gen_helper_sve_stbs_zss,
182
+ gen_helper_sve_sths_zss,
183
+ gen_helper_sve_stss_zss, },
184
+ };
185
+ /* Note that we overload xs=2 to indicate 64-bit offset. */
186
+ static gen_helper_gvec_mem_scatter * const fn64[3][4] = {
187
+ { gen_helper_sve_stbd_zsu,
188
+ gen_helper_sve_sthd_zsu,
189
+ gen_helper_sve_stsd_zsu,
190
+ gen_helper_sve_stdd_zsu, },
191
+ { gen_helper_sve_stbd_zss,
192
+ gen_helper_sve_sthd_zss,
193
+ gen_helper_sve_stsd_zss,
194
+ gen_helper_sve_stdd_zss, },
195
+ { gen_helper_sve_stbd_zd,
196
+ gen_helper_sve_sthd_zd,
197
+ gen_helper_sve_stsd_zd,
198
+ gen_helper_sve_stdd_zd, },
199
+ };
200
+ gen_helper_gvec_mem_scatter *fn;
201
+
202
+ if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
203
+ return false;
204
+ }
205
+ if (!sve_access_check(s)) {
206
+ return true;
207
+ }
208
+ switch (a->esz) {
209
+ case MO_32:
210
+ fn = fn32[a->xs][a->msz];
211
+ break;
212
+ case MO_64:
213
+ fn = fn64[a->xs][a->msz];
214
+ break;
215
+ default:
216
+ g_assert_not_reached();
217
+ }
218
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
219
+ cpu_reg_sp(s, a->rn), fn);
220
+ return true;
221
+}
222
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
223
index XXXXXXX..XXXXXXX 100644
224
--- a/target/arm/sve.decode
225
+++ b/target/arm/sve.decode
226
@@ -XXX,XX +XXX,XX @@
227
&rpri_load rd pg rn imm dtype nreg
228
&rprr_store rd pg rn rm msz esz nreg
229
&rpri_store rd pg rn imm msz esz nreg
230
+&rprr_scatter_store rd pg rn rm esz msz xs scale
231
232
###########################################################################
233
# Named instruction formats. These are generally used to
234
@@ -XXX,XX +XXX,XX @@
235
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
236
@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
237
&rprr_store nreg=0
238
+@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
239
+ &rprr_scatter_store
240
241
###########################################################################
242
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
243
@@ -XXX,XX +XXX,XX @@ ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
244
# SVE store multiple structures (scalar plus scalar) (nreg != 0)
245
ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
246
@rprr_store esz=%size_23
247
+
248
+# SVE 32-bit scatter store (scalar plus 32-bit scaled offsets)
249
+# Require msz > 0 && msz <= esz.
250
+ST1_zprz 1110010 .. 11 ..... 100 ... ..... ..... \
251
+ @rprr_scatter_store xs=0 esz=2 scale=1
252
+ST1_zprz 1110010 .. 11 ..... 110 ... ..... ..... \
253
+ @rprr_scatter_store xs=1 esz=2 scale=1
254
+
255
+# SVE 32-bit scatter store (scalar plus 32-bit unscaled offsets)
256
+# Require msz <= esz.
257
+ST1_zprz 1110010 .. 10 ..... 100 ... ..... ..... \
258
+ @rprr_scatter_store xs=0 esz=2 scale=0
259
+ST1_zprz 1110010 .. 10 ..... 110 ... ..... ..... \
260
+ @rprr_scatter_store xs=1 esz=2 scale=0
261
+
262
+# SVE 64-bit scatter store (scalar plus 64-bit scaled offset)
263
+# Require msz > 0
264
+ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
265
+ @rprr_scatter_store xs=2 esz=3 scale=1
266
+
267
+# SVE 64-bit scatter store (scalar plus 64-bit unscaled offset)
268
+ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
269
+ @rprr_scatter_store xs=2 esz=3 scale=0
270
+
271
+# SVE 64-bit scatter store (scalar plus unpacked 32-bit scaled offset)
272
+# Require msz > 0
273
+ST1_zprz 1110010 .. 01 ..... 100 ... ..... ..... \
274
+ @rprr_scatter_store xs=0 esz=3 scale=1
275
+ST1_zprz 1110010 .. 01 ..... 110 ... ..... ..... \
276
+ @rprr_scatter_store xs=1 esz=3 scale=1
277
+
278
+# SVE 64-bit scatter store (scalar plus unpacked 32-bit unscaled offset)
279
+ST1_zprz 1110010 .. 00 ..... 100 ... ..... ..... \
280
+ @rprr_scatter_store xs=0 esz=3 scale=0
281
+ST1_zprz 1110010 .. 00 ..... 110 ... ..... ..... \
282
+ @rprr_scatter_store xs=1 esz=3 scale=0
283
--
284
2.17.1
285
286
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-sve.c | 21 +++++++++++++++++++++
9
target/arm/sve.decode | 23 +++++++++++++++++++++++
10
2 files changed, 44 insertions(+)
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
17
cpu_reg_sp(s, a->rn), fn);
18
return true;
19
}
20
+
21
+/*
22
+ * Prefetches
23
+ */
24
+
25
+static bool trans_PRF(DisasContext *s, arg_PRF *a, uint32_t insn)
26
+{
27
+ /* Prefetch is a nop within QEMU. */
28
+ sve_access_check(s);
29
+ return true;
30
+}
31
+
32
+static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
33
+{
34
+ if (a->rm == 31) {
35
+ return false;
36
+ }
37
+ /* Prefetch is a nop within QEMU. */
38
+ sve_access_check(s);
39
+ return true;
40
+}
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
44
+++ b/target/arm/sve.decode
45
@@ -XXX,XX +XXX,XX @@ LD1RQ_zprr 1010010 .. 00 ..... 000 ... ..... ..... \
46
LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
47
@rpri_load_msz nreg=0
48
49
+# SVE 32-bit gather prefetch (scalar plus 32-bit scaled offsets)
50
+PRF 1000010 00 -1 ----- 0-- --- ----- 0 ----
51
+
52
+# SVE 32-bit gather prefetch (vector plus immediate)
53
+PRF 1000010 -- 00 ----- 111 --- ----- 0 ----
54
+
55
+# SVE contiguous prefetch (scalar plus immediate)
56
+PRF 1000010 11 1- ----- 0-- --- ----- 0 ----
57
+
58
+# SVE contiguous prefetch (scalar plus scalar)
59
+PRF_rr 1000010 -- 00 rm:5 110 --- ----- 0 ----
60
+
61
+### SVE Memory 64-bit Gather Group
62
+
63
+# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
64
+PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
65
+
66
+# SVE 64-bit gather prefetch (scalar plus unpacked 32-bit scaled offsets)
67
+PRF 1100010 00 -1 ----- 0-- --- ----- 0 ----
68
+
69
+# SVE 64-bit gather prefetch (vector plus immediate)
70
+PRF 1100010 -- 00 ----- 111 --- ----- 0 ----
71
+
72
### SVE Memory Store Group
73
74
# SVE store predicate register
75
--
76
2.17.1
77
78
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add the remaining devices (or unimplemented-device stubs) for
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
2
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
7
---
8
---
8
target/arm/translate-sve.c | 85 ++++++++++++++++++++++++++------------
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
target/arm/sve.decode | 11 +++++
10
1 file changed, 74 insertions(+)
10
2 files changed, 70 insertions(+), 26 deletions(-)
11
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
14
--- a/hw/arm/mps3r.c
15
+++ b/target/arm/translate-sve.c
15
+++ b/hw/arm/mps3r.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@
17
return true;
17
#include "hw/char/cmsdk-apb-uart.h"
18
}
18
#include "hw/i2c/arm_sbcon_i2c.h"
19
19
#include "hw/intc/arm_gicv3.h"
20
+/* Indexed by [xs][msz]. */
20
+#include "hw/misc/mps2-scc.h"
21
+static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][3] = {
21
+#include "hw/misc/mps2-fpgaio.h"
22
+ { gen_helper_sve_stbs_zsu,
22
#include "hw/misc/unimp.h"
23
+ gen_helper_sve_sths_zsu,
23
+#include "hw/net/lan9118.h"
24
+ gen_helper_sve_stss_zsu, },
24
+#include "hw/rtc/pl031.h"
25
+ { gen_helper_sve_stbs_zss,
25
+#include "hw/ssi/pl022.h"
26
+ gen_helper_sve_sths_zss,
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
+ gen_helper_sve_stss_zss, },
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
28
+};
53
+};
29
+
54
+
30
+/* Note that we overload xs=2 to indicate 64-bit offset. */
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
31
+static gen_helper_gvec_mem_scatter * const scatter_store_fn64[3][4] = {
56
const RAMInfo *raminfo)
32
+ { gen_helper_sve_stbd_zsu,
57
{
33
+ gen_helper_sve_sthd_zsu,
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
34
+ gen_helper_sve_stsd_zsu,
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
35
+ gen_helper_sve_stdd_zsu, },
60
MemoryRegion *sysmem = get_system_memory();
36
+ { gen_helper_sve_stbd_zss,
61
DeviceState *gicdev;
37
+ gen_helper_sve_sthd_zss,
62
+ QList *oscclk;
38
+ gen_helper_sve_stsd_zss,
63
39
+ gen_helper_sve_stdd_zss, },
64
mms->clk = clock_new(OBJECT(machine), "CLK");
40
+ { gen_helper_sve_stbd_zd,
65
clock_set_hz(mms->clk, CLK_FRQ);
41
+ gen_helper_sve_sthd_zd,
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
42
+ gen_helper_sve_stsd_zd,
67
}
43
+ gen_helper_sve_stdd_zd, },
68
}
44
+};
69
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
45
+
73
+
46
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
47
{
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
48
- /* Indexed by [xs][msz]. */
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
49
- static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
50
- { gen_helper_sve_stbs_zsu,
78
+ qdev_get_gpio_in(gicdev, 22 + i));
51
- gen_helper_sve_sths_zsu,
52
- gen_helper_sve_stss_zsu, },
53
- { gen_helper_sve_stbs_zss,
54
- gen_helper_sve_sths_zss,
55
- gen_helper_sve_stss_zss, },
56
- };
57
- /* Note that we overload xs=2 to indicate 64-bit offset. */
58
- static gen_helper_gvec_mem_scatter * const fn64[3][4] = {
59
- { gen_helper_sve_stbd_zsu,
60
- gen_helper_sve_sthd_zsu,
61
- gen_helper_sve_stsd_zsu,
62
- gen_helper_sve_stdd_zsu, },
63
- { gen_helper_sve_stbd_zss,
64
- gen_helper_sve_sthd_zss,
65
- gen_helper_sve_stsd_zss,
66
- gen_helper_sve_stdd_zss, },
67
- { gen_helper_sve_stbd_zd,
68
- gen_helper_sve_sthd_zd,
69
- gen_helper_sve_stsd_zd,
70
- gen_helper_sve_stdd_zd, },
71
- };
72
gen_helper_gvec_mem_scatter *fn;
73
74
if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
75
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
76
}
77
switch (a->esz) {
78
case MO_32:
79
- fn = fn32[a->xs][a->msz];
80
+ fn = scatter_store_fn32[a->xs][a->msz];
81
break;
82
case MO_64:
83
- fn = fn64[a->xs][a->msz];
84
+ fn = scatter_store_fn64[a->xs][a->msz];
85
break;
86
default:
87
g_assert_not_reached();
88
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
89
return true;
90
}
91
92
+static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a, uint32_t insn)
93
+{
94
+ gen_helper_gvec_mem_scatter *fn = NULL;
95
+ TCGv_i64 imm;
96
+
97
+ if (a->esz < a->msz) {
98
+ return false;
99
+ }
100
+ if (!sve_access_check(s)) {
101
+ return true;
102
+ }
79
+ }
103
+
80
+
104
+ switch (a->esz) {
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
105
+ case MO_32:
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
106
+ fn = scatter_store_fn32[0][a->msz];
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
107
+ break;
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
108
+ case MO_64:
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
109
+ fn = scatter_store_fn64[2][a->msz];
86
+ oscclk = qlist_new();
110
+ break;
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
111
+ }
89
+ }
112
+ assert(fn != NULL);
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
113
+
93
+
114
+ /* Treat ST1_zpiz (zn[x] + imm) the same way as ST1_zprz (rn + zm[x])
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
115
+ * by loading the immediate into the scalar parameter.
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
116
+ */
117
+ imm = tcg_const_i64(a->imm << a->msz);
117
+ lan9118_init(0xe0300000,
118
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
118
+ qdev_get_gpio_in(gicdev, 18));
119
+ tcg_temp_free_i64(imm);
120
+ return true;
121
+}
122
+
119
+
123
/*
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
124
* Prefetches
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
125
*/
126
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/sve.decode
129
+++ b/target/arm/sve.decode
130
@@ -XXX,XX +XXX,XX @@
131
&rprr_gather_load rd pg rn rm esz msz u ff xs scale
132
&rpri_gather_load rd pg rn imm esz msz u ff
133
&rprr_scatter_store rd pg rn rm esz msz xs scale
134
+&rpri_scatter_store rd pg rn imm esz msz
135
136
###########################################################################
137
# Named instruction formats. These are generally used to
138
@@ -XXX,XX +XXX,XX @@
139
&rprr_store nreg=0
140
@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
141
&rprr_scatter_store
142
+@rpri_scatter_store ....... msz:2 .. imm:5 ... pg:3 rn:5 rd:5 \
143
+ &rpri_scatter_store
144
145
###########################################################################
146
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
147
@@ -XXX,XX +XXX,XX @@ ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
148
ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
149
@rprr_scatter_store xs=2 esz=3 scale=0
150
151
+# SVE 64-bit scatter store (vector plus immediate)
152
+ST1_zpiz 1110010 .. 10 ..... 101 ... ..... ..... \
153
+ @rpri_scatter_store esz=3
154
+
122
+
155
+# SVE 32-bit scatter store (vector plus immediate)
123
mms->bootinfo.ram_size = machine->ram_size;
156
+ST1_zpiz 1110010 .. 11 ..... 101 ... ..... ..... \
124
mms->bootinfo.board_id = -1;
157
+ @rpri_scatter_store esz=2
125
mms->bootinfo.loader_start = mmc->loader_start;
158
+
159
# SVE 64-bit scatter store (scalar plus unpacked 32-bit scaled offset)
160
# Require msz > 0
161
ST1_zprz 1110010 .. 01 ..... 100 ... ..... ..... \
162
--
126
--
163
2.17.1
127
2.34.1
164
128
165
129
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 49 ++++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 62 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 40 ++++++++++++++++++++++++
11
target/arm/sve.decode | 11 +++++++
12
4 files changed, 162 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fcmge_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fcmge_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fcmge_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fcmgt_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fcmgt_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fcmgt_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fcmeq_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fcmeq_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fcmeq_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fcmne_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fcmne_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fcmne_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fcmuo_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fcmuo_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fcmuo_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_facge_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_facge_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_facge_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_facgt_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, ptr, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, ptr, ptr, i32)
70
+
71
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
72
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
73
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
74
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/sve_helper.c
77
+++ b/target/arm/sve_helper.c
78
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
79
do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
80
}
81
82
+/* Two operand floating-point comparison controlled by a predicate.
83
+ * Unlike the integer version, we are not allowed to optimistically
84
+ * compare operands, since the comparison may have side effects wrt
85
+ * the FPSR.
86
+ */
87
+#define DO_FPCMP_PPZZ(NAME, TYPE, H, OP) \
88
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
89
+ void *status, uint32_t desc) \
90
+{ \
91
+ intptr_t i = simd_oprsz(desc), j = (i - 1) >> 6; \
92
+ uint64_t *d = vd, *g = vg; \
93
+ do { \
94
+ uint64_t out = 0, pg = g[j]; \
95
+ do { \
96
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
97
+ if (likely((pg >> (i & 63)) & 1)) { \
98
+ TYPE nn = *(TYPE *)(vn + H(i)); \
99
+ TYPE mm = *(TYPE *)(vm + H(i)); \
100
+ out |= OP(TYPE, nn, mm, status); \
101
+ } \
102
+ } while (i & 63); \
103
+ d[j--] = out; \
104
+ } while (i > 0); \
105
+}
106
+
107
+#define DO_FPCMP_PPZZ_H(NAME, OP) \
108
+ DO_FPCMP_PPZZ(NAME##_h, float16, H1_2, OP)
109
+#define DO_FPCMP_PPZZ_S(NAME, OP) \
110
+ DO_FPCMP_PPZZ(NAME##_s, float32, H1_4, OP)
111
+#define DO_FPCMP_PPZZ_D(NAME, OP) \
112
+ DO_FPCMP_PPZZ(NAME##_d, float64, , OP)
113
+
114
+#define DO_FPCMP_PPZZ_ALL(NAME, OP) \
115
+ DO_FPCMP_PPZZ_H(NAME, OP) \
116
+ DO_FPCMP_PPZZ_S(NAME, OP) \
117
+ DO_FPCMP_PPZZ_D(NAME, OP)
118
+
119
+#define DO_FCMGE(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) <= 0
120
+#define DO_FCMGT(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) < 0
121
+#define DO_FCMEQ(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) == 0
122
+#define DO_FCMNE(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) != 0
123
+#define DO_FCMUO(TYPE, X, Y, ST) \
124
+ TYPE##_compare_quiet(X, Y, ST) == float_relation_unordered
125
+#define DO_FACGE(TYPE, X, Y, ST) \
126
+ TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) <= 0
127
+#define DO_FACGT(TYPE, X, Y, ST) \
128
+ TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) < 0
129
+
130
+DO_FPCMP_PPZZ_ALL(sve_fcmge, DO_FCMGE)
131
+DO_FPCMP_PPZZ_ALL(sve_fcmgt, DO_FCMGT)
132
+DO_FPCMP_PPZZ_ALL(sve_fcmeq, DO_FCMEQ)
133
+DO_FPCMP_PPZZ_ALL(sve_fcmne, DO_FCMNE)
134
+DO_FPCMP_PPZZ_ALL(sve_fcmuo, DO_FCMUO)
135
+DO_FPCMP_PPZZ_ALL(sve_facge, DO_FACGE)
136
+DO_FPCMP_PPZZ_ALL(sve_facgt, DO_FACGT)
137
+
138
+#undef DO_FPCMP_PPZZ_ALL
139
+#undef DO_FPCMP_PPZZ_D
140
+#undef DO_FPCMP_PPZZ_S
141
+#undef DO_FPCMP_PPZZ_H
142
+#undef DO_FPCMP_PPZZ
143
+
144
/*
145
* Load contiguous data, protected by a governing predicate.
146
*/
147
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/target/arm/translate-sve.c
150
+++ b/target/arm/translate-sve.c
151
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
152
153
#undef DO_FP3
154
155
+static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
156
+ gen_helper_gvec_4_ptr *fn)
157
+{
158
+ if (fn == NULL) {
159
+ return false;
160
+ }
161
+ if (sve_access_check(s)) {
162
+ unsigned vsz = vec_full_reg_size(s);
163
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
164
+ tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd),
165
+ vec_full_reg_offset(s, a->rn),
166
+ vec_full_reg_offset(s, a->rm),
167
+ pred_full_reg_offset(s, a->pg),
168
+ status, vsz, vsz, 0, fn);
169
+ tcg_temp_free_ptr(status);
170
+ }
171
+ return true;
172
+}
173
+
174
+#define DO_FPCMP(NAME, name) \
175
+static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a, \
176
+ uint32_t insn) \
177
+{ \
178
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
179
+ NULL, gen_helper_sve_##name##_h, \
180
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
181
+ }; \
182
+ return do_fp_cmp(s, a, fns[a->esz]); \
183
+}
184
+
185
+DO_FPCMP(FCMGE, fcmge)
186
+DO_FPCMP(FCMGT, fcmgt)
187
+DO_FPCMP(FCMEQ, fcmeq)
188
+DO_FPCMP(FCMNE, fcmne)
189
+DO_FPCMP(FCMUO, fcmuo)
190
+DO_FPCMP(FACGE, facge)
191
+DO_FPCMP(FACGT, facgt)
192
+
193
+#undef DO_FPCMP
194
+
195
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
196
197
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
198
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/sve.decode
201
+++ b/target/arm/sve.decode
202
@@ -XXX,XX +XXX,XX @@ UXTH 00000100 .. 010 011 101 ... ..... ..... @rd_pg_rn
203
SXTW 00000100 .. 010 100 101 ... ..... ..... @rd_pg_rn
204
UXTW 00000100 .. 010 101 101 ... ..... ..... @rd_pg_rn
205
206
+### SVE Floating Point Compare - Vectors Group
207
+
208
+# SVE floating-point compare vectors
209
+FCMGE_ppzz 01100101 .. 0 ..... 010 ... ..... 0 .... @pd_pg_rn_rm
210
+FCMGT_ppzz 01100101 .. 0 ..... 010 ... ..... 1 .... @pd_pg_rn_rm
211
+FCMEQ_ppzz 01100101 .. 0 ..... 011 ... ..... 0 .... @pd_pg_rn_rm
212
+FCMNE_ppzz 01100101 .. 0 ..... 011 ... ..... 1 .... @pd_pg_rn_rm
213
+FCMUO_ppzz 01100101 .. 0 ..... 110 ... ..... 0 .... @pd_pg_rn_rm
214
+FACGE_ppzz 01100101 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm
215
+FACGT_ppzz 01100101 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm
216
+
217
### SVE Integer Multiply-Add Group
218
219
# SVE integer multiply-add writing addend (predicated)
220
--
221
2.17.1
222
223
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 56 ++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 69 +++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 14 +++++++
12
4 files changed, 214 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fadds_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, i64, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fadds_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, i64, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fadds_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, i64, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fsubs_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, i64, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fsubs_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, i64, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fsubs_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, i64, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fmuls_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, i64, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fmuls_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, i64, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fmuls_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, i64, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fsubrs_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, i64, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fsubrs_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, i64, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fsubrs_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, i64, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fmaxnms_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, i64, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fmaxnms_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, i64, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fmaxnms_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, i64, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_fminnms_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, i64, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_fminnms_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, i64, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_fminnms_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, i64, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_fmaxs_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, i64, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_fmaxs_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, i64, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_fmaxs_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, i64, ptr, i32)
70
+
71
+DEF_HELPER_FLAGS_6(sve_fmins_h, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, i64, ptr, i32)
73
+DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, i64, ptr, i32)
75
+DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
76
+ void, ptr, ptr, ptr, i64, ptr, i32)
77
+
78
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
79
void, ptr, ptr, ptr, ptr, i32)
80
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
81
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/sve_helper.c
84
+++ b/target/arm/sve_helper.c
85
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd)
86
87
#undef DO_ZPZZ_FP
88
89
+/* Three-operand expander, with one scalar operand, controlled by
90
+ * a predicate, with the extra float_status parameter.
91
+ */
92
+#define DO_ZPZS_FP(NAME, TYPE, H, OP) \
93
+void HELPER(NAME)(void *vd, void *vn, void *vg, uint64_t scalar, \
94
+ void *status, uint32_t desc) \
95
+{ \
96
+ intptr_t i = simd_oprsz(desc); \
97
+ uint64_t *g = vg; \
98
+ TYPE mm = scalar; \
99
+ do { \
100
+ uint64_t pg = g[(i - 1) >> 6]; \
101
+ do { \
102
+ i -= sizeof(TYPE); \
103
+ if (likely((pg >> (i & 63)) & 1)) { \
104
+ TYPE nn = *(TYPE *)(vn + H(i)); \
105
+ *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \
106
+ } \
107
+ } while (i & 63); \
108
+ } while (i != 0); \
109
+}
110
+
111
+DO_ZPZS_FP(sve_fadds_h, float16, H1_2, float16_add)
112
+DO_ZPZS_FP(sve_fadds_s, float32, H1_4, float32_add)
113
+DO_ZPZS_FP(sve_fadds_d, float64, , float64_add)
114
+
115
+DO_ZPZS_FP(sve_fsubs_h, float16, H1_2, float16_sub)
116
+DO_ZPZS_FP(sve_fsubs_s, float32, H1_4, float32_sub)
117
+DO_ZPZS_FP(sve_fsubs_d, float64, , float64_sub)
118
+
119
+DO_ZPZS_FP(sve_fmuls_h, float16, H1_2, float16_mul)
120
+DO_ZPZS_FP(sve_fmuls_s, float32, H1_4, float32_mul)
121
+DO_ZPZS_FP(sve_fmuls_d, float64, , float64_mul)
122
+
123
+static inline float16 subr_h(float16 a, float16 b, float_status *s)
124
+{
125
+ return float16_sub(b, a, s);
126
+}
127
+
128
+static inline float32 subr_s(float32 a, float32 b, float_status *s)
129
+{
130
+ return float32_sub(b, a, s);
131
+}
132
+
133
+static inline float64 subr_d(float64 a, float64 b, float_status *s)
134
+{
135
+ return float64_sub(b, a, s);
136
+}
137
+
138
+DO_ZPZS_FP(sve_fsubrs_h, float16, H1_2, subr_h)
139
+DO_ZPZS_FP(sve_fsubrs_s, float32, H1_4, subr_s)
140
+DO_ZPZS_FP(sve_fsubrs_d, float64, , subr_d)
141
+
142
+DO_ZPZS_FP(sve_fmaxnms_h, float16, H1_2, float16_maxnum)
143
+DO_ZPZS_FP(sve_fmaxnms_s, float32, H1_4, float32_maxnum)
144
+DO_ZPZS_FP(sve_fmaxnms_d, float64, , float64_maxnum)
145
+
146
+DO_ZPZS_FP(sve_fminnms_h, float16, H1_2, float16_minnum)
147
+DO_ZPZS_FP(sve_fminnms_s, float32, H1_4, float32_minnum)
148
+DO_ZPZS_FP(sve_fminnms_d, float64, , float64_minnum)
149
+
150
+DO_ZPZS_FP(sve_fmaxs_h, float16, H1_2, float16_max)
151
+DO_ZPZS_FP(sve_fmaxs_s, float32, H1_4, float32_max)
152
+DO_ZPZS_FP(sve_fmaxs_d, float64, , float64_max)
153
+
154
+DO_ZPZS_FP(sve_fmins_h, float16, H1_2, float16_min)
155
+DO_ZPZS_FP(sve_fmins_s, float32, H1_4, float32_min)
156
+DO_ZPZS_FP(sve_fmins_d, float64, , float64_min)
157
+
158
/* Fully general two-operand expander, controlled by a predicate,
159
* With the extra float_status parameter.
160
*/
161
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate-sve.c
164
+++ b/target/arm/translate-sve.c
165
@@ -XXX,XX +XXX,XX @@
166
#include "exec/log.h"
167
#include "trace-tcg.h"
168
#include "translate-a64.h"
169
+#include "fpu/softfloat.h"
170
171
172
typedef void GVecGen2sFn(unsigned, uint32_t, uint32_t,
173
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
174
175
#undef DO_FP3
176
177
+typedef void gen_helper_sve_fp2scalar(TCGv_ptr, TCGv_ptr, TCGv_ptr,
178
+ TCGv_i64, TCGv_ptr, TCGv_i32);
179
+
180
+static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16,
181
+ TCGv_i64 scalar, gen_helper_sve_fp2scalar *fn)
182
+{
183
+ unsigned vsz = vec_full_reg_size(s);
184
+ TCGv_ptr t_zd, t_zn, t_pg, status;
185
+ TCGv_i32 desc;
186
+
187
+ t_zd = tcg_temp_new_ptr();
188
+ t_zn = tcg_temp_new_ptr();
189
+ t_pg = tcg_temp_new_ptr();
190
+ tcg_gen_addi_ptr(t_zd, cpu_env, vec_full_reg_offset(s, zd));
191
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, zn));
192
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
193
+
194
+ status = get_fpstatus_ptr(is_fp16);
195
+ desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
196
+ fn(t_zd, t_zn, t_pg, scalar, status, desc);
197
+
198
+ tcg_temp_free_i32(desc);
199
+ tcg_temp_free_ptr(status);
200
+ tcg_temp_free_ptr(t_pg);
201
+ tcg_temp_free_ptr(t_zn);
202
+ tcg_temp_free_ptr(t_zd);
203
+}
204
+
205
+static void do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm,
206
+ gen_helper_sve_fp2scalar *fn)
207
+{
208
+ TCGv_i64 temp = tcg_const_i64(imm);
209
+ do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16, temp, fn);
210
+ tcg_temp_free_i64(temp);
211
+}
212
+
213
+#define DO_FP_IMM(NAME, name, const0, const1) \
214
+static bool trans_##NAME##_zpzi(DisasContext *s, arg_rpri_esz *a, \
215
+ uint32_t insn) \
216
+{ \
217
+ static gen_helper_sve_fp2scalar * const fns[3] = { \
218
+ gen_helper_sve_##name##_h, \
219
+ gen_helper_sve_##name##_s, \
220
+ gen_helper_sve_##name##_d \
221
+ }; \
222
+ static uint64_t const val[3][2] = { \
223
+ { float16_##const0, float16_##const1 }, \
224
+ { float32_##const0, float32_##const1 }, \
225
+ { float64_##const0, float64_##const1 }, \
226
+ }; \
227
+ if (a->esz == 0) { \
228
+ return false; \
229
+ } \
230
+ if (sve_access_check(s)) { \
231
+ do_fp_imm(s, a, val[a->esz - 1][a->imm], fns[a->esz - 1]); \
232
+ } \
233
+ return true; \
234
+}
235
+
236
+#define float16_two make_float16(0x4000)
237
+#define float32_two make_float32(0x40000000)
238
+#define float64_two make_float64(0x4000000000000000ULL)
239
+
240
+DO_FP_IMM(FADD, fadds, half, one)
241
+DO_FP_IMM(FSUB, fsubs, half, one)
242
+DO_FP_IMM(FMUL, fmuls, half, two)
243
+DO_FP_IMM(FSUBR, fsubrs, half, one)
244
+DO_FP_IMM(FMAXNM, fmaxnms, zero, one)
245
+DO_FP_IMM(FMINNM, fminnms, zero, one)
246
+DO_FP_IMM(FMAX, fmaxs, zero, one)
247
+DO_FP_IMM(FMIN, fmins, zero, one)
248
+
249
+#undef DO_FP_IMM
250
+
251
static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
252
gen_helper_gvec_4_ptr *fn)
253
{
254
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
255
index XXXXXXX..XXXXXXX 100644
256
--- a/target/arm/sve.decode
257
+++ b/target/arm/sve.decode
258
@@ -XXX,XX +XXX,XX @@
259
@rdn_pg4 ........ esz:2 .. pg:4 ... ........ rd:5 \
260
&rpri_esz rn=%reg_movprfx
261
262
+# Two register operand, one one-bit floating-point operand.
263
+@rdn_i1 ........ esz:2 ......... pg:3 .... imm:1 rd:5 \
264
+ &rpri_esz rn=%reg_movprfx
265
+
266
# Two register operand, one encoded bitmask.
267
@rdn_dbm ........ .. .... dbm:13 rd:5 \
268
&rr_dbm rn=%reg_movprfx
269
@@ -XXX,XX +XXX,XX @@ FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
270
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
271
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
272
273
+# SVE floating-point arithmetic with immediate (predicated)
274
+FADD_zpzi 01100101 .. 011 000 100 ... 0000 . ..... @rdn_i1
275
+FSUB_zpzi 01100101 .. 011 001 100 ... 0000 . ..... @rdn_i1
276
+FMUL_zpzi 01100101 .. 011 010 100 ... 0000 . ..... @rdn_i1
277
+FSUBR_zpzi 01100101 .. 011 011 100 ... 0000 . ..... @rdn_i1
278
+FMAXNM_zpzi 01100101 .. 011 100 100 ... 0000 . ..... @rdn_i1
279
+FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1
280
+FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1
281
+FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1
282
+
283
### SVE FP Multiply-Add Group
284
285
# SVE floating-point multiply-accumulate writing addend
286
--
287
2.17.1
288
289
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-20-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 35 ++++++++++++++++++++++
9
target/arm/sve_helper.c | 61 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 57 +++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 8 +++++
12
4 files changed, 161 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve_faddv_h, TCG_CALL_NO_RWG,
23
+ i64, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve_faddv_s, TCG_CALL_NO_RWG,
25
+ i64, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve_faddv_d, TCG_CALL_NO_RWG,
27
+ i64, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_h, TCG_CALL_NO_RWG,
30
+ i64, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_s, TCG_CALL_NO_RWG,
32
+ i64, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_d, TCG_CALL_NO_RWG,
34
+ i64, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_4(sve_fminnmv_h, TCG_CALL_NO_RWG,
37
+ i64, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(sve_fminnmv_s, TCG_CALL_NO_RWG,
39
+ i64, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(sve_fminnmv_d, TCG_CALL_NO_RWG,
41
+ i64, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_4(sve_fmaxv_h, TCG_CALL_NO_RWG,
44
+ i64, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_4(sve_fmaxv_s, TCG_CALL_NO_RWG,
46
+ i64, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(sve_fmaxv_d, TCG_CALL_NO_RWG,
48
+ i64, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(sve_fminv_h, TCG_CALL_NO_RWG,
51
+ i64, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(sve_fminv_s, TCG_CALL_NO_RWG,
53
+ i64, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_4(sve_fminv_d, TCG_CALL_NO_RWG,
55
+ i64, ptr, ptr, ptr, i32)
56
+
57
DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
58
i64, i64, ptr, ptr, ptr, i32)
59
DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
60
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/sve_helper.c
63
+++ b/target/arm/sve_helper.c
64
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
65
return predtest_ones(d, oprsz, esz_mask);
66
}
67
68
+/* Recursive reduction on a function;
69
+ * C.f. the ARM ARM function ReducePredicated.
70
+ *
71
+ * While it would be possible to write this without the DATA temporary,
72
+ * it is much simpler to process the predicate register this way.
73
+ * The recursion is bounded to depth 7 (128 fp16 elements), so there's
74
+ * little to gain with a more complex non-recursive form.
75
+ */
76
+#define DO_REDUCE(NAME, TYPE, H, FUNC, IDENT) \
77
+static TYPE NAME##_reduce(TYPE *data, float_status *status, uintptr_t n) \
78
+{ \
79
+ if (n == 1) { \
80
+ return *data; \
81
+ } else { \
82
+ uintptr_t half = n / 2; \
83
+ TYPE lo = NAME##_reduce(data, status, half); \
84
+ TYPE hi = NAME##_reduce(data + half, status, half); \
85
+ return TYPE##_##FUNC(lo, hi, status); \
86
+ } \
87
+} \
88
+uint64_t HELPER(NAME)(void *vn, void *vg, void *vs, uint32_t desc) \
89
+{ \
90
+ uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_maxsz(desc); \
91
+ TYPE data[sizeof(ARMVectorReg) / sizeof(TYPE)]; \
92
+ for (i = 0; i < oprsz; ) { \
93
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
94
+ do { \
95
+ TYPE nn = *(TYPE *)(vn + H(i)); \
96
+ *(TYPE *)((void *)data + i) = (pg & 1 ? nn : IDENT); \
97
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
98
+ } while (i & 15); \
99
+ } \
100
+ for (; i < maxsz; i += sizeof(TYPE)) { \
101
+ *(TYPE *)((void *)data + i) = IDENT; \
102
+ } \
103
+ return NAME##_reduce(data, vs, maxsz / sizeof(TYPE)); \
104
+}
105
+
106
+DO_REDUCE(sve_faddv_h, float16, H1_2, add, float16_zero)
107
+DO_REDUCE(sve_faddv_s, float32, H1_4, add, float32_zero)
108
+DO_REDUCE(sve_faddv_d, float64, , add, float64_zero)
109
+
110
+/* Identity is floatN_default_nan, without the function call. */
111
+DO_REDUCE(sve_fminnmv_h, float16, H1_2, minnum, 0x7E00)
112
+DO_REDUCE(sve_fminnmv_s, float32, H1_4, minnum, 0x7FC00000)
113
+DO_REDUCE(sve_fminnmv_d, float64, , minnum, 0x7FF8000000000000ULL)
114
+
115
+DO_REDUCE(sve_fmaxnmv_h, float16, H1_2, maxnum, 0x7E00)
116
+DO_REDUCE(sve_fmaxnmv_s, float32, H1_4, maxnum, 0x7FC00000)
117
+DO_REDUCE(sve_fmaxnmv_d, float64, , maxnum, 0x7FF8000000000000ULL)
118
+
119
+DO_REDUCE(sve_fminv_h, float16, H1_2, min, float16_infinity)
120
+DO_REDUCE(sve_fminv_s, float32, H1_4, min, float32_infinity)
121
+DO_REDUCE(sve_fminv_d, float64, , min, float64_infinity)
122
+
123
+DO_REDUCE(sve_fmaxv_h, float16, H1_2, max, float16_chs(float16_infinity))
124
+DO_REDUCE(sve_fmaxv_s, float32, H1_4, max, float32_chs(float32_infinity))
125
+DO_REDUCE(sve_fmaxv_d, float64, , max, float64_chs(float64_infinity))
126
+
127
+#undef DO_REDUCE
128
+
129
uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
130
void *status, uint32_t desc)
131
{
132
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-sve.c
135
+++ b/target/arm/translate-sve.c
136
@@ -XXX,XX +XXX,XX @@ static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
137
return true;
138
}
139
140
+/*
141
+ *** SVE Floating Point Fast Reduction Group
142
+ */
143
+
144
+typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr,
145
+ TCGv_ptr, TCGv_i32);
146
+
147
+static void do_reduce(DisasContext *s, arg_rpr_esz *a,
148
+ gen_helper_fp_reduce *fn)
149
+{
150
+ unsigned vsz = vec_full_reg_size(s);
151
+ unsigned p2vsz = pow2ceil(vsz);
152
+ TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, p2vsz, 0));
153
+ TCGv_ptr t_zn, t_pg, status;
154
+ TCGv_i64 temp;
155
+
156
+ temp = tcg_temp_new_i64();
157
+ t_zn = tcg_temp_new_ptr();
158
+ t_pg = tcg_temp_new_ptr();
159
+
160
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, a->rn));
161
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
162
+ status = get_fpstatus_ptr(a->esz == MO_16);
163
+
164
+ fn(temp, t_zn, t_pg, status, t_desc);
165
+ tcg_temp_free_ptr(t_zn);
166
+ tcg_temp_free_ptr(t_pg);
167
+ tcg_temp_free_ptr(status);
168
+ tcg_temp_free_i32(t_desc);
169
+
170
+ write_fp_dreg(s, a->rd, temp);
171
+ tcg_temp_free_i64(temp);
172
+}
173
+
174
+#define DO_VPZ(NAME, name) \
175
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
176
+{ \
177
+ static gen_helper_fp_reduce * const fns[3] = { \
178
+ gen_helper_sve_##name##_h, \
179
+ gen_helper_sve_##name##_s, \
180
+ gen_helper_sve_##name##_d, \
181
+ }; \
182
+ if (a->esz == 0) { \
183
+ return false; \
184
+ } \
185
+ if (sve_access_check(s)) { \
186
+ do_reduce(s, a, fns[a->esz - 1]); \
187
+ } \
188
+ return true; \
189
+}
190
+
191
+DO_VPZ(FADDV, faddv)
192
+DO_VPZ(FMINNMV, fminnmv)
193
+DO_VPZ(FMAXNMV, fmaxnmv)
194
+DO_VPZ(FMINV, fminv)
195
+DO_VPZ(FMAXV, fmaxv)
196
+
197
/*
198
*** SVE Floating Point Accumulating Reduction Group
199
*/
200
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
201
index XXXXXXX..XXXXXXX 100644
202
--- a/target/arm/sve.decode
203
+++ b/target/arm/sve.decode
204
@@ -XXX,XX +XXX,XX @@ FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
205
FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
206
FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
207
208
+### SVE FP Fast Reduction Group
209
+
210
+FADDV 01100101 .. 000 000 001 ... ..... ..... @rd_pg_rn
211
+FMAXNMV 01100101 .. 000 100 001 ... ..... ..... @rd_pg_rn
212
+FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn
213
+FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn
214
+FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
215
+
216
### SVE FP Accumulating Reduction Group
217
218
# SVE floating-point serial reduction (predicated)
219
--
220
2.17.1
221
222
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-21-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper.h | 8 +++++++
9
target/arm/translate-sve.c | 47 ++++++++++++++++++++++++++++++++++++++
10
target/arm/vec_helper.c | 20 ++++++++++++++++
11
target/arm/sve.decode | 5 ++++
12
4 files changed, 80 insertions(+)
13
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
17
+++ b/target/arm/helper.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_4(gvec_frsqrte_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(gvec_frsqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+
30
DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
36
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ DO_VPZ(FMAXNMV, fmaxnmv)
38
DO_VPZ(FMINV, fminv)
39
DO_VPZ(FMAXV, fmaxv)
40
41
+/*
42
+ *** SVE Floating Point Unary Operations - Unpredicated Group
43
+ */
44
+
45
+static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
46
+{
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
49
+
50
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
51
+ vec_full_reg_offset(s, a->rn),
52
+ status, vsz, vsz, 0, fn);
53
+ tcg_temp_free_ptr(status);
54
+}
55
+
56
+static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
57
+{
58
+ static gen_helper_gvec_2_ptr * const fns[3] = {
59
+ gen_helper_gvec_frecpe_h,
60
+ gen_helper_gvec_frecpe_s,
61
+ gen_helper_gvec_frecpe_d,
62
+ };
63
+ if (a->esz == 0) {
64
+ return false;
65
+ }
66
+ if (sve_access_check(s)) {
67
+ do_zz_fp(s, a, fns[a->esz - 1]);
68
+ }
69
+ return true;
70
+}
71
+
72
+static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
73
+{
74
+ static gen_helper_gvec_2_ptr * const fns[3] = {
75
+ gen_helper_gvec_frsqrte_h,
76
+ gen_helper_gvec_frsqrte_s,
77
+ gen_helper_gvec_frsqrte_d,
78
+ };
79
+ if (a->esz == 0) {
80
+ return false;
81
+ }
82
+ if (sve_access_check(s)) {
83
+ do_zz_fp(s, a, fns[a->esz - 1]);
84
+ }
85
+ return true;
86
+}
87
+
88
/*
89
*** SVE Floating Point Accumulating Reduction Group
90
*/
91
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/vec_helper.c
94
+++ b/target/arm/vec_helper.c
95
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
96
clear_tail(d, opr_sz, simd_maxsz(desc));
97
}
98
99
+#define DO_2OP(NAME, FUNC, TYPE) \
100
+void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \
101
+{ \
102
+ intptr_t i, oprsz = simd_oprsz(desc); \
103
+ TYPE *d = vd, *n = vn; \
104
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
105
+ d[i] = FUNC(n[i], stat); \
106
+ } \
107
+}
108
+
109
+DO_2OP(gvec_frecpe_h, helper_recpe_f16, float16)
110
+DO_2OP(gvec_frecpe_s, helper_recpe_f32, float32)
111
+DO_2OP(gvec_frecpe_d, helper_recpe_f64, float64)
112
+
113
+DO_2OP(gvec_frsqrte_h, helper_rsqrte_f16, float16)
114
+DO_2OP(gvec_frsqrte_s, helper_rsqrte_f32, float32)
115
+DO_2OP(gvec_frsqrte_d, helper_rsqrte_f64, float64)
116
+
117
+#undef DO_2OP
118
+
119
/* Floating-point trigonometric starting value.
120
* See the ARM ARM pseudocode function FPTrigSMul.
121
*/
122
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/sve.decode
125
+++ b/target/arm/sve.decode
126
@@ -XXX,XX +XXX,XX @@ FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn
127
FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn
128
FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
129
130
+## SVE Floating Point Unary Operations - Unpredicated Group
131
+
132
+FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
133
+FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
134
+
135
### SVE FP Accumulating Reduction Group
136
137
# SVE floating-point serial reduction (predicated)
138
--
139
2.17.1
140
141
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 42 +++++++++++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 43 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 10 +++++++++
12
4 files changed, 138 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
20
i64, i64, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_fcmge0_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_fcmge0_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_fcmge0_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_5(sve_fcmgt0_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_fcmgt0_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_fcmgt0_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_5(sve_fcmlt0_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_5(sve_fcmlt0_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve_fcmlt0_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_5(sve_fcmle0_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(sve_fcmle0_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_5(sve_fcmle0_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_5(sve_fcmeq0_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_5(sve_fcmeq0_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_5(sve_fcmeq0_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_5(sve_fcmne0_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_5(sve_fcmne0_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_5(sve_fcmne0_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, i32)
63
+
64
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
65
void, ptr, ptr, ptr, ptr, ptr, i32)
66
DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
67
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/sve_helper.c
70
+++ b/target/arm/sve_helper.c
71
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
72
73
#define DO_FCMGE(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) <= 0
74
#define DO_FCMGT(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) < 0
75
+#define DO_FCMLE(TYPE, X, Y, ST) TYPE##_compare(X, Y, ST) <= 0
76
+#define DO_FCMLT(TYPE, X, Y, ST) TYPE##_compare(X, Y, ST) < 0
77
#define DO_FCMEQ(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) == 0
78
#define DO_FCMNE(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) != 0
79
#define DO_FCMUO(TYPE, X, Y, ST) \
80
@@ -XXX,XX +XXX,XX @@ DO_FPCMP_PPZZ_ALL(sve_facgt, DO_FACGT)
81
#undef DO_FPCMP_PPZZ_H
82
#undef DO_FPCMP_PPZZ
83
84
+/* One operand floating-point comparison against zero, controlled
85
+ * by a predicate.
86
+ */
87
+#define DO_FPCMP_PPZ0(NAME, TYPE, H, OP) \
88
+void HELPER(NAME)(void *vd, void *vn, void *vg, \
89
+ void *status, uint32_t desc) \
90
+{ \
91
+ intptr_t i = simd_oprsz(desc), j = (i - 1) >> 6; \
92
+ uint64_t *d = vd, *g = vg; \
93
+ do { \
94
+ uint64_t out = 0, pg = g[j]; \
95
+ do { \
96
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
97
+ if ((pg >> (i & 63)) & 1) { \
98
+ TYPE nn = *(TYPE *)(vn + H(i)); \
99
+ out |= OP(TYPE, nn, 0, status); \
100
+ } \
101
+ } while (i & 63); \
102
+ d[j--] = out; \
103
+ } while (i > 0); \
104
+}
105
+
106
+#define DO_FPCMP_PPZ0_H(NAME, OP) \
107
+ DO_FPCMP_PPZ0(NAME##_h, float16, H1_2, OP)
108
+#define DO_FPCMP_PPZ0_S(NAME, OP) \
109
+ DO_FPCMP_PPZ0(NAME##_s, float32, H1_4, OP)
110
+#define DO_FPCMP_PPZ0_D(NAME, OP) \
111
+ DO_FPCMP_PPZ0(NAME##_d, float64, , OP)
112
+
113
+#define DO_FPCMP_PPZ0_ALL(NAME, OP) \
114
+ DO_FPCMP_PPZ0_H(NAME, OP) \
115
+ DO_FPCMP_PPZ0_S(NAME, OP) \
116
+ DO_FPCMP_PPZ0_D(NAME, OP)
117
+
118
+DO_FPCMP_PPZ0_ALL(sve_fcmge0, DO_FCMGE)
119
+DO_FPCMP_PPZ0_ALL(sve_fcmgt0, DO_FCMGT)
120
+DO_FPCMP_PPZ0_ALL(sve_fcmle0, DO_FCMLE)
121
+DO_FPCMP_PPZ0_ALL(sve_fcmlt0, DO_FCMLT)
122
+DO_FPCMP_PPZ0_ALL(sve_fcmeq0, DO_FCMEQ)
123
+DO_FPCMP_PPZ0_ALL(sve_fcmne0, DO_FCMNE)
124
+
125
/*
126
* Load contiguous data, protected by a governing predicate.
127
*/
128
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate-sve.c
131
+++ b/target/arm/translate-sve.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
133
return true;
134
}
135
136
+/*
137
+ *** SVE Floating Point Compare with Zero Group
138
+ */
139
+
140
+static void do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
141
+ gen_helper_gvec_3_ptr *fn)
142
+{
143
+ unsigned vsz = vec_full_reg_size(s);
144
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
145
+
146
+ tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
147
+ vec_full_reg_offset(s, a->rn),
148
+ pred_full_reg_offset(s, a->pg),
149
+ status, vsz, vsz, 0, fn);
150
+ tcg_temp_free_ptr(status);
151
+}
152
+
153
+#define DO_PPZ(NAME, name) \
154
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
155
+{ \
156
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
157
+ gen_helper_sve_##name##_h, \
158
+ gen_helper_sve_##name##_s, \
159
+ gen_helper_sve_##name##_d, \
160
+ }; \
161
+ if (a->esz == 0) { \
162
+ return false; \
163
+ } \
164
+ if (sve_access_check(s)) { \
165
+ do_ppz_fp(s, a, fns[a->esz - 1]); \
166
+ } \
167
+ return true; \
168
+}
169
+
170
+DO_PPZ(FCMGE_ppz0, fcmge0)
171
+DO_PPZ(FCMGT_ppz0, fcmgt0)
172
+DO_PPZ(FCMLE_ppz0, fcmle0)
173
+DO_PPZ(FCMLT_ppz0, fcmlt0)
174
+DO_PPZ(FCMEQ_ppz0, fcmeq0)
175
+DO_PPZ(FCMNE_ppz0, fcmne0)
176
+
177
+#undef DO_PPZ
178
+
179
/*
180
*** SVE Floating Point Accumulating Reduction Group
181
*/
182
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/sve.decode
185
+++ b/target/arm/sve.decode
186
@@ -XXX,XX +XXX,XX @@
187
# One register operand, with governing predicate, vector element size
188
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
189
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
190
+@pd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 . rd:4 &rpr_esz
191
192
# One register operand, with governing predicate, no vector element size
193
@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
194
@@ -XXX,XX +XXX,XX @@ FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
195
FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
196
FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
197
198
+### SVE FP Compare with Zero Group
199
+
200
+FCMGE_ppz0 01100101 .. 0100 00 001 ... ..... 0 .... @pd_pg_rn
201
+FCMGT_ppz0 01100101 .. 0100 00 001 ... ..... 1 .... @pd_pg_rn
202
+FCMLT_ppz0 01100101 .. 0100 01 001 ... ..... 0 .... @pd_pg_rn
203
+FCMLE_ppz0 01100101 .. 0100 01 001 ... ..... 1 .... @pd_pg_rn
204
+FCMEQ_ppz0 01100101 .. 0100 10 001 ... ..... 0 .... @pd_pg_rn
205
+FCMNE_ppz0 01100101 .. 0100 11 001 ... ..... 0 .... @pd_pg_rn
206
+
207
### SVE FP Accumulating Reduction Group
208
209
# SVE floating-point serial reduction (predicated)
210
--
211
2.17.1
212
213
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-23-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 4 +++
9
target/arm/sve_helper.c | 70 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 27 +++++++++++++++
11
target/arm/sve.decode | 3 ++
12
4 files changed, 104 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
+
26
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve_helper.c
32
+++ b/target/arm/sve_helper.c
33
@@ -XXX,XX +XXX,XX @@ DO_FPCMP_PPZ0_ALL(sve_fcmlt0, DO_FCMLT)
34
DO_FPCMP_PPZ0_ALL(sve_fcmeq0, DO_FCMEQ)
35
DO_FPCMP_PPZ0_ALL(sve_fcmne0, DO_FCMNE)
36
37
+/* FP Trig Multiply-Add. */
38
+
39
+void HELPER(sve_ftmad_h)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
40
+{
41
+ static const float16 coeff[16] = {
42
+ 0x3c00, 0xb155, 0x2030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
43
+ 0x3c00, 0xb800, 0x293a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
44
+ };
45
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float16);
46
+ intptr_t x = simd_data(desc);
47
+ float16 *d = vd, *n = vn, *m = vm;
48
+ for (i = 0; i < opr_sz; i++) {
49
+ float16 mm = m[i];
50
+ intptr_t xx = x;
51
+ if (float16_is_neg(mm)) {
52
+ mm = float16_abs(mm);
53
+ xx += 8;
54
+ }
55
+ d[i] = float16_muladd(n[i], mm, coeff[xx], 0, vs);
56
+ }
57
+}
58
+
59
+void HELPER(sve_ftmad_s)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
60
+{
61
+ static const float32 coeff[16] = {
62
+ 0x3f800000, 0xbe2aaaab, 0x3c088886, 0xb95008b9,
63
+ 0x36369d6d, 0x00000000, 0x00000000, 0x00000000,
64
+ 0x3f800000, 0xbf000000, 0x3d2aaaa6, 0xbab60705,
65
+ 0x37cd37cc, 0x00000000, 0x00000000, 0x00000000,
66
+ };
67
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float32);
68
+ intptr_t x = simd_data(desc);
69
+ float32 *d = vd, *n = vn, *m = vm;
70
+ for (i = 0; i < opr_sz; i++) {
71
+ float32 mm = m[i];
72
+ intptr_t xx = x;
73
+ if (float32_is_neg(mm)) {
74
+ mm = float32_abs(mm);
75
+ xx += 8;
76
+ }
77
+ d[i] = float32_muladd(n[i], mm, coeff[xx], 0, vs);
78
+ }
79
+}
80
+
81
+void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
82
+{
83
+ static const float64 coeff[16] = {
84
+ 0x3ff0000000000000ull, 0xbfc5555555555543ull,
85
+ 0x3f8111111110f30cull, 0xbf2a01a019b92fc6ull,
86
+ 0x3ec71de351f3d22bull, 0xbe5ae5e2b60f7b91ull,
87
+ 0x3de5d8408868552full, 0x0000000000000000ull,
88
+ 0x3ff0000000000000ull, 0xbfe0000000000000ull,
89
+ 0x3fa5555555555536ull, 0xbf56c16c16c13a0bull,
90
+ 0x3efa01a019b1e8d8ull, 0xbe927e4f7282f468ull,
91
+ 0x3e21ee96d2641b13ull, 0xbda8f76380fbb401ull,
92
+ };
93
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float64);
94
+ intptr_t x = simd_data(desc);
95
+ float64 *d = vd, *n = vn, *m = vm;
96
+ for (i = 0; i < opr_sz; i++) {
97
+ float64 mm = m[i];
98
+ intptr_t xx = x;
99
+ if (float64_is_neg(mm)) {
100
+ mm = float64_abs(mm);
101
+ xx += 8;
102
+ }
103
+ d[i] = float64_muladd(n[i], mm, coeff[xx], 0, vs);
104
+ }
105
+}
106
+
107
/*
108
* Load contiguous data, protected by a governing predicate.
109
*/
110
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/translate-sve.c
113
+++ b/target/arm/translate-sve.c
114
@@ -XXX,XX +XXX,XX @@ DO_PPZ(FCMNE_ppz0, fcmne0)
115
116
#undef DO_PPZ
117
118
+/*
119
+ *** SVE floating-point trig multiply-add coefficient
120
+ */
121
+
122
+static bool trans_FTMAD(DisasContext *s, arg_FTMAD *a, uint32_t insn)
123
+{
124
+ static gen_helper_gvec_3_ptr * const fns[3] = {
125
+ gen_helper_sve_ftmad_h,
126
+ gen_helper_sve_ftmad_s,
127
+ gen_helper_sve_ftmad_d,
128
+ };
129
+
130
+ if (a->esz == 0) {
131
+ return false;
132
+ }
133
+ if (sve_access_check(s)) {
134
+ unsigned vsz = vec_full_reg_size(s);
135
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
136
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
137
+ vec_full_reg_offset(s, a->rn),
138
+ vec_full_reg_offset(s, a->rm),
139
+ status, vsz, vsz, a->imm, fns[a->esz - 1]);
140
+ tcg_temp_free_ptr(status);
141
+ }
142
+ return true;
143
+}
144
+
145
/*
146
*** SVE Floating Point Accumulating Reduction Group
147
*/
148
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/sve.decode
151
+++ b/target/arm/sve.decode
152
@@ -XXX,XX +XXX,XX @@ FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1
153
FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1
154
FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1
155
156
+# SVE floating-point trig multiply-add coefficient
157
+FTMAD 01100101 esz:2 010 imm:3 100000 rm:5 rd:5 rn=%reg_movprfx
158
+
159
### SVE FP Multiply-Add Group
160
161
# SVE floating-point multiply-accumulate writing addend
162
--
163
2.17.1
164
165
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-24-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 13 +++++++++
9
target/arm/sve_helper.c | 55 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 30 +++++++++++++++++++++
11
target/arm/sve.decode | 8 ++++++
12
4 files changed, 106 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, i64, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_fcvt_sh, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_fcvt_dh, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_fcvt_hs, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve_fcvt_ds, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+
35
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
38
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/sve_helper.c
41
+++ b/target/arm/sve_helper.c
42
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
43
} while (i != 0); \
44
}
45
46
+/* SVE fp16 conversions always use IEEE mode. Like AdvSIMD, they ignore
47
+ * FZ16. When converting from fp16, this affects flushing input denormals;
48
+ * when converting to fp16, this affects flushing output denormals.
49
+ */
50
+static inline float32 sve_f16_to_f32(float16 f, float_status *fpst)
51
+{
52
+ flag save = get_flush_inputs_to_zero(fpst);
53
+ float32 ret;
54
+
55
+ set_flush_inputs_to_zero(false, fpst);
56
+ ret = float16_to_float32(f, true, fpst);
57
+ set_flush_inputs_to_zero(save, fpst);
58
+ return ret;
59
+}
60
+
61
+static inline float64 sve_f16_to_f64(float16 f, float_status *fpst)
62
+{
63
+ flag save = get_flush_inputs_to_zero(fpst);
64
+ float64 ret;
65
+
66
+ set_flush_inputs_to_zero(false, fpst);
67
+ ret = float16_to_float64(f, true, fpst);
68
+ set_flush_inputs_to_zero(save, fpst);
69
+ return ret;
70
+}
71
+
72
+static inline float16 sve_f32_to_f16(float32 f, float_status *fpst)
73
+{
74
+ flag save = get_flush_to_zero(fpst);
75
+ float16 ret;
76
+
77
+ set_flush_to_zero(false, fpst);
78
+ ret = float32_to_float16(f, true, fpst);
79
+ set_flush_to_zero(save, fpst);
80
+ return ret;
81
+}
82
+
83
+static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
84
+{
85
+ flag save = get_flush_to_zero(fpst);
86
+ float16 ret;
87
+
88
+ set_flush_to_zero(false, fpst);
89
+ ret = float64_to_float16(f, true, fpst);
90
+ set_flush_to_zero(save, fpst);
91
+ return ret;
92
+}
93
+
94
+DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
+DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
97
+DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
98
+DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
99
+DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
100
+
101
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
102
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
103
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
104
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-sve.c
107
+++ b/target/arm/translate-sve.c
108
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
109
return true;
110
}
111
112
+static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
113
+{
114
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
115
+}
116
+
117
+static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
118
+{
119
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
120
+}
121
+
122
+static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
123
+{
124
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
125
+}
126
+
127
+static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
128
+{
129
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hd);
130
+}
131
+
132
+static bool trans_FCVT_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
133
+{
134
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_ds);
135
+}
136
+
137
+static bool trans_FCVT_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
138
+{
139
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sd);
140
+}
141
+
142
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
143
{
144
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
145
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/sve.decode
148
+++ b/target/arm/sve.decode
149
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
150
151
### SVE FP Unary Operations Predicated Group
152
153
+# SVE floating-point convert precision
154
+FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
155
+FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
156
+FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
157
+FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
158
+FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
159
+FCVT_sd 01100101 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
160
+
161
# SVE integer convert to floating-point
162
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
163
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
164
--
165
2.17.1
166
167
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add documentation for the mps3-an536 board type.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-27-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-sve.h | 14 ++++++++++++++
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
9
target/arm/sve_helper.c | 8 ++++++++
8
1 file changed, 34 insertions(+), 3 deletions(-)
10
target/arm/translate-sve.c | 26 ++++++++++++++++++++++++++
11
target/arm/sve.decode | 4 ++++
12
4 files changed, 52 insertions(+)
13
9
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
12
--- a/docs/system/arm/mps2.rst
17
+++ b/target/arm/helper-sve.h
13
+++ b/docs/system/arm/mps2.rst
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_frintx_s, TCG_CALL_NO_RWG,
14
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(sve_frintx_d, TCG_CALL_NO_RWG,
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
20
void, ptr, ptr, ptr, ptr, i32)
16
-=========================================================================================================================================================
21
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
22
+DEF_HELPER_FLAGS_5(sve_frecpx_h, TCG_CALL_NO_RWG,
18
+=========================================================================================================================================================================
23
+ void, ptr, ptr, ptr, ptr, i32)
19
24
+DEF_HELPER_FLAGS_5(sve_frecpx_s, TCG_CALL_NO_RWG,
20
-These board models all use Arm M-profile CPUs.
25
+ void, ptr, ptr, ptr, ptr, i32)
21
+These board models use Arm M-profile or R-profile CPUs.
26
+DEF_HELPER_FLAGS_5(sve_frecpx_d, TCG_CALL_NO_RWG,
22
27
+ void, ptr, ptr, ptr, ptr, i32)
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
26
27
QEMU models the following FPGA images:
28
29
+FPGA images using M-profile CPUs:
28
+
30
+
29
+DEF_HELPER_FLAGS_5(sve_fsqrt_h, TCG_CALL_NO_RWG,
31
``mps2-an385``
30
+ void, ptr, ptr, ptr, ptr, i32)
32
Cortex-M3 as documented in Arm Application Note AN385
31
+DEF_HELPER_FLAGS_5(sve_fsqrt_s, TCG_CALL_NO_RWG,
33
``mps2-an386``
32
+ void, ptr, ptr, ptr, ptr, i32)
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
33
+DEF_HELPER_FLAGS_5(sve_fsqrt_d, TCG_CALL_NO_RWG,
35
``mps3-an547``
34
+ void, ptr, ptr, ptr, ptr, i32)
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
35
+
39
+
36
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
40
+``mps3-an536``
37
void, ptr, ptr, ptr, ptr, i32)
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
38
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
42
+++ b/target/arm/sve_helper.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_frintx_h, uint16_t, H1_2, float16_round_to_int)
44
DO_ZPZ_FP(sve_frintx_s, uint32_t, H1_4, float32_round_to_int)
45
DO_ZPZ_FP(sve_frintx_d, uint64_t, , float64_round_to_int)
46
47
+DO_ZPZ_FP(sve_frecpx_h, uint16_t, H1_2, helper_frecpx_f16)
48
+DO_ZPZ_FP(sve_frecpx_s, uint32_t, H1_4, helper_frecpx_f32)
49
+DO_ZPZ_FP(sve_frecpx_d, uint64_t, , helper_frecpx_f64)
50
+
42
+
51
+DO_ZPZ_FP(sve_fsqrt_h, uint16_t, H1_2, float16_sqrt)
43
Differences between QEMU and real hardware:
52
+DO_ZPZ_FP(sve_fsqrt_s, uint32_t, H1_4, float32_sqrt)
44
53
+DO_ZPZ_FP(sve_fsqrt_d, uint64_t, , float64_sqrt)
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
54
+
64
+
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
65
+Note that for the AN536 the first UART is accessible only by
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
66
+CPU0, and the second UART is accessible only by CPU1. The
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
67
+first UART accessible shared between both CPUs is the third
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
68
+UART. Guest software might therefore be built to use either
59
index XXXXXXX..XXXXXXX 100644
69
+the first UART or the third UART; if you don't see any output
60
--- a/target/arm/translate-sve.c
70
+from the UART you are looking at, try one of the others.
61
+++ b/target/arm/translate-sve.c
71
+(Even if the AN536 machine is started with a single CPU and so
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
72
+no "CPU1-only UART", the UART numbering remains the same,
63
return do_frint_mode(s, a, float_round_ties_away);
73
+with the third UART being the first of the shared ones.)
64
}
74
65
75
Machine-specific options
66
+static bool trans_FRECPX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
76
""""""""""""""""""""""""
67
+{
68
+ static gen_helper_gvec_3_ptr * const fns[3] = {
69
+ gen_helper_sve_frecpx_h,
70
+ gen_helper_sve_frecpx_s,
71
+ gen_helper_sve_frecpx_d
72
+ };
73
+ if (a->esz == 0) {
74
+ return false;
75
+ }
76
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
77
+}
78
+
79
+static bool trans_FSQRT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
80
+{
81
+ static gen_helper_gvec_3_ptr * const fns[3] = {
82
+ gen_helper_sve_fsqrt_h,
83
+ gen_helper_sve_fsqrt_s,
84
+ gen_helper_sve_fsqrt_d
85
+ };
86
+ if (a->esz == 0) {
87
+ return false;
88
+ }
89
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
90
+}
91
+
92
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
93
{
94
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
95
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/arm/sve.decode
98
+++ b/target/arm/sve.decode
99
@@ -XXX,XX +XXX,XX @@ FRINTA 01100101 .. 000 100 101 ... ..... ..... @rd_pg_rn
100
FRINTX 01100101 .. 000 110 101 ... ..... ..... @rd_pg_rn
101
FRINTI 01100101 .. 000 111 101 ... ..... ..... @rd_pg_rn
102
103
+# SVE floating-point unary operations
104
+FRECPX 01100101 .. 001 100 101 ... ..... ..... @rd_pg_rn
105
+FSQRT 01100101 .. 001 101 101 ... ..... ..... @rd_pg_rn
106
+
107
# SVE integer convert to floating-point
108
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
109
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
110
--
77
--
111
2.17.1
78
2.34.1
112
79
113
80
diff view generated by jsdifflib