1
Hopefully last target-arm queue before softfreeze;
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
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 remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
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-20210702
15
8
16
for you to fetch changes up to 802abf4024d23e48d45373ac3f2b580124b54b47:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
17
10
18
target/arm: Add ID_ISAR6 (2018-06-29 15:30:54 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
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
* more MVE instructions
23
* sd: Don't trace SDRequest crc field (coverity bugfix)
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
24
* target/arm: Mark PMINTENSET accesses as possibly doing IO
17
* target/arm: Check NaN mode before silencing NaN
25
* clean up v7VE feature bit handling
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
26
* i.mx7d: minor cleanups
19
* hw/arm: Add basic power management to raspi.
27
* target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
28
* target/arm: Implement ARMv8.2-DotProd
29
* virt: add addresses to dt node names (which stops dtc from
30
complaining that they're not correctly named)
31
* cleanups: replace error_setg(&error_fatal) by error_report() + exit()
32
21
33
----------------------------------------------------------------
22
----------------------------------------------------------------
34
Aaron Lindsay (3):
23
Joe Komlodi (1):
35
target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
24
target/arm: Check NaN mode before silencing NaN
36
target/arm: Remove redundant DIV detection for KVM
37
target/arm: Mark PMINTENSET accesses as possibly doing IO
38
25
39
Alex Bennée (1):
26
Maxim Uvarov (1):
40
target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
27
hw/gpio/gpio_pwr: use shutdown function for reboot
41
28
42
Eric Auger (3):
29
Nolan Leake (1):
43
device_tree: Add qemu_fdt_node_unit_path
30
hw/arm: Add basic power management to raspi.
44
hw/arm/virt: Silence dtc /intc warnings
45
hw/arm/virt: Silence dtc /memory warning
46
31
47
Jean-Christophe Dubois (3):
32
Patrick Venture (2):
48
i.mx7d: Remove unused header files
33
docs/system/arm: Add quanta-q7l1-bmc reference
49
i.mx7d: Change SRC unimplemented device name from sdma to src
34
docs/system/arm: Add quanta-gbs-bmc reference
50
i.mx7d: Change IRQ number type from hwaddr to int
51
35
52
Peter Maydell (1):
36
Peter Maydell (18):
53
sd: Don't trace SDRequest crc field
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
54
55
55
Philippe Mathieu-Daudé (4):
56
Philippe Mathieu-Daudé (1):
56
hw/block/fdc: Replace error_setg(&error_abort) by assert()
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
57
hw/arm/sysbus-fdt: Replace error_setg(&error_fatal) by error_report() + exit()
58
device_tree: Replace error_setg(&error_fatal) by error_report() + exit()
59
sdcard: Use the ldst API
60
58
61
Richard Henderson (40):
59
docs/system/arm/aspeed.rst | 1 +
62
target/arm: Implement SVE Memory Contiguous Load Group
60
docs/system/arm/nuvoton.rst | 5 +-
63
target/arm: Implement SVE Contiguous Load, first-fault and no-fault
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
64
target/arm: Implement SVE Memory Contiguous Store Group
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
65
target/arm: Implement SVE load and broadcast quadword
63
target/arm/helper-mve.h | 108 +++++++
66
target/arm: Implement SVE integer convert to floating-point
64
target/arm/translate.h | 41 +++
67
target/arm: Implement SVE floating-point arithmetic (predicated)
65
target/arm/mve.decode | 177 ++++++++++-
68
target/arm: Implement SVE FP Multiply-Add Group
66
target/arm/t32.decode | 71 ++++-
69
target/arm: Implement SVE Floating Point Accumulating Reduction Group
67
hw/arm/bcm2835_peripherals.c | 13 +-
70
target/arm: Implement SVE load and broadcast element
68
hw/gpio/gpio_pwr.c | 2 +-
71
target/arm: Implement SVE store vector/predicate register
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
72
target/arm: Implement SVE scatter stores
70
target/arm/helper-a64.c | 12 +-
73
target/arm: Implement SVE prefetches
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
74
target/arm: Implement SVE gather loads
72
target/arm/translate-a64.c | 86 +-----
75
target/arm: Implement SVE first-fault gather loads
73
target/arm/translate-mve.c | 261 +++++++++++++++-
76
target/arm: Implement SVE scatter store vector immediate
74
target/arm/translate-neon.c | 81 -----
77
target/arm: Implement SVE floating-point compare vectors
75
target/arm/translate.c | 327 +++++++++++++++++++-
78
target/arm: Implement SVE floating-point arithmetic with immediate
76
target/arm/vfp_helper.c | 24 +-
79
target/arm: Implement SVE Floating Point Multiply Indexed Group
77
hw/misc/meson.build | 1 +
80
target/arm: Implement SVE FP Fast Reduction Group
78
tests/acceptance/boot_linux_console.py | 43 +++
81
target/arm: Implement SVE Floating Point Unary Operations - Unpredicated Group
79
20 files changed, 1760 insertions(+), 209 deletions(-)
82
target/arm: Implement SVE FP Compare with Zero Group
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
83
target/arm: Implement SVE floating-point trig multiply-add coefficient
81
create mode 100644 hw/misc/bcm2835_powermgt.c
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
82
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: Alex Bennée <alex.bennee@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
Since kernel commit a86bd139f2 (arm64: arch_timer: Enable CNTVCT_EL0
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
trap..), released in kernel version v4.12, user-space has been able
4
entry.
5
to read these system registers. As we can't use QEMUTimer's in
6
linux-user mode we just directly call cpu_get_clock().
7
5
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Patrick Venture <venture@google.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20180625160009.17437-2-alex.bennee@linaro.org
8
Message-id: 20210615192848.1065297-2-venture@google.com
11
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
target/arm/helper.c | 27 ++++++++++++++++++++++++---
11
docs/system/arm/aspeed.rst | 1 +
15
1 file changed, 24 insertions(+), 3 deletions(-)
12
1 file changed, 1 insertion(+)
16
13
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
16
--- a/docs/system/arm/aspeed.rst
20
+++ b/target/arm/helper.c
17
+++ b/docs/system/arm/aspeed.rst
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
18
@@ -XXX,XX +XXX,XX @@ etc.
22
};
19
AST2400 SoC based machines :
23
20
24
#else
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
25
-/* In user-mode none of the generic timer registers are accessible,
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
26
- * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
23
27
- * so instead just don't register any of them.
24
AST2500 SoC based machines :
28
+
29
+/* In user-mode most of the generic timer registers are inaccessible
30
+ * however modern kernels (4.12+) allow access to cntvct_el0
31
*/
32
+
33
+static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
34
+{
35
+ /* Currently we have no support for QEMUTimer in linux-user so we
36
+ * can't call gt_get_countervalue(env), instead we directly
37
+ * call the lower level functions.
38
+ */
39
+ return cpu_get_clock() / GTIMER_SCALE;
40
+}
41
+
42
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
43
+ { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
45
+ .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
46
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
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
25
57
--
26
--
58
2.17.1
27
2.20.1
59
28
60
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
This register was added to aa32 state by ARMv8.2.
3
Add line item reference to quanta-gbs-bmc machine.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Patrick Venture <venture@google.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 20180629001538.11415-6-richard.henderson@linaro.org
7
Message-id: 20210615192848.1065297-3-venture@google.com
8
[PMM: fixed underline Sphinx warning]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/cpu.h | 1 +
11
docs/system/arm/nuvoton.rst | 5 +++--
11
target/arm/cpu.c | 4 ++++
12
1 file changed, 3 insertions(+), 2 deletions(-)
12
target/arm/cpu64.c | 2 ++
13
target/arm/helper.c | 5 ++---
14
4 files changed, 9 insertions(+), 3 deletions(-)
15
13
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
16
--- a/docs/system/arm/nuvoton.rst
19
+++ b/target/arm/cpu.h
17
+++ b/docs/system/arm/nuvoton.rst
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
18
@@ -XXX,XX +XXX,XX @@
21
uint32_t id_isar3;
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
22
uint32_t id_isar4;
20
-=====================================================
23
uint32_t id_isar5;
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
24
+ uint32_t id_isar6;
22
+================================================================
25
uint64_t id_aa64pfr0;
23
26
uint64_t id_aa64pfr1;
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
27
uint64_t id_aa64dfr0;
25
designed to be used as Baseboard Management Controllers (BMCs) in various
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
29
index XXXXXXX..XXXXXXX 100644
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
30
--- a/target/arm/cpu.c
28
Hyperscale applications. The following machines are based on this chip :
31
+++ b/target/arm/cpu.c
29
32
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
33
cpu->id_isar3 = 0x01111110;
31
- ``quanta-gsj`` Quanta GSJ server BMC
34
cpu->id_isar4 = 0x01310102;
32
35
cpu->id_isar5 = 0x00000000;
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
36
+ cpu->id_isar6 = 0x00000000;
37
}
38
39
static void cortex_m4_initfn(Object *obj)
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
41
cpu->id_isar3 = 0x01111110;
42
cpu->id_isar4 = 0x01310102;
43
cpu->id_isar5 = 0x00000000;
44
+ cpu->id_isar6 = 0x00000000;
45
}
46
47
static void cortex_m33_initfn(Object *obj)
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
49
cpu->id_isar3 = 0x01111131;
50
cpu->id_isar4 = 0x01310132;
51
cpu->id_isar5 = 0x00000000;
52
+ cpu->id_isar6 = 0x00000000;
53
cpu->clidr = 0x00000000;
54
cpu->ctr = 0x8000c000;
55
}
56
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
57
cpu->id_isar3 = 0x01112131;
58
cpu->id_isar4 = 0x0010142;
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
--
34
--
103
2.17.1
35
2.20.1
104
36
105
37
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This is just enough to make reboot and poweroff work. Works for
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
Message-id: 20180627043328.11531-30-richard.henderson@linaro.org
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
do what linux does for reset.
7
8
The watchdog timer functionality is not yet implemented.
9
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
18
---
8
target/arm/helper-sve.h | 4 +
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
9
target/arm/sve_helper.c | 162 +++++++++++++++++++++++++++++++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
10
target/arm/translate-sve.c | 37 +++++++++
21
hw/arm/bcm2835_peripherals.c | 13 ++-
11
target/arm/sve.decode | 4 +
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
12
4 files changed, 207 insertions(+)
23
hw/misc/meson.build | 1 +
13
24
5 files changed, 204 insertions(+), 2 deletions(-)
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
30
--- a/include/hw/arm/bcm2835_peripherals.h
17
+++ b/target/arm/helper-sve.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
32
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
33
#include "hw/misc/bcm2835_mphi.h"
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
#include "hw/misc/bcm2835_thermal.h"
21
35
#include "hw/misc/bcm2835_cprman.h"
22
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
36
+#include "hw/misc/bcm2835_powermgt.h"
23
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
37
#include "hw/sd/sdhci.h"
24
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
38
#include "hw/sd/bcm2835_sdhost.h"
25
+
39
#include "hw/gpio/bcm2835_gpio.h"
26
DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
27
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
41
BCM2835MphiState mphi;
28
DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
42
UnimplementedDeviceState txp;
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/include/hw/misc/bcm2835_powermgt.h
54
@@ -XXX,XX +XXX,XX @@
55
+/*
56
+ * BCM2835 Power Management emulation
57
+ *
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
63
+ */
64
+
65
+#ifndef BCM2835_POWERMGT_H
66
+#define BCM2835_POWERMGT_H
67
+
68
+#include "hw/sysbus.h"
69
+#include "qom/object.h"
70
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
73
+
74
+struct BCM2835PowerMgtState {
75
+ SysBusDevice busdev;
76
+ MemoryRegion iomem;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
30
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve_helper.c
86
--- a/hw/arm/bcm2835_peripherals.c
32
+++ b/target/arm/sve_helper.c
87
+++ b/hw/arm/bcm2835_peripherals.c
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
34
} while (i != 0);
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
35
}
96
}
36
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
37
+/*
123
+/*
38
+ * FP Complex Multiply
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
39
+ */
131
+ */
40
+
132
+
41
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 22 > 32);
133
+#include "qemu/osdep.h"
42
+
134
+#include "qemu/log.h"
43
+void HELPER(sve_fcmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
135
+#include "qemu/module.h"
44
+{
136
+#include "hw/misc/bcm2835_powermgt.h"
45
+ intptr_t j, i = simd_oprsz(desc);
137
+#include "migration/vmstate.h"
46
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
138
+#include "sysemu/runstate.h"
47
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
139
+
48
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
140
+#define PASSWORD 0x5a000000
49
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
141
+#define PASSWORD_MASK 0xff000000
50
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
142
+
51
+ bool flip = rot & 1;
143
+#define R_RSTC 0x1c
52
+ float16 neg_imag, neg_real;
144
+#define V_RSTC_RESET 0x20
53
+ void *vd = &env->vfp.zregs[rd];
145
+#define R_RSTS 0x20
54
+ void *vn = &env->vfp.zregs[rn];
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
55
+ void *vm = &env->vfp.zregs[rm];
147
+#define R_WDOG 0x24
56
+ void *va = &env->vfp.zregs[ra];
148
+
57
+ uint64_t *g = vg;
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
58
+
150
+ unsigned size)
59
+ neg_imag = float16_set_sign(0, (rot & 2) != 0);
151
+{
60
+ neg_real = float16_set_sign(0, rot == 1 || rot == 2);
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
61
+
153
+ uint32_t res = 0;
62
+ do {
154
+
63
+ uint64_t pg = g[(i - 1) >> 6];
155
+ switch (offset) {
64
+ do {
156
+ case R_RSTC:
65
+ float16 e1, e2, e3, e4, nr, ni, mr, mi, d;
157
+ res = s->rstc;
66
+
158
+ break;
67
+ /* I holds the real index; J holds the imag index. */
159
+ case R_RSTS:
68
+ j = i - sizeof(float16);
160
+ res = s->rsts;
69
+ i -= 2 * sizeof(float16);
161
+ break;
70
+
162
+ case R_WDOG:
71
+ nr = *(float16 *)(vn + H1_2(i));
163
+ res = s->wdog;
72
+ ni = *(float16 *)(vn + H1_2(j));
164
+ break;
73
+ mr = *(float16 *)(vm + H1_2(i));
165
+
74
+ mi = *(float16 *)(vm + H1_2(j));
166
+ default:
75
+
167
+ qemu_log_mask(LOG_UNIMP,
76
+ e2 = (flip ? ni : nr);
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
77
+ e1 = (flip ? mi : mr) ^ neg_real;
169
+ "\n", offset);
78
+ e4 = e2;
170
+ res = 0;
79
+ e3 = (flip ? mr : mi) ^ neg_imag;
171
+ break;
80
+
172
+ }
81
+ if (likely((pg >> (i & 63)) & 1)) {
173
+
82
+ d = *(float16 *)(va + H1_2(i));
174
+ return res;
83
+ d = float16_muladd(e2, e1, d, 0, &env->vfp.fp_status_f16);
175
+}
84
+ *(float16 *)(vd + H1_2(i)) = d;
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
85
+ }
200
+ }
86
+ if (likely((pg >> (j & 63)) & 1)) {
201
+ }
87
+ d = *(float16 *)(va + H1_2(j));
202
+ break;
88
+ d = float16_muladd(e4, e3, d, 0, &env->vfp.fp_status_f16);
203
+ case R_RSTS:
89
+ *(float16 *)(vd + H1_2(j)) = d;
204
+ qemu_log_mask(LOG_UNIMP,
90
+ }
205
+ "bcm2835_powermgt_write: RSTS\n");
91
+ } while (i & 63);
206
+ s->rsts = value;
92
+ } while (i != 0);
207
+ break;
93
+}
208
+ case R_WDOG:
94
+
209
+ qemu_log_mask(LOG_UNIMP,
95
+void HELPER(sve_fcmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
210
+ "bcm2835_powermgt_write: WDOG\n");
96
+{
211
+ s->wdog = value;
97
+ intptr_t j, i = simd_oprsz(desc);
212
+ break;
98
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
213
+
99
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
214
+ default:
100
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
215
+ qemu_log_mask(LOG_UNIMP,
101
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
102
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
217
+ "\n", offset);
103
+ bool flip = rot & 1;
218
+ break;
104
+ float32 neg_imag, neg_real;
219
+ }
105
+ void *vd = &env->vfp.zregs[rd];
220
+}
106
+ void *vn = &env->vfp.zregs[rn];
221
+
107
+ void *vm = &env->vfp.zregs[rm];
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
108
+ void *va = &env->vfp.zregs[ra];
223
+ .read = bcm2835_powermgt_read,
109
+ uint64_t *g = vg;
224
+ .write = bcm2835_powermgt_write,
110
+
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
111
+ neg_imag = float32_set_sign(0, (rot & 2) != 0);
226
+ .impl.min_access_size = 4,
112
+ neg_real = float32_set_sign(0, rot == 1 || rot == 2);
227
+ .impl.max_access_size = 4,
113
+
228
+};
114
+ do {
229
+
115
+ uint64_t pg = g[(i - 1) >> 6];
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
116
+ do {
231
+ .name = TYPE_BCM2835_POWERMGT,
117
+ float32 e1, e2, e3, e4, nr, ni, mr, mi, d;
232
+ .version_id = 1,
118
+
233
+ .minimum_version_id = 1,
119
+ /* I holds the real index; J holds the imag index. */
234
+ .fields = (VMStateField[]) {
120
+ j = i - sizeof(float32);
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
121
+ i -= 2 * sizeof(float32);
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
122
+
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
123
+ nr = *(float32 *)(vn + H1_2(i));
238
+ VMSTATE_END_OF_LIST()
124
+ ni = *(float32 *)(vn + H1_2(j));
239
+ }
125
+ mr = *(float32 *)(vm + H1_2(i));
240
+};
126
+ mi = *(float32 *)(vm + H1_2(j));
241
+
127
+
242
+static void bcm2835_powermgt_init(Object *obj)
128
+ e2 = (flip ? ni : nr);
243
+{
129
+ e1 = (flip ? mi : mr) ^ neg_real;
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
130
+ e4 = e2;
245
+
131
+ e3 = (flip ? mr : mi) ^ neg_imag;
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
132
+
247
+ TYPE_BCM2835_POWERMGT, 0x200);
133
+ if (likely((pg >> (i & 63)) & 1)) {
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
134
+ d = *(float32 *)(va + H1_2(i));
249
+}
135
+ d = float32_muladd(e2, e1, d, 0, &env->vfp.fp_status);
250
+
136
+ *(float32 *)(vd + H1_2(i)) = d;
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
137
+ }
252
+{
138
+ if (likely((pg >> (j & 63)) & 1)) {
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
139
+ d = *(float32 *)(va + H1_2(j));
254
+
140
+ d = float32_muladd(e4, e3, d, 0, &env->vfp.fp_status);
255
+ /* https://elinux.org/BCM2835_registers#PM */
141
+ *(float32 *)(vd + H1_2(j)) = d;
256
+ s->rstc = 0x00000102;
142
+ }
257
+ s->rsts = 0x00001000;
143
+ } while (i & 63);
258
+ s->wdog = 0x00000000;
144
+ } while (i != 0);
259
+}
145
+}
260
+
146
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
147
+void HELPER(sve_fcmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
262
+{
148
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
149
+ intptr_t j, i = simd_oprsz(desc);
264
+
150
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
265
+ dc->reset = bcm2835_powermgt_reset;
151
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
152
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
267
+}
153
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
268
+
154
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
269
+static TypeInfo bcm2835_powermgt_info = {
155
+ bool flip = rot & 1;
270
+ .name = TYPE_BCM2835_POWERMGT,
156
+ float64 neg_imag, neg_real;
271
+ .parent = TYPE_SYS_BUS_DEVICE,
157
+ void *vd = &env->vfp.zregs[rd];
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
158
+ void *vn = &env->vfp.zregs[rn];
273
+ .class_init = bcm2835_powermgt_class_init,
159
+ void *vm = &env->vfp.zregs[rm];
274
+ .instance_init = bcm2835_powermgt_init,
160
+ void *va = &env->vfp.zregs[ra];
275
+};
161
+ uint64_t *g = vg;
276
+
162
+
277
+static void bcm2835_powermgt_register_types(void)
163
+ neg_imag = float64_set_sign(0, (rot & 2) != 0);
278
+{
164
+ neg_real = float64_set_sign(0, rot == 1 || rot == 2);
279
+ type_register_static(&bcm2835_powermgt_info);
165
+
280
+}
166
+ do {
281
+
167
+ uint64_t pg = g[(i - 1) >> 6];
282
+type_init(bcm2835_powermgt_register_types)
168
+ do {
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
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
+}
198
+
199
/*
200
* Load contiguous data, protected by a governing predicate.
201
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
203
index XXXXXXX..XXXXXXX 100644
284
index XXXXXXX..XXXXXXX 100644
204
--- a/target/arm/translate-sve.c
285
--- a/hw/misc/meson.build
205
+++ b/target/arm/translate-sve.c
286
+++ b/hw/misc/meson.build
206
@@ -XXX,XX +XXX,XX @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
207
288
'bcm2835_rng.c',
208
#undef DO_FMLA
289
'bcm2835_thermal.c',
209
290
'bcm2835_cprman.c',
210
+static bool trans_FCMLA_zpzzz(DisasContext *s,
291
+ 'bcm2835_powermgt.c',
211
+ arg_FCMLA_zpzzz *a, uint32_t insn)
292
))
212
+{
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
213
+ static gen_helper_sve_fmla * const fns[3] = {
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
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
+}
246
+
247
/*
248
*** SVE Floating Point Unary Operations Predicated Group
249
*/
250
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
251
index XXXXXXX..XXXXXXX 100644
252
--- a/target/arm/sve.decode
253
+++ b/target/arm/sve.decode
254
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
255
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
256
rn=%reg_movprfx
257
258
+# SVE floating-point complex multiply-add (predicated)
259
+FCMLA_zpzzz 01100100 esz:2 0 rm:5 0 rot:2 pg:3 rn:5 rd:5 \
260
+ ra=%reg_movprfx
261
+
262
### SVE FP Multiply-Add Indexed Group
263
264
# SVE floating-point multiply-add (indexed)
265
--
295
--
266
2.17.1
296
2.20.1
267
297
268
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The load/store API will ease further code movement.
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
4
5
5
Per the Physical Layer Simplified Spec. "3.6 Bus Protocol":
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
"In the CMD line the Most Significant Bit (MSB) is transmitted
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
8
first, the Least Significant Bit (LSB) is the last."
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
9
44
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
49
---
14
hw/sd/bcm2835_sdhost.c | 13 +++++--------
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
15
hw/sd/milkymist-memcard.c | 3 +--
51
1 file changed, 43 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
52
22
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
23
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/sd/bcm2835_sdhost.c
55
--- a/tests/acceptance/boot_linux_console.py
25
+++ b/hw/sd/bcm2835_sdhost.c
56
+++ b/tests/acceptance/boot_linux_console.py
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
57
@@ -XXX,XX +XXX,XX @@
27
goto error;
58
from avocado import skip
28
}
59
from avocado import skipUnless
29
if (!(s->cmd & SDCMD_NO_RESPONSE)) {
60
from avocado_qemu import Test
30
-#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
61
+from avocado_qemu import exec_command
31
- | (rsp[n + 2] << 8) | rsp[n + 3])
62
from avocado_qemu import exec_command_and_wait_for_pattern
32
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
63
from avocado_qemu import interrupt_interactive_console_until_pattern
33
goto error;
64
from avocado_qemu import wait_for_console_pattern
34
}
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
35
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
66
"""
36
goto error;
67
self.do_test_arm_raspi2(0)
37
}
68
38
if (rlen == 4) {
69
+ def test_arm_raspi2_initrd(self):
39
- s->rsp[0] = RWORD(0);
70
+ """
40
+ s->rsp[0] = ldl_be_p(&rsp[0]);
71
+ :avocado: tags=arch:arm
41
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
72
+ :avocado: tags=machine:raspi2
42
} else {
73
+ """
43
- s->rsp[0] = RWORD(12);
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
44
- s->rsp[1] = RWORD(8);
75
+ 'pool/main/r/raspberrypi-firmware/'
45
- s->rsp[2] = RWORD(4);
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
46
- s->rsp[3] = RWORD(0);
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
47
+ s->rsp[0] = ldl_be_p(&rsp[12]);
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
48
+ s->rsp[1] = ldl_be_p(&rsp[8]);
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
49
+ s->rsp[2] = ldl_be_p(&rsp[4]);
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
50
+ s->rsp[3] = ldl_be_p(&rsp[0]);
81
+
51
}
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
52
-#undef RWORD
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
53
}
84
+ 'arm/rootfs-armv7a.cpio.gz')
54
/* We never really delay commands, so if this was a 'busywait' command
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
55
* then we've completed it now and can raise the interrupt.
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
56
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
57
index XXXXXXX..XXXXXXX 100644
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
58
--- a/hw/sd/milkymist-memcard.c
89
+
59
+++ b/hw/sd/milkymist-memcard.c
90
+ self.vm.set_console()
60
@@ -XXX,XX +XXX,XX @@ static void memcard_sd_command(MilkymistMemcardState *s)
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
61
SDRequest req;
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
62
93
+ 'panic=-1 noreboot ' +
63
req.cmd = s->command[0] & 0x3f;
94
+ 'dwc_otg.fiq_fsm_enable=0')
64
- req.arg = (s->command[1] << 24) | (s->command[2] << 16)
95
+ self.vm.add_args('-kernel', kernel_path,
65
- | (s->command[3] << 8) | s->command[4];
96
+ '-dtb', dtb_path,
66
+ req.arg = ldl_be_p(s->command + 1);
97
+ '-initrd', initrd_path,
67
req.crc = s->command[5];
98
+ '-append', kernel_command_line,
68
99
+ '-no-reboot')
69
s->response[0] = req.cmd;
100
+ self.vm.launch()
70
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
101
+ self.wait_for_console_pattern('Boot successful.')
71
index XXXXXXX..XXXXXXX 100644
102
+
72
--- a/hw/sd/omap_mmc.c
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
73
+++ b/hw/sd/omap_mmc.c
104
+ 'BCM2835')
74
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
75
CID_CSD_OVERWRITE;
106
+ '/soc/cprman@7e101000')
76
if (host->sdio & (1 << 13))
107
+ exec_command(self, 'halt')
77
mask |= AKE_SEQ_ERROR;
108
+ # Wait for VM to shut down gracefully
78
- rspstatus = (response[0] << 24) | (response[1] << 16) |
109
+ self.vm.wait()
79
- (response[2] << 8) | (response[3] << 0);
110
+
80
+ rspstatus = ldl_be_p(response);
111
def test_arm_exynos4210_initrd(self):
81
break;
112
"""
82
113
:avocado: tags=arch:arm
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
--
114
--
187
2.17.1
115
2.20.1
188
116
189
117
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
The qdev_get_gpio_in() function accept an int as second parameter.
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
4
6
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
To avoid this, we check to see what NaN mode we're running in before we call
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
hw/arm/fsl-imx7.c | 6 +++---
16
target/arm/helper-a64.c | 12 +++++++++---
11
1 file changed, 3 insertions(+), 3 deletions(-)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
12
19
13
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx7.c
22
--- a/target/arm/helper-a64.c
16
+++ b/hw/arm/fsl-imx7.c
23
+++ b/target/arm/helper-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
18
FSL_IMX7_ECSPI4_ADDR,
25
float16 nan = a;
19
};
26
if (float16_is_signaling_nan(a, fpst)) {
20
27
float_raise(float_flag_invalid, fpst);
21
- static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
28
- nan = float16_silence_nan(a, fpst);
22
+ static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
29
+ if (!fpst->default_nan_mode) {
23
FSL_IMX7_ECSPI1_IRQ,
30
+ nan = float16_silence_nan(a, fpst);
24
FSL_IMX7_ECSPI2_IRQ,
31
+ }
25
FSL_IMX7_ECSPI3_IRQ,
32
}
26
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
33
if (fpst->default_nan_mode) {
27
FSL_IMX7_I2C4_ADDR,
34
nan = float16_default_nan(fpst);
28
};
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
29
36
float32 nan = a;
30
- static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
37
if (float32_is_signaling_nan(a, fpst)) {
31
+ static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
38
float_raise(float_flag_invalid, fpst);
32
FSL_IMX7_I2C1_IRQ,
39
- nan = float32_silence_nan(a, fpst);
33
FSL_IMX7_I2C2_IRQ,
40
+ if (!fpst->default_nan_mode) {
34
FSL_IMX7_I2C3_IRQ,
41
+ nan = float32_silence_nan(a, fpst);
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
42
+ }
36
FSL_IMX7_USB3_ADDR,
43
}
37
};
44
if (fpst->default_nan_mode) {
38
45
nan = float32_default_nan(fpst);
39
- static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
40
+ static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
47
float64 nan = a;
41
FSL_IMX7_USB1_IRQ,
48
if (float64_is_signaling_nan(a, fpst)) {
42
FSL_IMX7_USB2_IRQ,
49
float_raise(float_flag_invalid, fpst);
43
FSL_IMX7_USB3_IRQ,
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
44
--
127
--
45
2.17.1
128
2.20.1
46
129
47
130
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
5
Message-id: 20180627043328.11531-29-richard.henderson@linaro.org
10
[PMM: tweaked commit message]
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
hw/gpio/gpio_pwr.c | 2 +-
9
target/arm/sve_helper.c | 100 +++++++++++++++++++++++++++++++++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
target/arm/translate-sve.c | 24 +++++++++
11
target/arm/sve.decode | 4 ++
12
4 files changed, 135 insertions(+)
13
15
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
18
--- a/hw/gpio/gpio_pwr.c
17
+++ b/target/arm/helper-sve.h
19
+++ b/hw/gpio/gpio_pwr.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
19
DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
20
void, ptr, ptr, ptr, ptr, ptr, i32)
22
{
21
23
if (level) {
22
+DEF_HELPER_FLAGS_6(sve_fcadd_h, TCG_CALL_NO_RWG,
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
24
+DEF_HELPER_FLAGS_6(sve_fcadd_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fcadd_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+
29
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
30
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
31
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
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 @@ void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
37
}
26
}
38
}
27
}
39
28
40
+/*
41
+ * FP Complex Add
42
+ */
43
+
44
+void HELPER(sve_fcadd_h)(void *vd, void *vn, void *vm, void *vg,
45
+ void *vs, uint32_t desc)
46
+{
47
+ intptr_t j, i = simd_oprsz(desc);
48
+ uint64_t *g = vg;
49
+ float16 neg_imag = float16_set_sign(0, simd_data(desc));
50
+ float16 neg_real = float16_chs(neg_imag);
51
+
52
+ do {
53
+ uint64_t pg = g[(i - 1) >> 6];
54
+ do {
55
+ float16 e0, e1, e2, e3;
56
+
57
+ /* I holds the real index; J holds the imag index. */
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
+}
75
+
76
+void HELPER(sve_fcadd_s)(void *vd, void *vn, void *vm, void *vg,
77
+ void *vs, uint32_t desc)
78
+{
79
+ intptr_t j, i = simd_oprsz(desc);
80
+ uint64_t *g = vg;
81
+ float32 neg_imag = float32_set_sign(0, simd_data(desc));
82
+ float32 neg_real = float32_chs(neg_imag);
83
+
84
+ do {
85
+ uint64_t pg = g[(i - 1) >> 6];
86
+ do {
87
+ float32 e0, e1, e2, e3;
88
+
89
+ /* I holds the real index; J holds the imag index. */
90
+ j = i - sizeof(float32);
91
+ i -= 2 * sizeof(float32);
92
+
93
+ e0 = *(float32 *)(vn + H1_2(i));
94
+ e1 = *(float32 *)(vm + H1_2(j)) ^ neg_real;
95
+ e2 = *(float32 *)(vn + H1_2(j));
96
+ e3 = *(float32 *)(vm + H1_2(i)) ^ neg_imag;
97
+
98
+ if (likely((pg >> (i & 63)) & 1)) {
99
+ *(float32 *)(vd + H1_2(i)) = float32_add(e0, e1, vs);
100
+ }
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
+
108
+void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
109
+ void *vs, uint32_t desc)
110
+{
111
+ intptr_t j, i = simd_oprsz(desc);
112
+ uint64_t *g = vg;
113
+ float64 neg_imag = float64_set_sign(0, simd_data(desc));
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
+ if (sve_access_check(s)) {
163
+ unsigned vsz = vec_full_reg_size(s);
164
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
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
--
29
--
194
2.17.1
30
2.20.1
195
31
196
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In do_ldst(), the calculation of the offset needs to be based on the
2
size of the memory access, not the size of the elements in the
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
2
5
3
We've already added the helpers with an SVE patch, all that remains
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
is to wire up the aa64 and aa32 translators. Enable the feature
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
within -cpu max for CONFIG_USER_ONLY.
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-mve.c | 17 +++++++++--------
11
1 file changed, 9 insertions(+), 8 deletions(-)
6
12
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180627043328.11531-36-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
linux-user/elfload.c | 1 +
14
target/arm/cpu.c | 1 +
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
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
15
--- a/target/arm/translate-mve.c
23
+++ b/target/arm/cpu.h
16
+++ b/target/arm/translate-mve.c
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
25
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
26
ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
27
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
28
+ ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
29
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
30
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
38
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
39
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
40
+ GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
41
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
42
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
43
#undef GET_FEATURE
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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
}
18
}
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu64.c
59
+++ b/target/arm/cpu64.c
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
61
set_feature(&cpu->env, ARM_FEATURE_CRC);
62
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
63
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
64
+ set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
65
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
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
}
19
}
75
20
76
+/* Expand a 3-operand operation using an out-of-line helper. */
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
77
+static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
78
+ int rn, int rm, int data, gen_helper_gvec_3 *fn)
23
+ unsigned msize)
79
+{
24
{
80
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
25
TCGv_i32 addr;
81
+ vec_full_reg_offset(s, rn),
26
uint32_t offset;
82
+ vec_full_reg_offset(s, rm),
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
83
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
28
return true;
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
}
29
}
132
30
133
switch (16 * u + opcode) {
31
- offset = a->imm << a->size;
134
+ case 0x0e: /* SDOT */
32
+ offset = a->imm << msize;
135
+ case 0x1e: /* UDOT */
33
if (!a->a) {
136
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, index,
34
offset = -offset;
137
+ u ? gen_helper_gvec_udot_idx_b
35
}
138
+ : gen_helper_gvec_sdot_idx_b);
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
139
+ return;
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
140
case 0x11: /* FCMLA #0 */
38
{ NULL, NULL }
141
case 0x13: /* FCMLA #90 */
39
};
142
case 0x15: /* FCMLA #180 */
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
143
diff --git a/target/arm/translate.c b/target/arm/translate.c
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
144
index XXXXXXX..XXXXXXX 100644
42
}
145
--- a/target/arm/translate.c
43
146
+++ b/target/arm/translate.c
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
147
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
148
*/
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
149
static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
47
{ \
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
50
{ NULL, gen_helper_mve_##ULD }, \
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
54
}
55
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
62
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
150
{
64
{
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
}
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
276
--
65
--
277
2.17.1
66
2.20.1
278
67
279
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
In particular, fixing the second of these allows us to recast
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
the implementation to avoid 128-bit arithmetic entirely.
5
Message-id: 20180627043328.11531-7-richard.henderson@linaro.org
12
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
7
---
20
---
8
target/arm/helper-sve.h | 77 +++++++++++++++++++++++++++++++++
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
9
target/arm/sve_helper.c | 89 ++++++++++++++++++++++++++++++++++++++
22
1 file changed, 21 insertions(+), 17 deletions(-)
10
target/arm/translate-sve.c | 46 ++++++++++++++++++++
11
target/arm/sve.decode | 17 ++++++++
12
4 files changed, 229 insertions(+)
13
23
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
26
--- a/target/arm/mve_helper.c
17
+++ b/target/arm/helper-sve.h
27
+++ b/target/arm/mve_helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
28
@@ -XXX,XX +XXX,XX @@
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
*/
29
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
30
203
index XXXXXXX..XXXXXXX 100644
31
#include "qemu/osdep.h"
204
--- a/target/arm/translate-sve.c
32
-#include "qemu/int128.h"
205
+++ b/target/arm/translate-sve.c
33
#include "cpu.h"
206
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
34
#include "internals.h"
207
35
#include "vec_internal.h"
208
#undef DO_FP3
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
209
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
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
38
257
/*
39
/*
258
*** SVE Floating Point Unary Operations Predicated Group
40
- * Rounding multiply add long dual accumulate high: we must keep
259
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
41
- * a 72-bit internal accumulator value and return the top 64 bits.
260
index XXXXXXX..XXXXXXX 100644
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
261
--- a/target/arm/sve.decode
43
+ * this is implemented with a 72-bit internal accumulator value of which
262
+++ b/target/arm/sve.decode
44
+ * the top 64 bits are returned. We optimize this to avoid having to
263
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
264
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
46
+ * is squashed back into 64-bits after each beat.
265
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
47
*/
266
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
267
+### SVE FP Arithmetic Predicated Group
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
268
+
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
269
+# SVE floating-point arithmetic (predicated)
51
void *vm, uint64_t a) \
270
+FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
52
{ \
271
+FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
53
uint16_t mask = mve_element_mask(env); \
272
+FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
54
unsigned e; \
273
+FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR
55
TYPE *n = vn, *m = vm; \
274
+FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
56
- Int128 acc = int128_lshift(TO128(a), 8); \
275
+FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
276
+FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
277
+FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
59
if (mask & 1) { \
278
+FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm
60
+ LTYPE mul; \
279
+FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm
61
if (e & 1) { \
280
+FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
281
+FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
63
- m[H##ESIZE(e)])); \
282
+FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
283
+
65
+ if (SUB) { \
284
### SVE FP Unary Operations Predicated Group
66
+ mul = -mul; \
285
67
+ } \
286
# SVE integer convert to floating-point
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
82
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
87
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
287
--
98
--
288
2.17.1
99
2.20.1
289
100
290
101
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
2
5
3
This helper allows to retrieve the paths of nodes whose name
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
match node-name or node-name@unit-address patterns.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
5
14
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
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
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/sysemu/device_tree.h
17
--- a/target/arm/translate.h
18
+++ b/include/sysemu/device_tree.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
20
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
20
return opc | s->be_data;
21
Error **errp);
21
}
22
22
23
+/**
23
+/**
24
+ * qemu_fdt_node_unit_path: return the paths of nodes matching a given
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
25
+ * node-name, ie. node-name and node-name@unit-address
26
+ * @fdt: pointer to the dt blob
27
+ * @name: node name
28
+ * @errp: handle to an error object
29
+ *
25
+ *
30
+ * returns a newly allocated NULL-terminated array of node paths.
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
31
+ * Use g_strfreev() to free it. If one or more nodes were found, the
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
32
+ * array contains the path of each node and the last element equals to
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
33
+ * NULL. If there is no error but no matching node was found, the
29
+ *
34
+ * returned array contains a single element equal to NULL. If an error
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
35
+ * was encountered when parsing the blob, the function returns NULL
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
36
+ */
37
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
38
+
39
int qemu_fdt_setprop(void *fdt, const char *node_path,
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
const char *property, const void *val, int size);
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
42
diff --git a/device_tree.c b/device_tree.c
43
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
44
--- a/device_tree.c
42
--- a/target/arm/translate-neon.c
45
+++ b/device_tree.c
43
+++ b/target/arm/translate-neon.c
46
@@ -XXX,XX +XXX,XX @@ static int findnode_nofail(void *fdt, const char *node_path)
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
47
return offset;
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
48
}
120
}
49
121
50
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
51
+{
123
+{
52
+ char *prefix = g_strdup_printf("%s@", name);
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
53
+ unsigned int path_len = 16, n = 0;
125
+ switch (cmode) {
54
+ GSList *path_list = NULL, *iter;
126
+ case 0: case 1:
55
+ const char *iter_name;
127
+ /* no-op */
56
+ int offset, len, ret;
128
+ break;
57
+ char **path_array;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
58
+
158
+
59
+ offset = fdt_next_node(fdt, -1, NULL);
159
+ for (n = 0; n < 8; n++) {
60
+
160
+ if (imm & (1 << n)) {
61
+ while (offset >= 0) {
161
+ imm64 |= (0xffULL << (n * 8));
62
+ iter_name = fdt_get_name(fdt, offset, &len);
162
+ }
63
+ if (!iter_name) {
163
+ }
64
+ offset = len;
164
+ return imm64;
65
+ break;
66
+ }
165
+ }
67
+ if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
68
+ char *path;
167
+ break;
69
+
168
+ case 15:
70
+ path = g_malloc(path_len);
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
71
+ while ((ret = fdt_get_path(fdt, offset, path, path_len))
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
72
+ == -FDT_ERR_NOSPACE) {
171
+ break;
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
+ }
172
+ }
81
+ g_free(prefix);
173
+ if (op) {
82
+
174
+ imm = ~imm;
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
+ }
175
+ }
92
+
176
+ return dup_const(MO_32, imm);
93
+ path_array = g_new(char *, n + 1);
94
+ path_array[n--] = NULL;
95
+
96
+ for (iter = path_list; iter; iter = iter->next) {
97
+ path_array[n--] = iter->data;
98
+ }
99
+
100
+ g_slist_free(path_list);
101
+
102
+ return path_array;
103
+}
177
+}
104
+
178
+
105
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
179
/* Generate a label used for skipping this instruction */
106
Error **errp)
180
void arm_gen_condlabel(DisasContext *s)
107
{
181
{
108
--
182
--
109
2.17.1
183
2.20.1
110
184
111
185
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: Eric Auger <eric.auger@redhat.com>
2
1
3
When running dtc on the guest /proc/device-tree we get the
4
following warning: Warning (unit_address_vs_reg): Node /memory
5
has a reg or ranges property, but no unit name".
6
7
Let's fix that by adding the unit address to the node name. We also
8
don't create the /memory node anymore in create_fdt(). We directly
9
create it in load_dtb. /chosen still needs to be created in create_fdt
10
as the uart needs it. In case the user provided his own dtb, we nop
11
all memory nodes found in root and create new one(s).
12
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 1530044492-24921-4-git-send-email-eric.auger@redhat.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/arm/boot.c | 41 +++++++++++++++++++++++------------------
19
hw/arm/virt.c | 7 +------
20
2 files changed, 24 insertions(+), 24 deletions(-)
21
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
25
+++ b/hw/arm/boot.c
26
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
27
hwaddr addr_limit, AddressSpace *as)
28
{
29
void *fdt = NULL;
30
- int size, rc;
31
+ int size, rc, n = 0;
32
uint32_t acells, scells;
33
char *nodename;
34
unsigned int i;
35
hwaddr mem_base, mem_len;
36
+ char **node_path;
37
+ Error *err = NULL;
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
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/arm/virt.c
102
+++ b/hw/arm/virt.c
103
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
104
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
105
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
106
107
- /*
108
- * /chosen and /memory nodes must exist for load_dtb
109
- * to fill in necessary properties later
110
- */
111
+ /* /chosen must exist for load_dtb to fill in necessary properties later */
112
qemu_fdt_add_subnode(fdt, "/chosen");
113
- qemu_fdt_add_subnode(fdt, "/memory");
114
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
115
116
/* Clock node, for the benefit of the UART. The kernel device tree
117
* binding documentation claims the PL011 node clock properties are
118
--
119
2.17.1
120
121
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
2
5
3
For aa64 advsimd, we had been passing the pre-indexed vector.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
However, sve applies the index to each 128-bit segment, so we
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
need to pass in the index separately.
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 3 +-
11
target/arm/translate-a64.c | 86 ++++----------------------------------
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
6
14
7
For aa32 advsimd, the fp32 operation always has index 0, but
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
8
we failed to interpret the fp16 index correctly.
16
index XXXXXXX..XXXXXXX 100644
9
17
--- a/target/arm/translate.h
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
+++ b/target/arm/translate.h
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
* VMVN and VBIC (when cmode < 14 && op == 1).
13
Message-id: 20180627043328.11531-31-richard.henderson@linaro.org
21
*
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
15
---
23
- * callers must catch this.
16
target/arm/translate-a64.c | 21 ++++++++++++---------
24
+ * callers must catch this; we return the 64-bit constant value defined
17
target/arm/translate.c | 32 +++++++++++++++++++++++---------
25
+ * for AArch64.
18
target/arm/vec_helper.c | 10 ++++++----
26
*
19
3 files changed, 41 insertions(+), 22 deletions(-)
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
20
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
26
case 0x13: /* FCMLA #90 */
34
{
27
case 0x15: /* FCMLA #180 */
35
int rd = extract32(insn, 0, 5);
28
case 0x17: /* FCMLA #270 */
36
int cmode = extract32(insn, 12, 4);
29
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
37
- int cmode_3_1 = extract32(cmode, 1, 3);
30
- vec_full_reg_offset(s, rn),
38
- int cmode_0 = extract32(cmode, 0, 1);
31
- vec_reg_offset(s, rm, index, size), fpst,
39
int o2 = extract32(insn, 11, 1);
32
- is_q ? 16 : 8, vec_full_reg_size(s),
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
33
- extract32(insn, 13, 2), /* rot */
41
bool is_neg = extract32(insn, 29, 1);
34
- size == MO_64
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
35
- ? gen_helper_gvec_fcmlas_idx
36
- : gen_helper_gvec_fcmlah_idx);
37
- tcg_temp_free_ptr(fpst);
38
+ {
39
+ int rot = extract32(insn, 13, 2);
40
+ int data = (index << 2) | rot;
41
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
42
+ vec_full_reg_offset(s, rn),
43
+ vec_full_reg_offset(s, rm), fpst,
44
+ is_q ? 16 : 8, vec_full_reg_size(s), data,
45
+ size == MO_64
46
+ ? gen_helper_gvec_fcmlas_idx
47
+ : gen_helper_gvec_fcmlah_idx);
48
+ tcg_temp_free_ptr(fpst);
49
+ }
50
return;
43
return;
51
}
44
}
52
45
46
- /* See AdvSIMDExpandImm() in ARM ARM */
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
131
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
54
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.c
135
--- a/target/arm/translate.c
56
+++ b/target/arm/translate.c
136
+++ b/target/arm/translate.c
57
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
58
138
case 14:
59
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
139
if (op) {
60
{
140
/*
61
- int rd, rn, rm, rot, size, opr_sz;
141
- * This is the only case where the top and bottom 32 bits
62
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
142
- * of the encoded constant differ.
63
+ int rd, rn, rm, opr_sz, data;
143
+ * This and cmode == 15 op == 1 are the only cases where
64
TCGv_ptr fpst;
144
+ * the top and bottom 32 bits of the encoded constant differ.
65
bool q;
145
*/
66
146
uint64_t imm64 = 0;
67
q = extract32(insn, 6, 1);
147
int n;
68
VFP_DREG_D(rd, insn);
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
69
VFP_DREG_N(rn, insn);
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
70
- VFP_DREG_M(rm, insn);
150
break;
71
if ((rd | rn) & q) {
151
case 15:
72
return 1;
152
+ if (op) {
73
}
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
74
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
75
if ((insn & 0xff000f10) == 0xfe000800) {
155
+ if (imm & 0x80) {
76
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
156
+ imm64 |= 0x8000000000000000ULL;
77
- rot = extract32(insn, 20, 2);
78
- size = extract32(insn, 23, 1);
79
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
80
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
81
+ int rot = extract32(insn, 20, 2);
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
}
88
+ if (size == 0) {
89
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
90
+ return 1;
91
+ }
157
+ }
92
+ /* For fp16, rm is just Vm, and index is M. */
158
+ if (imm & 0x40) {
93
+ rm = extract32(insn, 0, 4);
159
+ imm64 |= 0x3fc0000000000000ULL;
94
+ index = extract32(insn, 5, 1);
160
+ } else {
95
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
96
+ /* For fp32, rm is the usual M:Vm, and index is 0. */
162
+ }
97
+ VFP_DREG_M(rm, insn);
163
+ return imm64;
98
+ index = 0;
99
+ }
164
+ }
100
+ data = (index << 2) | rot;
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
101
+ fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
102
+ : gen_helper_gvec_fcmlah_idx);
167
break;
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
--
168
--
150
2.17.1
169
2.20.1
151
170
152
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
Leave ARM_CP_SVE, removing ARM_CP_FPU; the sve_access_check
4
(We can't replace the other use of bitfield_replicate() in this file,
4
produced by the flag already includes fp_access_check. If
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
we also check ARM_CP_FPU the double fp_access_check asserts.
6
and 4 bit elements, which dup_const() cannot.)
6
7
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
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
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Message-id: 20180629001538.11415-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
14
---
11
---
15
target/arm/helper.c | 8 ++++----
12
target/arm/translate-a64.c | 2 +-
16
target/arm/translate-a64.c | 5 ++---
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
2 files changed, 6 insertions(+), 7 deletions(-)
18
14
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
24
static const ARMCPRegInfo zcr_el1_reginfo = {
25
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
26
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
27
- .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
28
+ .access = PL1_RW, .type = ARM_CP_SVE,
29
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
30
.writefn = zcr_write, .raw_writefn = raw_write
31
};
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
33
static const ARMCPRegInfo zcr_el2_reginfo = {
34
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
35
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
36
- .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
37
+ .access = PL2_RW, .type = ARM_CP_SVE,
38
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
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
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
59
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
62
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
63
default:
20
/* FMOV (vector, immediate) - half-precision */
64
break;
21
imm = vfp_expand_imm(MO_16, abcdefgh);
22
/* now duplicate across the lanes */
23
- imm = bitfield_replicate(imm, 16);
24
+ imm = dup_const(MO_16, imm);
25
} else {
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
65
}
27
}
66
- if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
67
- return;
68
- }
69
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
70
return;
71
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
72
+ return;
73
}
74
75
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
76
--
28
--
77
2.17.1
29
2.20.1
78
30
79
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper-sve.h | 35 +++++++++
10
target/arm/helper-mve.h | 4 +++
10
target/arm/sve_helper.c | 153 +++++++++++++++++++++++++++++++++++++
11
target/arm/mve.decode | 17 +++++++++++++
11
target/arm/translate-sve.c | 121 +++++++++++++++++++++++++++++
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
12
target/arm/sve.decode | 34 +++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 343 insertions(+)
14
4 files changed, 95 insertions(+)
14
15
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper-sve.h
19
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
void, ptr, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
23
+
24
+
24
+DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
25
+DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
+DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
27
+DEF_HELPER_FLAGS_4(sve_ld4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
31
+++ b/target/arm/mve.decode
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
28
+
38
+
29
+DEF_HELPER_FLAGS_4(sve_ld1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
&vldr_vstr rn qd imm p a w size l u
30
+DEF_HELPER_FLAGS_4(sve_ld2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
&1op qd qm size
31
+DEF_HELPER_FLAGS_4(sve_ld3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
&2op qd qm qn size
32
+DEF_HELPER_FLAGS_4(sve_ld4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
33
+
59
+
34
+DEF_HELPER_FLAGS_4(sve_ld1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
60
+# Logical immediate operations (1 reg and modified-immediate)
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
+
61
+
39
+DEF_HELPER_FLAGS_4(sve_ld1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
40
+DEF_HELPER_FLAGS_4(sve_ld2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
63
+# not in a way we can conveniently represent in decodetree without
41
+DEF_HELPER_FLAGS_4(sve_ld3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
64
+# a lot of repetition:
42
+DEF_HELPER_FLAGS_4(sve_ld4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
43
+
94
+
44
+DEF_HELPER_FLAGS_4(sve_ld1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
95
+#define DO_MOVI(N, I) (I)
45
+DEF_HELPER_FLAGS_4(sve_ld1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
96
+#define DO_ANDI(N, I) ((N) & (I))
46
+DEF_HELPER_FLAGS_4(sve_ld1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
97
+#define DO_ORRI(N, I) ((N) | (I))
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
+
98
+
51
+DEF_HELPER_FLAGS_4(sve_ld1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
99
+DO_1OP_IMM(vmovi, DO_MOVI)
52
+DEF_HELPER_FLAGS_4(sve_ld1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
100
+DO_1OP_IMM(vandi, DO_ANDI)
53
+DEF_HELPER_FLAGS_4(sve_ld1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
101
+DO_1OP_IMM(vorri, DO_ORRI)
54
+DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+
102
+
56
+DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
57
+DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
59
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
108
--- a/target/arm/translate-mve.c
61
+++ b/target/arm/sve_helper.c
109
+++ b/target/arm/translate-mve.c
62
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
64
return predtest_ones(d, oprsz, esz_mask);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
65
}
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
66
+
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
67
+/*
115
68
+ * Load contiguous data, protected by a governing predicate.
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
69
+ */
117
static inline long mve_qreg_offset(unsigned reg)
70
+#define DO_LD1(NAME, FN, TYPEE, TYPEM, H) \
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
71
+static void do_##NAME(CPUARMState *env, void *vd, void *vg, \
119
mve_update_eci(s);
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;
120
return true;
251
}
121
}
252
+
122
+
253
+/*
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
254
+ *** SVE Memory - Contiguous Load Group
124
+{
255
+ */
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
256
+
127
+
257
+/* The memory mode of the dtype. */
128
+ if (!dc_isar_feature(aa32_mve, s) ||
258
+static const TCGMemOp dtype_mop[16] = {
129
+ !mve_check_qreg_bank(s, a->qd) ||
259
+ MO_UB, MO_UB, MO_UB, MO_UB,
130
+ !fn) {
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;
131
+ return false;
337
+ }
132
+ }
338
+ if (sve_access_check(s)) {
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
339
+ TCGv_i64 addr = new_tmp_a64(s);
134
+ return true;
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
+ }
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
345
+ return true;
143
+ return true;
346
+}
144
+}
347
+
145
+
348
+static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
349
+{
147
+{
350
+ if (sve_access_check(s)) {
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
351
+ int vsz = vec_full_reg_size(s);
149
+ MVEGenOneOpImmFn *fn;
352
+ int elements = vsz >> dtype_esz[a->dtype];
353
+ TCGv_i64 addr = new_tmp_a64(s);
354
+
150
+
355
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
151
+ if ((a->cmode & 1) && a->cmode < 12) {
356
+ (a->imm * elements * (a->nreg + 1))
152
+ if (a->op) {
357
+ << dtype_msz(a->dtype));
153
+ /*
358
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
359
+ }
168
+ }
360
+ return true;
169
+ return do_1imm(s, a, fn);
361
+}
170
+}
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
--
171
--
426
2.17.1
172
2.20.1
427
173
428
174
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
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
2
and VQSHLU.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
The size-and-immediate encoding here is the same as Neon, and we
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
handle it the same way neon-dp.decode does.
6
Message-id: 20180627043328.11531-8-richard.henderson@linaro.org
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper-sve.h | 16 ++++
11
target/arm/helper-mve.h | 16 +++++++++++
10
target/arm/sve_helper.c | 158 +++++++++++++++++++++++++++++++++++++
12
target/arm/mve.decode | 23 +++++++++++++++
11
target/arm/translate-sve.c | 49 ++++++++++++
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 18 +++++
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
13
4 files changed, 241 insertions(+)
15
4 files changed, 147 insertions(+)
14
16
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
19
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper-sve.h
20
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
21
void, ptr, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
23
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
+
24
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
29
+
28
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
33
+
32
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
37
+
36
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
40
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
index XXXXXXX..XXXXXXX 100644
41
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
--- a/target/arm/mve.decode
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
44
+++ b/target/arm/mve.decode
43
index XXXXXXX..XXXXXXX 100644
45
@@ -XXX,XX +XXX,XX @@
44
--- a/target/arm/sve_helper.c
46
&2op qd qm qn size
45
+++ b/target/arm/sve_helper.c
47
&2scalar qd qn rm size
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
48
&1imm qd imm cmode op
47
49
+&2shift qd qm shift size
48
#undef DO_ZPZ_FP
50
49
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
50
+/* 4-operand predicated multiply-add. This requires 7 operands to pass
52
# Note that both Rn and Qd are 3 bits only (no D bit)
51
+ * "properly", so we need to encode some of the registers into DESC.
53
@@ -XXX,XX +XXX,XX @@
52
+ */
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
53
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 20 > 32);
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
54
+
56
55
+static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
56
+ uint16_t neg1, uint16_t neg3)
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
57
+{
177
+{
58
+ intptr_t i = simd_oprsz(desc);
178
+ TCGv_ptr qd, qm;
59
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
179
+ int shift = a->shift;
60
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
180
+
61
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
181
+ if (!dc_isar_feature(aa32_mve, s) ||
62
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
63
+ void *vd = &env->vfp.zregs[rd];
183
+ !fn) {
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;
184
+ return false;
225
+ }
185
+ }
226
+ if (!sve_access_check(s)) {
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
227
+ return true;
187
+ return true;
228
+ }
188
+ }
229
+
189
+
230
+ unsigned vsz = vec_full_reg_size(s);
190
+ /*
231
+ unsigned desc;
191
+ * When we handle a right shift insn using a left-shift helper
232
+ TCGv_i32 t_desc;
192
+ * which permits a negative shift count to indicate a right-shift,
233
+ TCGv_ptr pg = tcg_temp_new_ptr();
193
+ * we must negate the shift count.
234
+
235
+ /* We would need 7 operands to pass these arguments "properly".
236
+ * So we encode all the register numbers into the descriptor.
237
+ */
194
+ */
238
+ desc = deposit32(a->rd, 5, 5, a->rn);
195
+ if (negateshift) {
239
+ desc = deposit32(desc, 10, 5, a->rm);
196
+ shift = -shift;
240
+ desc = deposit32(desc, 15, 5, a->ra);
197
+ }
241
+ desc = simd_desc(vsz, vsz, desc);
198
+
242
+
199
+ qd = mve_qreg_ptr(a->qd);
243
+ t_desc = tcg_const_i32(desc);
200
+ qm = mve_qreg_ptr(a->qm);
244
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
245
+ fn(cpu_env, pg, t_desc);
202
+ tcg_temp_free_ptr(qd);
246
+ tcg_temp_free_i32(t_desc);
203
+ tcg_temp_free_ptr(qm);
247
+ tcg_temp_free_ptr(pg);
204
+ mve_update_eci(s);
248
+ return true;
205
+ return true;
249
+}
206
+}
250
+
207
+
251
+#define DO_FMLA(NAME, name) \
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
252
+static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a, uint32_t insn) \
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
253
+{ \
210
+ { \
254
+ static gen_helper_sve_fmla * const fns[4] = { \
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
255
+ NULL, gen_helper_sve_##name##_h, \
212
+ gen_helper_mve_##FN##b, \
256
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
213
+ gen_helper_mve_##FN##h, \
257
+ }; \
214
+ gen_helper_mve_##FN##w, \
258
+ return do_fmla(s, a, fns[a->esz]); \
215
+ NULL, \
259
+}
216
+ }; \
260
+
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
261
+DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
218
+ }
262
+DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
219
+
263
+DO_FMLA(FNMLA_zpzzz, fnmla_zpzzz)
220
+DO_2SHIFT(VSHLI, vshli_u, false)
264
+DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
265
+
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
266
+#undef DO_FMLA
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
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
--
224
--
308
2.17.1
225
2.20.1
309
226
310
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper-sve.h | 13 +++++++++
10
target/arm/helper-mve.h | 12 ++++++++++++
9
target/arm/sve_helper.c | 55 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate.h | 20 ++++++++++++++++++++
10
target/arm/translate-sve.c | 30 +++++++++++++++++++++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
11
target/arm/sve.decode | 8 ++++++
13
target/arm/mve_helper.c | 7 +++++++
12
4 files changed, 106 insertions(+)
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
13
17
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
20
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/helper-sve.h
21
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
19
DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
20
void, ptr, ptr, ptr, i64, ptr, i32)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
21
25
22
+DEF_HELPER_FLAGS_5(sve_fcvt_sh, TCG_CALL_NO_RWG,
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_fcvt_dh, TCG_CALL_NO_RWG,
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
+
29
+
35
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
void, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/sve_helper.c
47
--- a/target/arm/translate.h
41
+++ b/target/arm/sve_helper.c
48
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
43
} while (i != 0); \
50
return x * 2 + 1;
44
}
51
}
45
52
46
+/* SVE fp16 conversions always use IEEE mode. Like AdvSIMD, they ignore
53
+static inline int rsub_64(DisasContext *s, int x)
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
+{
54
+{
52
+ flag save = get_flush_inputs_to_zero(fpst);
55
+ return 64 - x;
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
+}
56
+}
60
+
57
+
61
+static inline float64 sve_f16_to_f64(float16 f, float_status *fpst)
58
+static inline int rsub_32(DisasContext *s, int x)
62
+{
59
+{
63
+ flag save = get_flush_inputs_to_zero(fpst);
60
+ return 32 - x;
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
+}
61
+}
71
+
62
+
72
+static inline float16 sve_f32_to_f16(float32 f, float_status *fpst)
63
+static inline int rsub_16(DisasContext *s, int x)
73
+{
64
+{
74
+ flag save = get_flush_to_zero(fpst);
65
+ return 16 - x;
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
+}
66
+}
82
+
67
+
83
+static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
68
+static inline int rsub_8(DisasContext *s, int x)
84
+{
69
+{
85
+ flag save = get_flush_to_zero(fpst);
70
+ return 8 - x;
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
+}
71
+}
93
+
72
+
94
+DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
95
+DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
74
{
96
+DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
75
return (dc->features & (1ULL << feature)) != 0;
97
+DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
98
+DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
77
index XXXXXXX..XXXXXXX 100644
99
+DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
78
--- a/target/arm/mve.decode
79
+++ b/target/arm/mve.decode
80
@@ -XXX,XX +XXX,XX @@
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
100
+
88
+
101
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
102
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
90
+ size=0 shift=%rshift_i3
103
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
104
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
92
+ size=1 shift=%rshift_i4
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
94
+ size=2 shift=%rshift_i5
95
+
96
# Vector loads and stores
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
105
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-sve.c
121
--- a/target/arm/mve_helper.c
107
+++ b/target/arm/translate-sve.c
122
+++ b/target/arm/mve_helper.c
108
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
109
return true;
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
110
}
163
}
111
164
112
+static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
165
-static inline int rsub_64(DisasContext *s, int x)
113
+{
166
-{
114
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
167
- return 64 - x;
115
+}
168
-}
116
+
169
-
117
+static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
170
-static inline int rsub_32(DisasContext *s, int x)
118
+{
171
-{
119
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
172
- return 32 - x;
120
+}
173
-}
121
+
174
-static inline int rsub_16(DisasContext *s, int x)
122
+static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
175
-{
123
+{
176
- return 16 - x;
124
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
177
-}
125
+}
178
-static inline int rsub_8(DisasContext *s, int x)
126
+
179
-{
127
+static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
180
- return 8 - x;
128
+{
181
-}
129
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hd);
182
-
130
+}
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
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
{
184
{
144
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
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
--
186
--
165
2.17.1
187
2.20.1
166
188
167
189
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
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: 20210628135835.6690-10-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper.h | 5 ++
10
target/arm/helper-mve.h | 9 +++++++
10
target/arm/translate-sve.c | 18 ++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
11
target/arm/vec_helper.c | 124 +++++++++++++++++++++++++++++++++++++
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
12
target/arm/sve.decode | 6 ++
13
target/arm/translate-mve.c | 15 +++++++++++
13
4 files changed, 153 insertions(+)
14
4 files changed, 105 insertions(+), 4 deletions(-)
14
15
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
18
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper.h
19
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
+
24
+
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
32
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
35
--- a/target/arm/mve.decode
34
+++ b/target/arm/translate-sve.c
36
+++ b/target/arm/mve.decode
35
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
37
@@ -XXX,XX +XXX,XX @@
36
return true;
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
37
}
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
38
40
39
+static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a, uint32_t insn)
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
40
+{
60
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
42
+ { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
43
+ { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h }
63
44
+ };
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
45
+
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
46
+ if (sve_access_check(s)) {
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
49
+ vec_full_reg_offset(s, a->rn),
50
+ vec_full_reg_offset(s, a->rm),
51
+ vsz, vsz, a->index, fns[a->u][a->sz]);
52
+ }
53
+ return true;
54
+}
67
+}
55
+
68
+
69
+{
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
56
+
72
+
57
/*
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
*** SVE Floating Point Multiply-Add Indexed Group
59
*/
60
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/vec_helper.c
63
+++ b/target/arm/vec_helper.c
64
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
65
clear_tail(d, opr_sz, simd_maxsz(desc));
66
}
67
68
+void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
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
+}
74
+}
98
+
75
+
99
+void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
100
+{
76
+{
101
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
102
+ intptr_t index = simd_data(desc);
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
103
+ uint32_t *d = vd;
104
+ uint8_t *n = vn;
105
+ uint8_t *m_indexed = (uint8_t *)vm + index * 4;
106
+
79
+
107
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
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
+}
81
+}
129
+
82
+
130
+void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
131
+{
83
+{
132
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
133
+ intptr_t index = simd_data(desc);
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
134
+ uint64_t *d = vd;
135
+ int16_t *n = vn;
136
+ int16_t *m_indexed = (int16_t *)vm + index * 4;
137
+
86
+
138
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
139
+ * Process the entire segment all at once, writing back the results
88
+}
140
+ * only after we've consumed all of the inputs.
89
141
+ */
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
142
+ for (i = 0; i < opr_sz_8 ; i += 2) {
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
143
+ uint64_t d0, d1;
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
144
+
96
+
145
+ d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
146
+ d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
147
+ d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
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
+
100
+
154
+ d[i + 0] += d0;
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
155
+ d[i + 1] += d1;
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
156
+ }
139
+ }
157
+
140
+
158
+ clear_tail(d, opr_sz, simd_maxsz(desc));
141
+#define DO_VSHLL_ALL(OP, TOP) \
159
+}
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
160
+
146
+
161
+void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
147
+DO_VSHLL_ALL(vshllb, false)
162
+{
148
+DO_VSHLL_ALL(vshllt, true)
163
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
164
+ intptr_t index = simd_data(desc);
150
index XXXXXXX..XXXXXXX 100644
165
+ uint64_t *d = vd;
151
--- a/target/arm/translate-mve.c
166
+ uint16_t *n = vn;
152
+++ b/target/arm/translate-mve.c
167
+ uint16_t *m_indexed = (uint16_t *)vm + index * 4;
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
168
+
157
+
169
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
158
+#define DO_VSHLL(INSN, FN) \
170
+ * Process the entire segment all at once, writing back the results
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
171
+ * only after we've consumed all of the inputs.
160
+ { \
172
+ */
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
173
+ for (i = 0; i < opr_sz_8 ; i += 2) {
162
+ gen_helper_mve_##FN##b, \
174
+ uint64_t d0, d1;
163
+ gen_helper_mve_##FN##h, \
175
+
164
+ }; \
176
+ d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
165
+ return do_2shift(s, a, fns[a->size], false); \
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
+ }
166
+ }
188
+
167
+
189
+ clear_tail(d, opr_sz, simd_maxsz(desc));
168
+DO_VSHLL(VSHLL_BS, vshllbs)
190
+}
169
+DO_VSHLL(VSHLL_BU, vshllbu)
191
+
170
+DO_VSHLL(VSHLL_TS, vshllts)
192
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
171
+DO_VSHLL(VSHLL_TU, vshlltu)
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
--
172
--
213
2.17.1
173
2.20.1
214
174
215
175
diff view generated by jsdifflib
1
We don't actually implement SD command CRC checking, because
1
Implement the MVE VSRI and VSLI insns, which perform a
2
for almost all of our SD controllers the CRC generation is
2
shift-and-insert operation.
3
done in hardware, and so modelling CRC generation and checking
4
would be a bit pointless. (The exception is that milkymist-memcard
5
makes the guest software compute the CRC.)
6
7
As a result almost all of our SD controller models don't bother
8
to set the SDRequest crc field, and the SD card model doesn't
9
check it. So the tracing of it in sdbus_do_command() provokes
10
Coverity warnings about use of uninitialized data.
11
12
Drop the CRC field from the trace; we can always add it back
13
if and when we do anything useful with the CRC.
14
15
Fixes Coverity issues 1386072, 1386074, 1386076, 1390571.
16
3
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20180626180324.5537-1-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
20
---
7
---
21
hw/sd/core.c | 2 +-
8
target/arm/helper-mve.h | 8 ++++++++
22
hw/sd/trace-events | 2 +-
9
target/arm/mve.decode | 9 ++++++++
23
2 files changed, 2 insertions(+), 2 deletions(-)
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
24
13
25
diff --git a/hw/sd/core.c b/hw/sd/core.c
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/core.c
16
--- a/target/arm/helper-mve.h
28
+++ b/hw/sd/core.c
17
+++ b/target/arm/helper-mve.h
29
@@ -XXX,XX +XXX,XX @@ int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
{
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
SDState *card = get_card(sdbus);
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
- trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg, req->crc);
22
+
34
+ trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg);
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
if (card) {
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
SDCardClass *sc = SD_CARD_GET_CLASS(card);
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
26
+
38
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
39
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/sd/trace-events
32
--- a/target/arm/mve.decode
41
+++ b/hw/sd/trace-events
33
+++ b/target/arm/mve.decode
42
@@ -XXX,XX +XXX,XX @@ bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x"
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
43
bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n"
35
44
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
45
# hw/sd/core.c
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
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"
38
+
47
+sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
39
+# Shift-and-insert
48
sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
49
sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
50
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
51
--
114
--
52
2.17.1
115
2.20.1
53
116
54
117
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
do_urshr() is borrowed from sve_helper.c.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180627043328.11531-4-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: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 29 +++++
9
target/arm/helper-mve.h | 10 ++++++++++
9
target/arm/sve_helper.c | 211 +++++++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 11 +++++++++++
10
target/arm/translate-sve.c | 65 ++++++++++++
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 38 +++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
12
4 files changed, 343 insertions(+)
13
4 files changed, 76 insertions(+)
13
14
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/helper-sve.h
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+
23
+
23
+DEF_HELPER_FLAGS_4(sve_st1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve_st2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve_st3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve_st4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+
28
+
28
+DEF_HELPER_FLAGS_4(sve_st1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(sve_st2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve_st3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve_st4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
32
+
41
+
33
+DEF_HELPER_FLAGS_4(sve_st1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+# Narrowing shifts (which only support b and h sizes)
34
+DEF_HELPER_FLAGS_4(sve_st2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
35
+DEF_HELPER_FLAGS_4(sve_st3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
36
+DEF_HELPER_FLAGS_4(sve_st4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
37
+
47
+
38
+DEF_HELPER_FLAGS_4(sve_st1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
39
+DEF_HELPER_FLAGS_4(sve_st2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
40
+DEF_HELPER_FLAGS_4(sve_st3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
41
+DEF_HELPER_FLAGS_4(sve_st4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
42
+
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
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
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve_helper.c
54
--- a/target/arm/mve_helper.c
54
+++ b/target/arm/sve_helper.c
55
+++ b/target/arm/mve_helper.c
55
@@ -XXX,XX +XXX,XX @@ DO_LDNF1(sds_r)
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
56
DO_LDNF1(dd_r)
57
57
58
DO_VSHLL_ALL(vshllb, false)
58
#undef DO_LDNF1
59
DO_VSHLL_ALL(vshllt, true)
59
+
60
+
60
+/*
61
+/*
61
+ * Store contiguous data, protected by a governing predicate.
62
+ * Narrowing right shifts, taking a double sized input, shifting it
63
+ * and putting the result in either the top or bottom half of the output.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
62
+ */
65
+ */
63
+#define DO_ST1(NAME, FN, TYPEE, TYPEM, H) \
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
64
+void HELPER(NAME)(CPUARMState *env, void *vg, \
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
65
+ target_ulong addr, uint32_t desc) \
68
+ void *vm, uint32_t shift) \
66
+{ \
69
+ { \
67
+ intptr_t i, oprsz = simd_oprsz(desc); \
70
+ LTYPE *m = vm; \
68
+ intptr_t ra = GETPC(); \
71
+ TYPE *d = vd; \
69
+ unsigned rd = simd_data(desc); \
72
+ uint16_t mask = mve_element_mask(env); \
70
+ void *vd = &env->vfp.zregs[rd]; \
73
+ unsigned le; \
71
+ for (i = 0; i < oprsz; ) { \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
72
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
73
+ do { \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
74
+ if (pg & 1) { \
77
+ } \
75
+ TYPEM m = *(TYPEE *)(vd + H(i)); \
78
+ mve_advance_vpt(env); \
76
+ FN(env, addr, m, ra); \
79
+ }
77
+ } \
78
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
79
+ addr += sizeof(TYPEM); \
80
+ } while (i & 15); \
81
+ } \
82
+}
83
+
80
+
84
+#define DO_ST1_D(NAME, FN, TYPEM) \
81
+#define DO_VSHRN_ALL(OP, FN) \
85
+void HELPER(NAME)(CPUARMState *env, void *vg, \
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
86
+ target_ulong addr, uint32_t desc) \
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
87
+{ \
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
88
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
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
+
86
+
101
+#define DO_ST2(NAME, FN, TYPEE, TYPEM, H) \
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
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
+{
88
+{
211
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
89
+ if (likely(sh < 64)) {
212
+ intptr_t ra = GETPC();
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
213
+ unsigned rd = simd_data(desc);
91
+ } else if (sh == 64) {
214
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
92
+ return x >> 63;
215
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
93
+ } else {
216
+ uint8_t *pg = vg;
94
+ return 0;
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
+ }
95
+ }
225
+}
96
+}
226
+
97
+
227
+void HELPER(sve_st3dd_r)(CPUARMState *env, void *vg,
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
228
+ target_ulong addr, uint32_t desc)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
229
+{
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
230
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
101
index XXXXXXX..XXXXXXX 100644
231
+ intptr_t ra = GETPC();
102
--- a/target/arm/translate-mve.c
232
+ unsigned rd = simd_data(desc);
103
+++ b/target/arm/translate-mve.c
233
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
234
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
105
DO_VSHLL(VSHLL_BU, vshllbu)
235
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
106
DO_VSHLL(VSHLL_TS, vshllts)
236
+ uint8_t *pg = vg;
107
DO_VSHLL(VSHLL_TU, vshlltu)
237
+
108
+
238
+ for (i = 0; i < oprsz; i += 1) {
109
+#define DO_2SHIFT_N(INSN, FN) \
239
+ if (pg[H1(i)] & 1) {
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
240
+ cpu_stq_data_ra(env, addr, d1[i], ra);
111
+ { \
241
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
242
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
113
+ gen_helper_mve_##FN##b, \
243
+ }
114
+ gen_helper_mve_##FN##h, \
244
+ addr += 3 * 8;
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
245
+ }
117
+ }
246
+}
247
+
118
+
248
+void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
249
+ target_ulong addr, uint32_t desc)
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
250
+{
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
251
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
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
--
123
--
411
2.17.1
124
2.20.1
412
125
413
126
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
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
do_srshr() is borrowed from sve_helper.c.
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
6
Message-id: 20180627043328.11531-14-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: 20210628135835.6690-13-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++
10
target/arm/helper-mve.h | 30 +++++++++++
10
target/arm/sve_helper.c | 77 ++++++++++++++++++++++++++++
11
target/arm/mve.decode | 28 ++++++++++
11
target/arm/translate-sve.c | 100 +++++++++++++++++++++++++++++++++++++
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 57 +++++++++++++++++++++
13
target/arm/translate-mve.c | 12 +++++
13
4 files changed, 301 insertions(+)
14
4 files changed, 174 insertions(+)
14
15
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper-sve.h
19
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_6(sve_ldbsu_zsu, TCG_CALL_NO_WG,
24
+
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_6(sve_ldhsu_zsu, TCG_CALL_NO_WG,
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_6(sve_ldssu_zsu, TCG_CALL_NO_WG,
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+
29
+DEF_HELPER_FLAGS_6(sve_ldbss_zsu, TCG_CALL_NO_WG,
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ void, env, ptr, ptr, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_ldhss_zsu, TCG_CALL_NO_WG,
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ void, env, ptr, ptr, ptr, tl, i32)
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+
34
+
34
+DEF_HELPER_FLAGS_6(sve_ldbsu_zss, TCG_CALL_NO_WG,
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_6(sve_ldhsu_zss, TCG_CALL_NO_WG,
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+ void, env, ptr, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_ldssu_zss, TCG_CALL_NO_WG,
39
+
39
+ void, env, ptr, ptr, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_ldbss_zss, TCG_CALL_NO_WG,
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+ void, env, ptr, ptr, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_6(sve_ldhss_zss, TCG_CALL_NO_WG,
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+ void, env, ptr, ptr, ptr, tl, i32)
44
+
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_ldbdu_zsu, TCG_CALL_NO_WG,
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+ void, env, ptr, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_ldhdu_zsu, TCG_CALL_NO_WG,
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+ void, env, ptr, ptr, ptr, tl, i32)
49
+
49
+DEF_HELPER_FLAGS_6(sve_ldsdu_zsu, TCG_CALL_NO_WG,
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
+ void, env, ptr, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_6(sve_ldddu_zsu, TCG_CALL_NO_WG,
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+ void, env, ptr, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_6(sve_ldbds_zsu, TCG_CALL_NO_WG,
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
54
+ void, env, ptr, ptr, ptr, tl, i32)
55
index XXXXXXX..XXXXXXX 100644
55
+DEF_HELPER_FLAGS_6(sve_ldhds_zsu, TCG_CALL_NO_WG,
56
--- a/target/arm/mve.decode
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+++ b/target/arm/mve.decode
57
+DEF_HELPER_FLAGS_6(sve_ldsds_zsu, TCG_CALL_NO_WG,
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
58
+ void, env, ptr, ptr, ptr, tl, i32)
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
59
+
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
60
+DEF_HELPER_FLAGS_6(sve_ldbdu_zss, TCG_CALL_NO_WG,
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+
62
+DEF_HELPER_FLAGS_6(sve_ldhdu_zss, TCG_CALL_NO_WG,
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
64
+DEF_HELPER_FLAGS_6(sve_ldsdu_zss, TCG_CALL_NO_WG,
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
66
+DEF_HELPER_FLAGS_6(sve_ldddu_zss, TCG_CALL_NO_WG,
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
68
+DEF_HELPER_FLAGS_6(sve_ldbds_zss, TCG_CALL_NO_WG,
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
70
+DEF_HELPER_FLAGS_6(sve_ldhds_zss, TCG_CALL_NO_WG,
71
+
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
72
+DEF_HELPER_FLAGS_6(sve_ldsds_zss, TCG_CALL_NO_WG,
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
73
+ void, env, ptr, ptr, ptr, tl, i32)
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
74
+
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
75
+DEF_HELPER_FLAGS_6(sve_ldbdu_zd, TCG_CALL_NO_WG,
76
+
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
77
+DEF_HELPER_FLAGS_6(sve_ldhdu_zd, TCG_CALL_NO_WG,
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
79
+DEF_HELPER_FLAGS_6(sve_ldsdu_zd, TCG_CALL_NO_WG,
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
81
+DEF_HELPER_FLAGS_6(sve_ldddu_zd, TCG_CALL_NO_WG,
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
83
+DEF_HELPER_FLAGS_6(sve_ldbds_zd, TCG_CALL_NO_WG,
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+
85
+DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
87
+DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
88
+ void, env, ptr, ptr, ptr, tl, i32)
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
89
+
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
90
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
91
index XXXXXXX..XXXXXXX 100644
91
void, env, ptr, ptr, ptr, tl, i32)
92
--- a/target/arm/mve_helper.c
92
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
93
+++ b/target/arm/mve_helper.c
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
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
}
95
}
99
}
96
}
100
97
101
+/* Loads with a vector index. */
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
102
+
99
+{
103
+#define DO_LD1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
100
+ if (likely(sh < 64)) {
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
105
+ target_ulong base, uint32_t desc) \
102
+ } else {
106
+{ \
103
+ /* Rounding the sign bit always produces 0. */
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
104
+ return 0;
108
+ unsigned scale = simd_data(desc); \
105
+ }
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
+}
106
+}
123
+
107
+
124
+#define DO_LD1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
108
DO_VSHRN_ALL(vshrn, DO_SHR)
125
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
109
DO_VSHRN_ALL(vrshrn, do_urshr)
126
+ target_ulong base, uint32_t desc) \
110
+
127
+{ \
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
128
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
112
+ bool *satp)
129
+ unsigned scale = simd_data(desc); \
113
+{
130
+ uintptr_t ra = GETPC(); \
114
+ if (val > max) {
131
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
115
+ *satp = true;
132
+ for (i = 0; i < oprsz; i++) { \
116
+ return max;
133
+ TYPEM mm = 0; \
117
+ } else if (val < min) {
134
+ if (pg[H1(i)] & 1) { \
118
+ *satp = true;
135
+ target_ulong off = (TYPEI)m[i]; \
119
+ return min;
136
+ mm = FN(env, base + (off << scale), ra); \
120
+ } else {
137
+ } \
121
+ return val;
138
+ d[i] = mm; \
122
+ }
139
+ } \
140
+}
123
+}
141
+
124
+
142
+DO_LD1_ZPZ_S(sve_ldbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
125
+/* Saturating narrowing right shifts */
143
+DO_LD1_ZPZ_S(sve_ldhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
144
+DO_LD1_ZPZ_S(sve_ldssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
145
+DO_LD1_ZPZ_S(sve_ldbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
128
+ void *vm, uint32_t shift) \
146
+DO_LD1_ZPZ_S(sve_ldhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
129
+ { \
147
+
130
+ LTYPE *m = vm; \
148
+DO_LD1_ZPZ_S(sve_ldbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
131
+ TYPE *d = vd; \
149
+DO_LD1_ZPZ_S(sve_ldhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
132
+ uint16_t mask = mve_element_mask(env); \
150
+DO_LD1_ZPZ_S(sve_ldssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
133
+ bool qc = false; \
151
+DO_LD1_ZPZ_S(sve_ldbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
134
+ unsigned le; \
152
+DO_LD1_ZPZ_S(sve_ldhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
153
+
136
+ bool sat = false; \
154
+DO_LD1_ZPZ_D(sve_ldbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
155
+DO_LD1_ZPZ_D(sve_ldhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
156
+DO_LD1_ZPZ_D(sve_ldsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
157
+DO_LD1_ZPZ_D(sve_ldddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
140
+ } \
158
+DO_LD1_ZPZ_D(sve_ldbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
141
+ if (qc) { \
159
+DO_LD1_ZPZ_D(sve_ldhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
142
+ env->vfp.qc[0] = qc; \
160
+DO_LD1_ZPZ_D(sve_ldsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
143
+ } \
161
+
144
+ mve_advance_vpt(env); \
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
}
188
189
+/* Indexed by [ff][xs][u][msz]. */
190
+static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
191
+ { { { gen_helper_sve_ldbss_zsu,
192
+ gen_helper_sve_ldhss_zsu,
193
+ NULL, },
194
+ { gen_helper_sve_ldbsu_zsu,
195
+ gen_helper_sve_ldhsu_zsu,
196
+ gen_helper_sve_ldssu_zsu, } },
197
+ { { gen_helper_sve_ldbss_zss,
198
+ gen_helper_sve_ldhss_zss,
199
+ NULL, },
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
+ }
145
+ }
242
+
146
+
243
+ switch (a->esz) {
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
244
+ case MO_32:
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
245
+ fn = gather_load_fn32[a->ff][a->xs][a->u][a->msz];
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
246
+ break;
150
+
247
+ case MO_64:
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
248
+ fn = gather_load_fn64[a->ff][a->xs][a->u][a->msz];
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
249
+ break;
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
250
+ }
154
+
251
+ assert(fn != NULL);
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
252
+
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
253
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
254
+ cpu_reg_sp(s, a->rn), fn);
158
+
255
+ return true;
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
256
+}
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
257
+
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
258
+static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
162
+
259
+{
163
+#define DO_SHRN_SB(N, M, SATP) \
260
+ gen_helper_gvec_mem_scatter *fn = NULL;
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
261
+ TCGv_i64 imm;
165
+#define DO_SHRN_UB(N, M, SATP) \
262
+
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
263
+ if (a->esz < a->msz || (a->esz == a->msz && !a->u)) {
167
+#define DO_SHRUN_B(N, M, SATP) \
264
+ return false;
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
265
+ }
169
+
266
+ if (!sve_access_check(s)) {
170
+#define DO_SHRN_SH(N, M, SATP) \
267
+ return true;
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
268
+ }
172
+#define DO_SHRN_UH(N, M, SATP) \
269
+
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
270
+ switch (a->esz) {
174
+#define DO_SHRUN_H(N, M, SATP) \
271
+ case MO_32:
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
272
+ fn = gather_load_fn32[a->ff][0][a->u][a->msz];
176
+
273
+ break;
177
+#define DO_RSHRN_SB(N, M, SATP) \
274
+ case MO_64:
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
275
+ fn = gather_load_fn64[a->ff][2][a->u][a->msz];
179
+#define DO_RSHRN_UB(N, M, SATP) \
276
+ break;
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
277
+ }
181
+#define DO_RSHRUN_B(N, M, SATP) \
278
+ assert(fn != NULL);
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
279
+
183
+
280
+ /* Treat LD1_zpiz (zn[x] + imm) the same way as LD1_zprz (rn + zm[x])
184
+#define DO_RSHRN_SH(N, M, SATP) \
281
+ * by loading the immediate into the scalar parameter.
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
282
+ */
186
+#define DO_RSHRN_UH(N, M, SATP) \
283
+ imm = tcg_const_i64(a->imm << a->msz);
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
284
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
188
+#define DO_RSHRUN_H(N, M, SATP) \
285
+ tcg_temp_free_i64(imm);
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
286
+ return true;
190
+
287
+}
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
288
+
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
289
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
290
{
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
291
/* Indexed by [xs][msz]. */
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
292
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
293
index XXXXXXX..XXXXXXX 100644
197
+
294
--- a/target/arm/sve.decode
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
295
+++ b/target/arm/sve.decode
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
296
@@ -XXX,XX +XXX,XX @@
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
297
&rpri_load rd pg rn imm dtype nreg
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
298
&rprr_store rd pg rn rm msz esz nreg
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
299
&rpri_store rd pg rn imm msz esz nreg
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
300
+&rprr_gather_load rd pg rn rm esz msz u ff xs scale
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
301
+&rpri_gather_load rd pg rn imm esz msz u ff
205
index XXXXXXX..XXXXXXX 100644
302
&rprr_scatter_store rd pg rn rm esz msz xs scale
206
--- a/target/arm/translate-mve.c
303
207
+++ b/target/arm/translate-mve.c
304
###########################################################################
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
305
@@ -XXX,XX +XXX,XX @@
209
DO_2SHIFT_N(VSHRNT, vshrnt)
306
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
307
&rpri_load dtype=%msz_dtype
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
308
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
309
+# Gather Loads.
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
310
+@rprr_g_load_u ....... .. . . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
311
+ &rprr_gather_load xs=2
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
312
+@rprr_g_load_xs_u ....... .. xs:1 . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
313
+ &rprr_gather_load
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
314
+@rprr_g_load_xs_u_sc ....... .. xs:1 scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
315
+ &rprr_gather_load
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
316
+@rprr_g_load_xs_sc ....... .. xs:1 scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
317
+ &rprr_gather_load
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
318
+@rprr_g_load_u_sc ....... .. . scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
319
+ &rprr_gather_load xs=2
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
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
381
--
224
--
382
2.17.1
225
2.20.1
383
226
384
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
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-9-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: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 7 +++++
9
target/arm/helper-mve.h | 2 ++
9
target/arm/sve_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 2 ++
10
target/arm/translate-sve.c | 45 ++++++++++++++++++++++++++++++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 5 ++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
12
4 files changed, 113 insertions(+)
13
4 files changed, 72 insertions(+)
13
14
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/helper-sve.h
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
23
+ i64, i64, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
25
+ i64, i64, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
27
+ i64, i64, ptr, ptr, ptr, i32)
28
+
23
+
29
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
30
void, ptr, ptr, ptr, ptr, ptr, i32)
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
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
26
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/sve_helper.c
27
--- a/target/arm/mve.decode
35
+++ b/target/arm/sve_helper.c
28
+++ b/target/arm/mve.decode
36
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
37
return predtest_ones(d, oprsz, esz_mask);
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
38
}
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
39
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
40
+uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
33
+
41
+ void *status, uint32_t desc)
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
42
+{
46
+{
43
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
47
+ uint32_t *d = vd;
44
+ float16 result = nn;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
45
+
51
+
46
+ do {
52
+ /*
47
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
53
+ * For each 32-bit element, we shift it left, bringing in the
48
+ do {
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
49
+ if (pg & 1) {
55
+ * the top become the new rdm, if the predicate mask permits.
50
+ float16 mm = *(float16 *)(vm + H1_2(i));
56
+ * The final rdm value is returned to update the register.
51
+ result = float16_add(result, mm, status);
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
52
+ }
64
+ }
53
+ i += sizeof(float16), pg >>= sizeof(float16);
65
+ mergemask(&d[H4(e)], r, mask);
54
+ } while (i & 15);
66
+ }
55
+ } while (i < opr_sz);
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
56
+
69
+
57
+ return result;
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
58
+}
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
59
+
72
+ if (mask & 1) {
60
+uint64_t HELPER(sve_fadda_s)(uint64_t nn, void *vm, void *vg,
73
+ rdm = d[H4(e)] >> (32 - shift);
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
+ }
74
+ }
73
+ i += sizeof(float32), pg >>= sizeof(float32);
75
+ mergemask(&d[H4(e)], r, mask);
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
+ }
76
+ }
91
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
92
+
89
+
93
+ return nn;
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
94
+}
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
95
+
99
+
96
/* Fully general three-operand expander, controlled by a predicate,
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
97
* With the extra float_status parameter.
98
*/
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-sve.c
102
+++ b/target/arm/translate-sve.c
103
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
104
105
#undef DO_ZZI
106
107
+/*
108
+ *** SVE Floating Point Accumulating Reduction Group
109
+ */
110
+
111
+static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
112
+{
113
+ typedef void fadda_fn(TCGv_i64, TCGv_i64, TCGv_ptr,
114
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
115
+ static fadda_fn * const fns[3] = {
116
+ gen_helper_sve_fadda_h,
117
+ gen_helper_sve_fadda_s,
118
+ gen_helper_sve_fadda_d,
119
+ };
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;
101
+ return false;
127
+ }
102
+ }
128
+ if (!sve_access_check(s)) {
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
129
+ return true;
108
+ return true;
130
+ }
109
+ }
131
+
110
+
132
+ t_val = load_esz(cpu_env, vec_reg_offset(s, a->rn, 0, a->esz), a->esz);
111
+ qd = mve_qreg_ptr(a->qd);
133
+ t_rm = tcg_temp_new_ptr();
112
+ rdm = load_reg(s, a->rdm);
134
+ t_pg = tcg_temp_new_ptr();
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
135
+ tcg_gen_addi_ptr(t_rm, cpu_env, vec_full_reg_offset(s, a->rm));
114
+ store_reg(s, a->rdm, rdm);
136
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
115
+ tcg_temp_free_ptr(qd);
137
+ t_fpst = get_fpstatus_ptr(a->esz == MO_16);
116
+ mve_update_eci(s);
138
+ t_desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
139
+
140
+ fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
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;
117
+ return true;
150
+}
118
+}
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
--
119
--
172
2.17.1
120
2.20.1
173
121
174
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
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-10-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: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 5 +++
9
target/arm/helper-mve.h | 3 ++
9
target/arm/sve_helper.c | 41 +++++++++++++++++++++++++
10
target/arm/mve.decode | 6 +++-
10
target/arm/translate-sve.c | 62 ++++++++++++++++++++++++++++++++++++++
11
target/arm/mve_helper.c | 19 ++++++++++++
11
target/arm/sve.decode | 5 +++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 113 insertions(+)
13
4 files changed, 90 insertions(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/helper-sve.h
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
22
22
+DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
23
+DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
+DEF_HELPER_FLAGS_4(sve_movz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve_movz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+
25
+
27
DEF_HELPER_FLAGS_4(sve_asr_zpzi_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DEF_HELPER_FLAGS_4(sve_asr_zpzi_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
29
DEF_HELPER_FLAGS_4(sve_asr_zpzi_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
30
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve_helper.c
31
--- a/target/arm/mve.decode
33
+++ b/target/arm/sve_helper.c
32
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
}
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
36
}
35
37
36
# Vector add across vector
38
+/* Copy Zn into Zd, and store zero into inactive elements. */
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
39
+void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
40
+{
38
+{
41
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
42
+ uint64_t *d = vd, *n = vn;
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
43
+ uint8_t *pg = vg;
41
+ rdahi=%rdahi rdalo=%rdalo
44
+ for (i = 0; i < opr_sz; i += 1) {
45
+ d[i] = n[i] & expand_pred_b(pg[H1(i)]);
46
+ }
47
+}
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
48
+
69
+
49
+void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
50
+{
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
51
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
52
+ uint64_t *d = vd, *n = vn;
53
+ uint8_t *pg = vg;
54
+ for (i = 0; i < opr_sz; i += 1) {
55
+ d[i] = n[i] & expand_pred_h(pg[H1(i)]);
56
+ }
57
+}
58
+
72
+
59
+void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
73
/* Shifts by immediate */
60
+{
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
61
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
62
+ uint64_t *d = vd, *n = vn;
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
63
+ uint8_t *pg = vg;
64
+ for (i = 0; i < opr_sz; i += 1) {
65
+ d[i] = n[i] & expand_pred_s(pg[H1(i)]);
66
+ }
67
+}
68
+
69
+void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, uint32_t desc)
70
+{
71
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
72
+ uint64_t *d = vd, *n = vn;
73
+ uint8_t *pg = vg;
74
+ for (i = 0; i < opr_sz; i += 1) {
75
+ d[i] = n[1] & -(uint64_t)(pg[H1(i)] & 1);
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
77
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/translate-sve.c
78
--- a/target/arm/translate-mve.c
85
+++ b/target/arm/translate-sve.c
79
+++ b/target/arm/translate-mve.c
86
@@ -XXX,XX +XXX,XX @@ static bool do_clr_zp(DisasContext *s, int rd, int pg, int esz)
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
87
return true;
81
return true;
88
}
82
}
89
83
90
+/* Copy Zn into Zd, storing zeros into inactive elements. */
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
91
+static void do_movz_zpz(DisasContext *s, int rd, int rn, int pg, int esz)
92
+{
85
+{
93
+ static gen_helper_gvec_3 * const fns[4] = {
86
+ /*
94
+ gen_helper_sve_movz_b, gen_helper_sve_movz_h,
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
95
+ gen_helper_sve_movz_s, gen_helper_sve_movz_d,
88
+ * elements of the vector into a 64-bit result stored in
96
+ };
89
+ * a pair of general-purpose registers.
97
+ unsigned vsz = vec_full_reg_size(s);
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
98
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
91
+ */
99
+ vec_full_reg_offset(s, rn),
92
+ TCGv_ptr qm;
100
+ pred_full_reg_offset(s, pg),
93
+ TCGv_i64 rda;
101
+ vsz, vsz, 0, fns[esz]);
94
+ TCGv_i32 rdalo, rdahi;
102
+}
103
+
95
+
104
static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
96
+ if (!dc_isar_feature(aa32_mve, s)) {
105
gen_helper_gvec_3 *fn)
97
+ return false;
106
{
98
+ }
107
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
99
+ /*
108
return true;
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
109
}
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
110
102
+ */
111
+/* Load and broadcast element. */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
112
+static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
104
+ return false;
113
+{
105
+ }
114
+ if (!sve_access_check(s)) {
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
115
+ return true;
107
+ return true;
116
+ }
108
+ }
117
+
109
+
118
+ unsigned vsz = vec_full_reg_size(s);
110
+ /*
119
+ unsigned psz = pred_full_reg_size(s);
111
+ * This insn is subject to beat-wise execution. Partial execution
120
+ unsigned esz = dtype_esz[a->dtype];
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
121
+ TCGLabel *over = gen_new_label();
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
122
+ TCGv_i64 temp;
114
+ */
123
+
115
+ if (a->a || mve_skip_first_beat(s)) {
124
+ /* If the guarding predicate has no bits set, no load occurs. */
116
+ /* Accumulate input from RdaHi:RdaLo */
125
+ if (psz <= 8) {
117
+ rda = tcg_temp_new_i64();
126
+ /* Reduce the pred_esz_masks value simply to reduce the
118
+ rdalo = load_reg(s, a->rdalo);
127
+ * size of the code generated here.
119
+ rdahi = load_reg(s, a->rdahi);
128
+ */
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
129
+ uint64_t psz_mask = MAKE_64BIT_MASK(0, psz * 8);
121
+ tcg_temp_free_i32(rdalo);
130
+ temp = tcg_temp_new_i64();
122
+ tcg_temp_free_i32(rdahi);
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 {
123
+ } else {
136
+ TCGv_i32 t32 = tcg_temp_new_i32();
124
+ /* Accumulate starting at zero */
137
+ find_last_active(s, t32, esz, a->pg);
125
+ rda = tcg_const_i64(0);
138
+ tcg_gen_brcondi_i32(TCG_COND_LT, t32, 0, over);
139
+ tcg_temp_free_i32(t32);
140
+ }
126
+ }
141
+
127
+
142
+ /* Load the data. */
128
+ qm = mve_qreg_ptr(a->qm);
143
+ temp = tcg_temp_new_i64();
129
+ if (a->u) {
144
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
145
+ tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
131
+ } else {
146
+ s->be_data | dtype_mop[a->dtype]);
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
147
+
135
+
148
+ /* Broadcast to *all* elements. */
136
+ rdalo = tcg_temp_new_i32();
149
+ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
137
+ rdahi = tcg_temp_new_i32();
150
+ vsz, vsz, temp);
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
151
+ tcg_temp_free_i64(temp);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
152
+
140
+ store_reg(s, a->rdalo, rdalo);
153
+ /* Zero the inactive elements. */
141
+ store_reg(s, a->rdahi, rdahi);
154
+ gen_set_label(over);
142
+ tcg_temp_free_i64(rda);
155
+ do_movz_zpz(s, a->rd, a->rd, a->pg, esz);
143
+ mve_update_eci(s);
156
+ return true;
144
+ return true;
157
+}
145
+}
158
+
146
+
159
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
160
int msz, int esz, int nreg)
161
{
148
{
162
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
149
TCGv_ptr qd;
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
--
150
--
186
2.17.1
151
2.20.1
187
152
188
153
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The MVE extension to v8.1M includes some new shift instructions which
2
2
sit entirely within the non-coprocessor part of the encoding space
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
and which operate only on general-purpose registers. They take up
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
Message-id: 20180627043328.11531-16-richard.henderson@linaro.org
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
7
---
27
---
8
target/arm/translate-sve.c | 85 ++++++++++++++++++++++++++------------
28
target/arm/helper-mve.h | 3 ++
9
target/arm/sve.decode | 11 +++++
29
target/arm/translate.h | 1 +
10
2 files changed, 70 insertions(+), 26 deletions(-)
30
target/arm/t32.decode | 28 +++++++++++++
11
31
target/arm/mve_helper.c | 10 +++++
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
13
index XXXXXXX..XXXXXXX 100644
33
5 files changed, 132 insertions(+)
14
--- a/target/arm/translate-sve.c
34
15
+++ b/target/arm/translate-sve.c
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
38
+++ b/target/arm/helper-mve.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
+{
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
17
return true;
133
return true;
18
}
134
}
19
135
20
+/* Indexed by [xs][msz]. */
136
+/*
21
+static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][3] = {
137
+ * v8.1M MVE wide-shifts
22
+ { gen_helper_sve_stbs_zsu,
138
+ */
23
+ gen_helper_sve_sths_zsu,
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
24
+ gen_helper_sve_stss_zsu, },
140
+ WideShiftImmFn *fn)
25
+ { gen_helper_sve_stbs_zss,
141
+{
26
+ gen_helper_sve_sths_zss,
142
+ TCGv_i64 rda;
27
+ gen_helper_sve_stss_zss, },
143
+ TCGv_i32 rdalo, rdahi;
28
+};
144
+
29
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
30
+/* Note that we overload xs=2 to indicate 64-bit offset. */
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
31
+static gen_helper_gvec_mem_scatter * const scatter_store_fn64[3][4] = {
32
+ { gen_helper_sve_stbd_zsu,
33
+ gen_helper_sve_sthd_zsu,
34
+ gen_helper_sve_stsd_zsu,
35
+ gen_helper_sve_stdd_zsu, },
36
+ { gen_helper_sve_stbd_zss,
37
+ gen_helper_sve_sthd_zss,
38
+ gen_helper_sve_stsd_zss,
39
+ gen_helper_sve_stdd_zss, },
40
+ { gen_helper_sve_stbd_zd,
41
+ gen_helper_sve_sthd_zd,
42
+ gen_helper_sve_stsd_zd,
43
+ gen_helper_sve_stdd_zd, },
44
+};
45
+
46
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
47
{
48
- /* Indexed by [xs][msz]. */
49
- static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
50
- { gen_helper_sve_stbs_zsu,
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;
147
+ return false;
99
+ }
148
+ }
100
+ if (!sve_access_check(s)) {
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
101
+ return true;
158
+ return true;
102
+ }
159
+ }
103
+
160
+
104
+ switch (a->esz) {
161
+ if (a->shim == 0) {
105
+ case MO_32:
162
+ a->shim = 32;
106
+ fn = scatter_store_fn32[0][a->msz];
163
+ }
107
+ break;
164
+
108
+ case MO_64:
165
+ rda = tcg_temp_new_i64();
109
+ fn = scatter_store_fn64[2][a->msz];
166
+ rdalo = load_reg(s, a->rdalo);
110
+ break;
167
+ rdahi = load_reg(s, a->rdahi);
111
+ }
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
112
+ assert(fn != NULL);
169
+
113
+
170
+ fn(rda, rda, a->shim);
114
+ /* Treat ST1_zpiz (zn[x] + imm) the same way as ST1_zprz (rn + zm[x])
171
+
115
+ * by loading the immediate into the scalar parameter.
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
116
+ */
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
117
+ imm = tcg_const_i64(a->imm << a->msz);
174
+ store_reg(s, a->rdalo, rdalo);
118
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
175
+ store_reg(s, a->rdahi, rdahi);
119
+ tcg_temp_free_i64(imm);
176
+ tcg_temp_free_i64(rda);
177
+
120
+ return true;
178
+ return true;
121
+}
179
+}
122
+
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
225
+
123
/*
226
/*
124
* Prefetches
227
* Multiply and multiply accumulate
125
*/
228
*/
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
+
155
+# SVE 32-bit scatter store (vector plus immediate)
156
+ST1_zpiz 1110010 .. 11 ..... 101 ... ..... ..... \
157
+ @rpri_scatter_store esz=2
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
--
229
--
163
2.17.1
230
2.20.1
164
231
165
232
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
the shift count in another general-purpose register, which might be
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
either positive or negative.
5
Message-id: 20180627043328.11531-19-richard.henderson@linaro.org
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
11
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
7
---
15
---
8
target/arm/helper.h | 14 +++++++++++
16
target/arm/helper-mve.h | 6 +++
9
target/arm/translate-sve.c | 50 ++++++++++++++++++++++++++++++++++++++
17
target/arm/translate.h | 1 +
10
target/arm/vec_helper.c | 48 ++++++++++++++++++++++++++++++++++++
18
target/arm/t32.decode | 16 +++++--
11
target/arm/sve.decode | 19 +++++++++++++++
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
12
4 files changed, 131 insertions(+)
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
13
21
5 files changed, 182 insertions(+), 3 deletions(-)
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
22
15
index XXXXXXX..XXXXXXX 100644
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
--- a/target/arm/helper.h
24
index XXXXXXX..XXXXXXX 100644
17
+++ b/target/arm/helper.h
25
--- a/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
26
+++ b/target/arm/helper-mve.h
19
DEF_HELPER_FLAGS_5(gvec_ftsmul_d, TCG_CALL_NO_RWG,
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
void, ptr, ptr, ptr, ptr, i32)
28
21
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
22
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_h, TCG_CALL_NO_RWG,
30
23
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_s, TCG_CALL_NO_RWG,
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
+ void, ptr, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_d, TCG_CALL_NO_RWG,
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
+
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_h, TCG_CALL_NO_RWG,
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
index XXXXXXX..XXXXXXX 100644
33
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
41
--- a/target/arm/translate.h
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
42
+++ b/target/arm/translate.h
35
+
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
#ifdef TARGET_AARCH64
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
#include "helper-a64.h"
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
#include "helper-sve.h"
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
40
index XXXXXXX..XXXXXXX 100644
48
41
--- a/target/arm/translate-sve.c
49
/**
42
+++ b/target/arm/translate-sve.c
50
* arm_tbflags_from_tb:
43
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
44
52
index XXXXXXX..XXXXXXX 100644
45
#undef DO_ZZI
53
--- a/target/arm/t32.decode
46
54
+++ b/target/arm/t32.decode
47
+/*
55
@@ -XXX,XX +XXX,XX @@
48
+ *** SVE Floating Point Multiply-Add Indexed Group
56
&mcrr !extern cp opc1 crm rt rt2
49
+ */
57
50
+
58
&mve_shl_ri rdalo rdahi shim
51
+static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a, uint32_t insn)
59
+&mve_shl_rr rdalo rdahi rm
52
+{
60
53
+ static gen_helper_gvec_4_ptr * const fns[3] = {
61
# rdahi: bits [3:1] from insn, bit 0 is 1
54
+ gen_helper_gvec_fmla_idx_h,
62
# rdalo: bits [3:1] from insn, bit 0 is 0
55
+ gen_helper_gvec_fmla_idx_s,
63
@@ -XXX,XX +XXX,XX @@
56
+ gen_helper_gvec_fmla_idx_d,
64
57
+ };
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
58
+
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
59
+ if (sve_access_check(s)) {
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
60
+ unsigned vsz = vec_full_reg_size(s);
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
61
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
69
62
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
70
{
63
+ vec_full_reg_offset(s, a->rn),
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
64
+ vec_full_reg_offset(s, a->rm),
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
65
+ vec_full_reg_offset(s, a->ra),
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
66
+ status, vsz, vsz, (a->index << 1) | a->sub,
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
67
+ fns[a->esz - 1]);
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
68
+ tcg_temp_free_ptr(status);
76
+
69
+ }
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
70
+ return true;
255
+ return true;
71
+}
256
+}
72
+
257
+
73
+/*
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
74
+ *** SVE Floating Point Multiply Indexed Group
259
+{
75
+ */
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
76
+
261
+}
77
+static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
262
+
78
+{
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
79
+ static gen_helper_gvec_3_ptr * const fns[3] = {
264
+{
80
+ gen_helper_gvec_fmul_idx_h,
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
81
+ gen_helper_gvec_fmul_idx_s,
266
+}
82
+ gen_helper_gvec_fmul_idx_d,
267
+
83
+ };
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
84
+
269
+{
85
+ if (sve_access_check(s)) {
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
86
+ unsigned vsz = vec_full_reg_size(s);
271
+}
87
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
272
+
88
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
89
+ vec_full_reg_offset(s, a->rn),
274
+{
90
+ vec_full_reg_offset(s, a->rm),
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
91
+ status, vsz, vsz, a->index, fns[a->esz - 1]);
276
+}
92
+ tcg_temp_free_ptr(status);
277
+
93
+ }
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
94
+ return true;
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
95
+}
286
+}
96
+
287
+
97
/*
288
/*
98
*** SVE Floating Point Accumulating Reduction Group
289
* Multiply and multiply accumulate
99
*/
290
*/
100
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/vec_helper.c
103
+++ b/target/arm/vec_helper.c
104
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
105
106
#endif
107
#undef DO_3OP
108
+
109
+/* For the indexed ops, SVE applies the index per 128-bit vector segment.
110
+ * For AdvSIMD, there is of course only one such vector segment.
111
+ */
112
+
113
+#define DO_MUL_IDX(NAME, TYPE, H) \
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
115
+{ \
116
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
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
158
--- a/target/arm/sve.decode
159
+++ b/target/arm/sve.decode
160
@@ -XXX,XX +XXX,XX @@
161
%imm9_16_10 16:s6 10:3
162
%size_23 23:2
163
%dtype_23_13 23:2 13:2
164
+%index3_22_19 22:1 19:2
165
166
# A combination of tsz:imm3 -- extract esize.
167
%tszimm_esz 22:2 5:5 !function=tszimm_esz
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
--
291
--
194
2.17.1
292
2.20.1
195
293
196
294
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
These patterns overlap with the long-shift-by-immediates,
5
Message-id: 20180627043328.11531-21-richard.henderson@linaro.org
5
so we have to rearrange the grouping a little here.
6
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
7
---
10
---
8
target/arm/helper.h | 8 +++++++
11
target/arm/helper-mve.h | 3 ++
9
target/arm/translate-sve.c | 47 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate.h | 1 +
10
target/arm/vec_helper.c | 20 ++++++++++++++++
13
target/arm/t32.decode | 31 ++++++++++++++-----
11
target/arm/sve.decode | 5 ++++
14
target/arm/mve_helper.c | 10 ++++++
12
4 files changed, 80 insertions(+)
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
13
16
5 files changed, 104 insertions(+), 9 deletions(-)
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
15
index XXXXXXX..XXXXXXX 100644
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
--- a/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
17
+++ b/target/arm/helper.h
20
--- a/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
21
+++ b/target/arm/helper-mve.h
19
DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
20
void, ptr, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
21
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
22
+DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
+DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+
24
+DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
+
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
26
+DEF_HELPER_FLAGS_4(gvec_frsqrte_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
+DEF_HELPER_FLAGS_4(gvec_frsqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
index XXXXXXX..XXXXXXX 100644
28
+DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
--- a/target/arm/translate.h
29
+
32
+++ b/target/arm/translate.h
30
DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
31
DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
32
DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
34
index XXXXXXX..XXXXXXX 100644
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
35
--- a/target/arm/translate-sve.c
38
36
+++ b/target/arm/translate-sve.c
39
/**
37
@@ -XXX,XX +XXX,XX @@ DO_VPZ(FMAXNMV, fmaxnmv)
40
* arm_tbflags_from_tb:
38
DO_VPZ(FMINV, fminv)
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
39
DO_VPZ(FMAXV, fmaxv)
42
index XXXXXXX..XXXXXXX 100644
40
43
--- a/target/arm/t32.decode
41
+/*
44
+++ b/target/arm/t32.decode
42
+ *** SVE Floating Point Unary Operations - Unpredicated Group
45
@@ -XXX,XX +XXX,XX @@
43
+ */
46
44
+
47
&mve_shl_ri rdalo rdahi shim
45
+static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
48
&mve_shl_rr rdalo rdahi rm
46
+{
49
+&mve_sh_ri rda shim
47
+ unsigned vsz = vec_full_reg_size(s);
50
48
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
51
# rdahi: bits [3:1] from insn, bit 0 is 1
49
+
52
# rdalo: bits [3:1] from insn, bit 0 is 0
50
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
53
@@ -XXX,XX +XXX,XX @@
51
+ vec_full_reg_offset(s, a->rn),
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
52
+ status, vsz, vsz, 0, fn);
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
53
+ tcg_temp_free_ptr(status);
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
54
+}
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
55
+
58
+ &mve_sh_ri shim=%imm5_12_6
56
+static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
59
57
+{
60
{
58
+ static gen_helper_gvec_2_ptr * const fns[3] = {
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
59
+ gen_helper_gvec_frecpe_h,
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
60
+ gen_helper_gvec_frecpe_s,
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
61
+ gen_helper_gvec_frecpe_d,
64
# handling them as r13 and r15 accesses with the same semantics as A32).
62
+ };
65
[
63
+ if (a->esz == 0) {
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
64
+ return false;
160
+ return false;
65
+ }
161
+ }
66
+ if (sve_access_check(s)) {
162
+ if (!dc_isar_feature(aa32_mve, s) ||
67
+ do_zz_fp(s, a, fns[a->esz - 1]);
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
68
+ }
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
69
+ return true;
175
+ return true;
70
+}
176
+}
71
+
177
+
72
+static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
73
+{
179
+{
74
+ static gen_helper_gvec_2_ptr * const fns[3] = {
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
75
+ gen_helper_gvec_frsqrte_h,
181
+}
76
+ gen_helper_gvec_frsqrte_s,
182
+
77
+ gen_helper_gvec_frsqrte_d,
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
78
+ };
184
+{
79
+ if (a->esz == 0) {
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
80
+ return false;
186
+}
81
+ }
187
+
82
+ if (sve_access_check(s)) {
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
83
+ do_zz_fp(s, a, fns[a->esz - 1]);
189
+{
84
+ }
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
85
+ return true;
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
86
+}
206
+}
87
+
207
+
88
/*
208
/*
89
*** SVE Floating Point Accumulating Reduction Group
209
* Multiply and multiply accumulate
90
*/
210
*/
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
--
211
--
139
2.17.1
212
2.20.1
140
213
141
214
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
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-11-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
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate-sve.c | 103 +++++++++++++++++++++++++++++++++++++
8
target/arm/helper-mve.h | 2 ++
9
target/arm/sve.decode | 6 +++
9
target/arm/translate.h | 1 +
10
2 files changed, 109 insertions(+)
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
11
14
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
17
--- a/target/arm/helper-mve.h
15
+++ b/target/arm/translate-sve.c
18
+++ b/target/arm/helper-mve.h
16
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
17
tcg_temp_free_i64(t0);
20
18
}
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
19
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
20
+/* Similarly for stores. */
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
21
+static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
+ int rn, int imm)
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
23
+{
26
index XXXXXXX..XXXXXXX 100644
24
+ uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
27
--- a/target/arm/translate.h
25
+ uint32_t len_remain = len % 8;
28
+++ b/target/arm/translate.h
26
+ uint32_t nparts = len / 8 + ctpop8(len_remain);
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
27
+ int midx = get_mem_index(s);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
28
+ TCGv_i64 addr, t0;
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
29
+
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
30
+ addr = tcg_temp_new_i64();
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
31
+ t0 = tcg_temp_new_i64();
34
32
+
35
/**
33
+ /* Note that unpredicated load/store of vector/predicate registers
36
* arm_tbflags_from_tb:
34
+ * are defined as a stream of bytes, which equates to little-endian
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
35
+ * operations on larger quantities. There is no nice way to force
38
index XXXXXXX..XXXXXXX 100644
36
+ * a little-endian store for aarch64_be-linux-user out of line.
39
--- a/target/arm/t32.decode
37
+ *
40
+++ b/target/arm/t32.decode
38
+ * Attempt to keep code expansion to a minimum by limiting the
41
@@ -XXX,XX +XXX,XX @@
39
+ * amount of unrolling done.
42
&mve_shl_ri rdalo rdahi shim
40
+ */
43
&mve_shl_rr rdalo rdahi rm
41
+ if (nparts <= 4) {
44
&mve_sh_ri rda shim
42
+ int i;
45
+&mve_sh_rr rda rm
43
+
46
44
+ for (i = 0; i < len_align; i += 8) {
47
# rdahi: bits [3:1] from insn, bit 0 is 1
45
+ tcg_gen_ld_i64(t0, cpu_env, vofs + i);
48
# rdalo: bits [3:1] from insn, bit 0 is 0
46
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + i);
49
@@ -XXX,XX +XXX,XX @@
47
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
48
+ }
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
49
+ } else {
52
&mve_sh_ri shim=%imm5_12_6
50
+ TCGLabel *loop = gen_new_label();
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
51
+ TCGv_ptr t2, i = tcg_const_local_ptr(0);
54
52
+
55
{
53
+ gen_set_label(loop);
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
54
+
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
55
+ t2 = tcg_temp_new_ptr();
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
56
+ tcg_gen_add_ptr(t2, cpu_env, i);
59
}
57
+ tcg_gen_ld_i64(t0, t2, vofs);
60
58
+
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
59
+ /* Minimize the number of local temps that must be re-read from
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
60
+ * the stack each iteration. Instead, re-compute values other
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
61
+ * than the loop counter.
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
62
+ */
65
+ {
63
+ tcg_gen_addi_ptr(t2, i, imm);
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
64
+ tcg_gen_extu_ptr_i64(addr, t2);
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
65
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, rn));
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
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
+ }
69
+ }
75
+
70
+
76
+ /* Predicate register stores can be any multiple of 2. */
71
+ {
77
+ if (len_remain) {
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
78
+ tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + len_align);
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
75
+ }
80
+
76
+
81
+ switch (len_remain) {
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ case 2:
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
+ case 4:
79
]
84
+ case 8:
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
85
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LE | ctz32(len_remain));
81
index XXXXXXX..XXXXXXX 100644
86
+ break;
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
87
}
87
+
88
+
88
+ case 6:
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
89
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUL);
90
+{
90
+ tcg_gen_addi_i64(addr, addr, 4);
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
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
+}
92
+}
102
+
93
+
103
static bool trans_LDR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
104
{
95
+{
105
if (sve_access_check(s)) {
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
106
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
97
+}
107
return true;
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
108
}
104
}
109
105
110
+static bool trans_STR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
111
+{
107
+{
112
+ if (sve_access_check(s)) {
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
113
+ int size = vec_full_reg_size(s);
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
114
+ int off = vec_full_reg_offset(s, a->rd);
110
+ return false;
115
+ do_str(s, off, size, a->rn, a->imm * size);
116
+ }
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
117
+ return true;
123
+ return true;
118
+}
124
+}
119
+
125
+
120
+static bool trans_STR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
121
+{
127
+{
122
+ if (sve_access_check(s)) {
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
123
+ int size = pred_full_reg_size(s);
129
+}
124
+ int off = pred_full_reg_offset(s, a->rd);
130
+
125
+ do_str(s, off, size, a->rn, a->imm * size);
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
126
+ }
132
+{
127
+ return true;
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
128
+}
134
+}
129
+
135
+
130
/*
136
/*
131
*** SVE Memory - Contiguous Load Group
137
* Multiply and multiply accumulate
132
*/
138
*/
133
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/sve.decode
136
+++ b/target/arm/sve.decode
137
@@ -XXX,XX +XXX,XX @@ LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
138
139
### SVE Memory Store Group
140
141
+# SVE store predicate register
142
+STR_pri 1110010 11 0. ..... 000 ... ..... 0 .... @pd_rn_i9
143
+
144
+# SVE store vector register
145
+STR_zri 1110010 11 0. ..... 010 ... ..... ..... @rd_rn_i9
146
+
147
# SVE contiguous store (scalar plus immediate)
148
# ST1B, ST1H, ST1W, ST1D; require msz <= esz
149
ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
150
--
139
--
151
2.17.1
140
2.20.1
152
141
153
142
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
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-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 40 ++++++++++++++++-
11
3 files changed, 193 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-sve.h
16
+++ b/target/arm/helper-sve.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
18
DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
19
void, env, ptr, ptr, ptr, tl, i32)
20
21
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zsu, TCG_CALL_NO_WG,
22
+ void, env, ptr, ptr, ptr, tl, i32)
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
};
213
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
--
249
2.17.1
250
251
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-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-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 30 +++++++++++++
9
target/arm/helper.h | 12 +++---
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
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
19
+++ b/target/arm/helper-sve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
21
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
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
}
86
87
#define CONV_FTOI(name, ftype, fsz, sign, round) \
88
-uint32_t HELPER(name)(ftype x, void *fpstp) \
89
+sign##int32_t HELPER(name)(ftype x, void *fpstp) \
90
{ \
91
float_status *fpst = fpstp; \
92
if (float##fsz##_is_any_nan(x)) { \
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 @@ static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
98
return ret;
99
}
100
101
+static inline int16_t vfp_float16_to_int16_rtz(float16 f, float_status *s)
102
+{
103
+ if (float16_is_any_nan(f)) {
104
+ float_raise(float_flag_invalid, s);
105
+ return 0;
106
+ }
107
+ return float16_to_int16_round_to_zero(f, s);
108
+}
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
}
206
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
--
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-26-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 +++++++
9
target/arm/sve_helper.c | 8 ++++
10
target/arm/translate-sve.c | 77 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 9 +++++
12
4 files changed, 108 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_fcvtzu_sd, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_fcvtzu_dd, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_frint_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_frint_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_frint_d, TCG_CALL_NO_RWG,
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
41
--- a/target/arm/sve_helper.c
42
+++ b/target/arm/sve_helper.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_fcvtzu_sd, uint64_t, , vfp_float32_to_uint64_rtz)
44
DO_ZPZ_FP(sve_fcvtzu_ds, uint64_t, , helper_vfp_touizd)
45
DO_ZPZ_FP(sve_fcvtzu_dd, uint64_t, , vfp_float64_to_uint64_rtz)
46
47
+DO_ZPZ_FP(sve_frint_h, uint16_t, H1_2, helper_advsimd_rinth)
48
+DO_ZPZ_FP(sve_frint_s, uint32_t, H1_4, helper_rints)
49
+DO_ZPZ_FP(sve_frint_d, uint64_t, , helper_rintd)
50
+
51
+DO_ZPZ_FP(sve_frintx_h, uint16_t, H1_2, float16_round_to_int)
52
+DO_ZPZ_FP(sve_frintx_s, uint32_t, H1_4, float32_round_to_int)
53
+DO_ZPZ_FP(sve_frintx_d, uint64_t, , float64_round_to_int)
54
+
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
63
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
64
}
65
66
+static gen_helper_gvec_3_ptr * const frint_fns[3] = {
67
+ gen_helper_sve_frint_h,
68
+ gen_helper_sve_frint_s,
69
+ gen_helper_sve_frint_d
70
+};
71
+
72
+static bool trans_FRINTI(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
73
+{
74
+ if (a->esz == 0) {
75
+ return false;
76
+ }
77
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16,
78
+ frint_fns[a->esz - 1]);
79
+}
80
+
81
+static bool trans_FRINTX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
82
+{
83
+ static gen_helper_gvec_3_ptr * const fns[3] = {
84
+ gen_helper_sve_frintx_h,
85
+ gen_helper_sve_frintx_s,
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
--
167
2.17.1
168
169
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-27-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 ++++++++++++++
9
target/arm/sve_helper.c | 8 ++++++++
10
target/arm/translate-sve.c | 26 ++++++++++++++++++++++++++
11
target/arm/sve.decode | 4 ++++
12
4 files changed, 52 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_frintx_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_frintx_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_frecpx_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_frecpx_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_frecpx_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_5(sve_fsqrt_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_fsqrt_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_fsqrt_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
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
+
51
+DO_ZPZ_FP(sve_fsqrt_h, uint16_t, H1_2, float16_sqrt)
52
+DO_ZPZ_FP(sve_fsqrt_s, uint32_t, H1_4, float32_sqrt)
53
+DO_ZPZ_FP(sve_fsqrt_d, uint64_t, , float64_sqrt)
54
+
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
63
return do_frint_mode(s, a, float_round_ties_away);
64
}
65
66
+static bool trans_FRECPX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
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
--
111
2.17.1
112
113
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-28-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-
9
target/arm/sve.decode | 7 +++++
10
2 files changed, 66 insertions(+), 1 deletion(-)
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 do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
17
return true;
18
}
19
20
+/* Select active elememnts from Zn and inactive elements from Zm,
21
+ * storing the result in Zd.
22
+ */
23
+static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
24
+{
25
+ static gen_helper_gvec_4 * const fns[4] = {
26
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
27
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
28
+ };
29
+ unsigned vsz = vec_full_reg_size(s);
30
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
31
+ vec_full_reg_offset(s, rn),
32
+ vec_full_reg_offset(s, rm),
33
+ pred_full_reg_offset(s, pg),
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
}
43
44
-DO_ZPZZ(SEL, sel)
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
--
120
2.17.1
121
122
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Enhance the existing helpers to support SVE, which takes the
4
index from each 128-bit segment. The change has no effect
5
for AdvSIMD, since there is only one such segment.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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
20
--- a/target/arm/translate-sve.c
21
+++ b/target/arm/translate-sve.c
22
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zpzzz(DisasContext *s,
23
return true;
24
}
25
26
+static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a, uint32_t insn)
27
+{
28
+ static gen_helper_gvec_3_ptr * const fns[2] = {
29
+ gen_helper_gvec_fcmlah_idx,
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
--
150
2.17.1
151
152
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-33-richard.henderson@linaro.org
6
[PMM: moved 'ra=%reg_movprfx' here from following patch]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper.h | 5 +++
10
target/arm/translate-sve.c | 17 ++++++++++
11
target/arm/vec_helper.c | 67 ++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 3 ++
13
4 files changed, 92 insertions(+)
14
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
18
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(gvec_udot_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 @@ DO_ZZI(UMIN, umin)
36
37
#undef DO_ZZI
38
39
+static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
40
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
42
+ { gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h },
43
+ { gen_helper_gvec_udot_b, gen_helper_gvec_udot_h }
44
+ };
45
+
46
+ if (sve_access_check(s)) {
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
49
+ vec_full_reg_offset(s, a->rn),
50
+ vec_full_reg_offset(s, a->rm),
51
+ vsz, vsz, 0, fns[a->u][a->sz]);
52
+ }
53
+ return true;
54
+}
55
+
56
/*
57
*** SVE Floating Point Multiply-Add Indexed Group
58
*/
59
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/vec_helper.c
62
+++ b/target/arm/vec_helper.c
63
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
64
clear_tail(d, opr_sz, simd_maxsz(desc));
65
}
66
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
--
152
2.17.1
153
154
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Enable ARM_FEATURE_SVE for the generic "max" cpu.
4
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180627043328.11531-35-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
linux-user/elfload.c | 1 +
12
target/arm/cpu.c | 7 +++++++
13
target/arm/cpu64.c | 1 +
14
3 files changed, 9 insertions(+)
15
16
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/elfload.c
19
+++ b/linux-user/elfload.c
20
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
21
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
22
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
23
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
24
+ GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
25
#undef GET_FEATURE
26
27
return hwcaps;
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
33
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
34
/* and to the FP/Neon instructions */
35
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
36
+ /* and to the SVE instructions */
37
+ env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
38
+ env->cp15.cptr_el[3] |= CPTR_EZ;
39
+ /* with maximum vector length */
40
+ env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
41
+ env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
42
+ env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
43
#else
44
/* Reset into the highest available EL */
45
if (arm_feature(env, ARM_FEATURE_EL3)) {
46
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu64.c
49
+++ b/target/arm/cpu64.c
50
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
52
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
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
--
59
2.17.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
1
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
hw/arm/mcimx7d-sabre.c | 2 --
8
1 file changed, 2 deletions(-)
9
10
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mcimx7d-sabre.c
13
+++ b/hw/arm/mcimx7d-sabre.c
14
@@ -XXX,XX +XXX,XX @@
15
#include "hw/arm/fsl-imx7.h"
16
#include "hw/boards.h"
17
#include "sysemu/sysemu.h"
18
-#include "sysemu/device_tree.h"
19
#include "qemu/error-report.h"
20
#include "sysemu/qtest.h"
21
-#include "net/net.h"
22
23
typedef struct {
24
FslIMX7State soc;
25
--
26
2.17.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
1
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
hw/arm/fsl-imx7.c | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
9
10
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/fsl-imx7.c
13
+++ b/hw/arm/fsl-imx7.c
14
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
15
/*
16
* SRC
17
*/
18
- create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
19
+ create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
20
21
/*
22
* Watchdog
23
--
24
2.17.1
25
26
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <alindsay@codeaurora.org>
2
1
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
4
Message-id: 1529699547-17044-5-git-send-email-alindsay@codeaurora.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
target/arm/cpu.h | 1 +
8
target/arm/cpu.c | 21 ++++++++++++++-------
9
target/arm/kvm32.c | 8 ++++----
10
3 files changed, 19 insertions(+), 11 deletions(-)
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
18
ARM_FEATURE_THUMB2EE,
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
*/
98
- set_feature(&features, ARM_FEATURE_V7);
99
+ set_feature(&features, ARM_FEATURE_V7VE);
100
set_feature(&features, ARM_FEATURE_VFP3);
101
- set_feature(&features, ARM_FEATURE_LPAE);
102
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
103
104
switch (extract32(id_isar0, 24, 4)) {
105
--
106
2.17.1
107
108
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <alindsay@codeaurora.org>
2
1
3
KVM implies V7VE, which implies ARM_DIV and THUMB_DIV. The conditional
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
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
9
Message-id: 1529699547-17044-6-git-send-email-alindsay@codeaurora.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/kvm32.c | 19 +------------------
13
1 file changed, 1 insertion(+), 18 deletions(-)
14
15
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/kvm32.c
18
+++ b/target/arm/kvm32.c
19
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
20
* and then query that CPU for the relevant ID registers.
21
*/
22
int i, ret, fdarray[3];
23
- uint32_t midr, id_pfr0, id_isar0, mvfr1;
24
+ uint32_t midr, id_pfr0, mvfr1;
25
uint64_t features = 0;
26
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
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
--
60
2.17.1
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <alindsay@codeaurora.org>
2
1
3
This makes it match its AArch64 equivalent, PMINTENSET_EL1
4
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
6
Message-id: 1529699547-17044-13-git-send-email-alindsay@codeaurora.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
17
.writefn = pmuserenr_write, .raw_writefn = raw_write },
18
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
19
.access = PL1_RW, .accessfn = access_tpm,
20
- .type = ARM_CP_ALIAS,
21
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
22
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
23
.resetvalue = 0,
24
.writefn = pmintenset_write, .raw_writefn = raw_write },
25
--
26
2.17.1
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We already check for the same condition within the normal integer
4
sdiv and sdiv64 helpers. Use a slightly different formation that
5
does not require deducing the expression type.
6
7
Fixes: f97cfd596ed
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
20
--- a/target/arm/sve_helper.c
21
+++ b/target/arm/sve_helper.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
23
#define DO_MIN(N, M) ((N) >= (M) ? (M) : (N))
24
#define DO_ABD(N, M) ((N) >= (M) ? (N) - (M) : (M) - (N))
25
#define DO_MUL(N, M) (N * M)
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
--
58
2.17.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
There is no need to re-set these 9 features already
4
implied by the call to aarch64_a57_initfn.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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>
11
---
12
target/arm/cpu64.c | 9 ---------
13
1 file changed, 9 deletions(-)
14
15
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu64.c
18
+++ b/target/arm/cpu64.c
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
* whereas the architecture requires them to be present in both if
21
* present in either.
22
*/
23
- set_feature(&cpu->env, ARM_FEATURE_V8);
24
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
25
- set_feature(&cpu->env, ARM_FEATURE_NEON);
26
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
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
--
40
2.17.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
There is no need to re-set these 3 features already
4
implied by the call to aarch64_a15_initfn.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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
17
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
* since we don't correctly set the ID registers to advertise them,
21
*/
22
set_feature(&cpu->env, ARM_FEATURE_V8);
23
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
24
- set_feature(&cpu->env, ARM_FEATURE_NEON);
25
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
26
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
27
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
28
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
29
--
30
2.17.1
31
32
diff view generated by jsdifflib