1
Hopefully last target-arm queue before softfreeze;
1
First pullreq for arm of the 4.1 series, since I'm back from
2
this one's largest part is the remainder of the SVE patches,
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
but there are a selection of other minor things too.
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
4
6
5
thanks
7
thanks
6
-- PMM
8
-- PMM
7
9
8
The following changes since commit 109b25045b3651f9c5d02c3766c0b3ff63e6d193:
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
9
11
10
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2018-06-29 12:30:29 +0100)
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
11
13
12
are available in the Git repository at:
14
are available in the Git repository at:
13
15
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180629
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
15
17
16
for you to fetch changes up to 802abf4024d23e48d45373ac3f2b580124b54b47:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
17
19
18
target/arm: Add ID_ISAR6 (2018-06-29 15:30:54 +0100)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
19
21
20
----------------------------------------------------------------
22
----------------------------------------------------------------
21
target-arm queue:
23
target-arm queue:
22
* last of the SVE patches; SVE is now enabled for aarch64 linux-user
24
* remove "bag of random stuff" hw/devices.h header
23
* sd: Don't trace SDRequest crc field (coverity bugfix)
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
24
* target/arm: Mark PMINTENSET accesses as possibly doing IO
26
* hw/dma: Compile the bcm2835_dma device as common object
25
* clean up v7VE feature bit handling
27
* configure: Remove --source-path option
26
* i.mx7d: minor cleanups
28
* hw/ssi/xilinx_spips: Avoid variable length array
27
* target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
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
30
33
----------------------------------------------------------------
31
----------------------------------------------------------------
34
Aaron Lindsay (3):
32
Eric Auger (1):
35
target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
33
hw/arm/smmuv3: Remove SMMUNotifierNode
36
target/arm: Remove redundant DIV detection for KVM
37
target/arm: Mark PMINTENSET accesses as possibly doing IO
38
34
39
Alex Bennée (1):
35
Peter Maydell (28):
40
target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
36
hw/ssi/xilinx_spips: Avoid variable length array
37
configure: Remove --source-path option
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
41
target/arm: Disable most VFP sysregs for M-profile
42
target/arm: Honour M-profile FP enable bits
43
target/arm: Decode FP instructions for M profile
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
46
target/arm/helper: don't return early for STKOF faults during stacking
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
41
64
42
Eric Auger (3):
65
Philippe Mathieu-Daudé (13):
43
device_tree: Add qemu_fdt_node_unit_path
66
hw/dma: Compile the bcm2835_dma device as common object
44
hw/arm/virt: Silence dtc /intc warnings
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
45
hw/arm/virt: Silence dtc /memory warning
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
69
hw/display/tc6393xb: Remove unused functions
70
hw/devices: Move TC6393XB declarations into a new header
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
46
79
47
Jean-Christophe Dubois (3):
80
configure | 10 +-
48
i.mx7d: Remove unused header files
81
hw/dma/Makefile.objs | 2 +-
49
i.mx7d: Change SRC unimplemented device name from sdma to src
82
include/hw/arm/omap.h | 6 +-
50
i.mx7d: Change IRQ number type from hwaddr to int
83
include/hw/arm/smmu-common.h | 8 +-
84
include/hw/devices.h | 62 ---
85
include/hw/display/blizzard.h | 22 ++
86
include/hw/display/tc6393xb.h | 24 ++
87
include/hw/input/gamepad.h | 19 +
88
include/hw/input/tsc2xxx.h | 36 ++
89
include/hw/misc/cbus.h | 32 ++
90
include/hw/net/lan9118.h | 21 +
91
include/hw/net/ne2000-isa.h | 6 +
92
include/hw/net/smc91c111.h | 19 +
93
include/qemu/typedefs.h | 1 -
94
target/arm/cpu.h | 95 ++++-
95
target/arm/helper.h | 5 +
96
target/arm/translate.h | 3 +
97
hw/arm/aspeed.c | 13 +-
98
hw/arm/exynos4_boards.c | 3 +-
99
hw/arm/gumstix.c | 2 +-
100
hw/arm/integratorcp.c | 2 +-
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
51
139
52
Peter Maydell (1):
53
sd: Don't trace SDRequest crc field
54
55
Philippe Mathieu-Daudé (4):
56
hw/block/fdc: Replace error_setg(&error_abort) by assert()
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
61
Richard Henderson (40):
62
target/arm: Implement SVE Memory Contiguous Load Group
63
target/arm: Implement SVE Contiguous Load, first-fault and no-fault
64
target/arm: Implement SVE Memory Contiguous Store Group
65
target/arm: Implement SVE load and broadcast quadword
66
target/arm: Implement SVE integer convert to floating-point
67
target/arm: Implement SVE floating-point arithmetic (predicated)
68
target/arm: Implement SVE FP Multiply-Add Group
69
target/arm: Implement SVE Floating Point Accumulating Reduction Group
70
target/arm: Implement SVE load and broadcast element
71
target/arm: Implement SVE store vector/predicate register
72
target/arm: Implement SVE scatter stores
73
target/arm: Implement SVE prefetches
74
target/arm: Implement SVE gather loads
75
target/arm: Implement SVE first-fault gather loads
76
target/arm: Implement SVE scatter store vector immediate
77
target/arm: Implement SVE floating-point compare vectors
78
target/arm: Implement SVE floating-point arithmetic with immediate
79
target/arm: Implement SVE Floating Point Multiply Indexed Group
80
target/arm: Implement SVE FP Fast Reduction Group
81
target/arm: Implement SVE Floating Point Unary Operations - Unpredicated Group
82
target/arm: Implement SVE FP Compare with Zero Group
83
target/arm: Implement SVE floating-point trig multiply-add coefficient
84
target/arm: Implement SVE floating-point convert precision
85
target/arm: Implement SVE floating-point convert to integer
86
target/arm: Implement SVE floating-point round to integral value
87
target/arm: Implement SVE floating-point unary operations
88
target/arm: Implement SVE MOVPRFX
89
target/arm: Implement SVE floating-point complex add
90
target/arm: Implement SVE fp complex multiply add
91
target/arm: Pass index to AdvSIMD FCMLA (indexed)
92
target/arm: Implement SVE fp complex multiply add (indexed)
93
target/arm: Implement SVE dot product (vectors)
94
target/arm: Implement SVE dot product (indexed)
95
target/arm: Enable SVE for aarch64-linux-user
96
target/arm: Implement ARMv8.2-DotProd
97
target/arm: Fix SVE signed division vs x86 overflow exception
98
target/arm: Fix SVE system register access checks
99
target/arm: Prune a57 features from max
100
target/arm: Prune a15 features from max
101
target/arm: Add ID_ISAR6
102
103
include/sysemu/device_tree.h | 16 +
104
target/arm/cpu.h | 3 +
105
target/arm/helper-sve.h | 682 +++++++++++++++
106
target/arm/helper.h | 44 +-
107
device_tree.c | 78 +-
108
hw/arm/boot.c | 41 +-
109
hw/arm/fsl-imx7.c | 8 +-
110
hw/arm/mcimx7d-sabre.c | 2 -
111
hw/arm/sysbus-fdt.c | 53 +-
112
hw/arm/virt.c | 70 +-
113
hw/block/fdc.c | 9 +-
114
hw/sd/bcm2835_sdhost.c | 13 +-
115
hw/sd/core.c | 2 +-
116
hw/sd/milkymist-memcard.c | 3 +-
117
hw/sd/omap_mmc.c | 6 +-
118
hw/sd/pl181.c | 11 +-
119
hw/sd/sdhci.c | 15 +-
120
hw/sd/ssi-sd.c | 6 +-
121
linux-user/elfload.c | 2 +
122
target/arm/cpu.c | 36 +-
123
target/arm/cpu64.c | 13 +-
124
target/arm/helper.c | 44 +-
125
target/arm/kvm32.c | 27 +-
126
target/arm/sve_helper.c | 1875 +++++++++++++++++++++++++++++++++++++++++-
127
target/arm/translate-a64.c | 62 +-
128
target/arm/translate-sve.c | 1688 ++++++++++++++++++++++++++++++++++++-
129
target/arm/translate.c | 102 ++-
130
target/arm/vec_helper.c | 311 ++++++-
131
hw/sd/trace-events | 2 +-
132
target/arm/sve.decode | 427 ++++++++++
133
30 files changed, 5394 insertions(+), 257 deletions(-)
134
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use assert() instead of error_setg(&error_abort),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
Likewise, don't error_setg(&error_abort, ...), use assert().
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: John Snow <jsnow@redhat.com>
12
Message-id: 20180625165749.3910-2-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/block/fdc.c | 9 +--------
16
1 file changed, 1 insertion(+), 8 deletions(-)
17
18
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/fdc.c
21
+++ b/hw/block/fdc.c
22
@@ -XXX,XX +XXX,XX @@ static int pick_geometry(FDrive *drv)
23
nb_sectors,
24
FloppyDriveType_str(parse->drive));
25
}
26
+ assert(type_match != -1 && "misconfigured fd_format");
27
match = type_match;
28
}
29
-
30
- /* No match of any kind found -- fd_format is misconfigured, abort. */
31
- if (match == -1) {
32
- error_setg(&error_abort, "No candidate geometries present in table "
33
- " for floppy drive type '%s'",
34
- FloppyDriveType_str(drv->drive));
35
- }
36
-
37
parse = &(fd_formats[match]);
38
39
out:
40
--
41
2.17.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use error_report() + exit() instead of error_setg(&error_fatal),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
9
This fixes CID 1352173:
10
"Passing null pointer dt_name to qemu_fdt_node_path, which dereferences it."
11
12
And this also fixes:
13
14
hw/arm/sysbus-fdt.c:322:9: warning: Array access (from variable 'node_path') results in a null pointer dereference
15
if (node_path[1]) {
16
^~~~~~~~~~~~
17
18
Fixes: Coverity CID 1352173 (Dereference after null check)
19
Suggested-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Message-id: 20180625165749.3910-3-f4bug@amsat.org
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/arm/sysbus-fdt.c | 53 +++++++++++++++++++++++++--------------------
26
1 file changed, 30 insertions(+), 23 deletions(-)
27
28
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sysbus-fdt.c
31
+++ b/hw/arm/sysbus-fdt.c
32
@@ -XXX,XX +XXX,XX @@ static void copy_properties_from_host(HostProperty *props, int nb_props,
33
r = qemu_fdt_getprop(host_fdt, node_path,
34
props[i].name,
35
&prop_len,
36
- props[i].optional ? &err : &error_fatal);
37
+ &err);
38
if (r) {
39
qemu_fdt_setprop(guest_fdt, nodename,
40
props[i].name, r, prop_len);
41
} else {
42
- if (prop_len != -FDT_ERR_NOTFOUND) {
43
- /* optional property not returned although property exists */
44
- error_report_err(err);
45
- } else {
46
+ if (props[i].optional && prop_len == -FDT_ERR_NOTFOUND) {
47
+ /* optional property does not exist */
48
error_free(err);
49
+ } else {
50
+ error_report_err(err);
51
+ }
52
+ if (!props[i].optional) {
53
+ /* mandatory property not found: bail out */
54
+ exit(1);
55
}
56
}
57
}
58
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
59
60
node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
61
if (node_offset <= 0) {
62
- error_setg(&error_fatal,
63
- "not able to locate clock handle %d in host device tree",
64
- host_phandle);
65
+ error_report("not able to locate clock handle %d in host device tree",
66
+ host_phandle);
67
+ exit(1);
68
}
69
node_path = g_malloc(path_len);
70
while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
71
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
72
node_path = g_realloc(node_path, path_len);
73
}
74
if (ret < 0) {
75
- error_setg(&error_fatal,
76
- "not able to retrieve node path for clock handle %d",
77
- host_phandle);
78
+ error_report("not able to retrieve node path for clock handle %d",
79
+ host_phandle);
80
+ exit(1);
81
}
82
83
r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
84
&error_fatal);
85
if (strcmp(r, "fixed-clock")) {
86
- error_setg(&error_fatal,
87
- "clock handle %d is not a fixed clock", host_phandle);
88
+ error_report("clock handle %d is not a fixed clock", host_phandle);
89
+ exit(1);
90
}
91
92
nodename = strrchr(node_path, '/');
93
@@ -XXX,XX +XXX,XX @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
94
95
dt_name = sysfs_to_dt_name(vbasedev->name);
96
if (!dt_name) {
97
- error_setg(&error_fatal, "%s incorrect sysfs device name %s",
98
- __func__, vbasedev->name);
99
+ error_report("%s incorrect sysfs device name %s",
100
+ __func__, vbasedev->name);
101
+ exit(1);
102
}
103
node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
104
&error_fatal);
105
if (!node_path || !node_path[0]) {
106
- error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
107
- __func__, dt_name, vdev->compat);
108
+ error_report("%s unable to retrieve node path for %s/%s",
109
+ __func__, dt_name, vdev->compat);
110
+ exit(1);
111
}
112
113
if (node_path[1]) {
114
- error_setg(&error_fatal, "%s more than one node matching %s/%s!",
115
- __func__, dt_name, vdev->compat);
116
+ error_report("%s more than one node matching %s/%s!",
117
+ __func__, dt_name, vdev->compat);
118
+ exit(1);
119
}
120
121
g_free(dt_name);
122
123
if (vbasedev->num_regions != 5) {
124
- error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
125
- __func__);
126
+ error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
127
+ exit(1);
128
}
129
130
/* generate nodes for DMA_CLK and PTP_CLK */
131
r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
132
&prop_len, &error_fatal);
133
if (prop_len != 8) {
134
- error_setg(&error_fatal, "%s clocks property should contain 2 handles",
135
- __func__);
136
+ error_report("%s clocks property should contain 2 handles", __func__);
137
+ exit(1);
138
}
139
host_clock_phandles = (uint32_t *)r;
140
guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
141
--
142
2.17.1
143
144
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use error_report() + exit() instead of error_setg(&error_fatal),
4
as suggested by the "qapi/error.h" documentation:
5
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
13
Message-id: 20180625165749.3910-4-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
device_tree.c | 23 +++++++++++++----------
17
1 file changed, 13 insertions(+), 10 deletions(-)
18
19
diff --git a/device_tree.c b/device_tree.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/device_tree.c
22
+++ b/device_tree.c
23
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
24
const char *parent_node;
25
26
if (strstr(dirname, root_dir) != dirname) {
27
- error_setg(&error_fatal, "%s: %s must be searched within %s",
28
- __func__, dirname, root_dir);
29
+ error_report("%s: %s must be searched within %s",
30
+ __func__, dirname, root_dir);
31
+ exit(1);
32
}
33
parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];
34
35
d = opendir(dirname);
36
if (!d) {
37
- error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
38
- return;
39
+ error_report("%s cannot open %s", __func__, dirname);
40
+ exit(1);
41
}
42
43
while ((de = readdir(d)) != NULL) {
44
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
45
tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);
46
47
if (lstat(tmpnam, &st) < 0) {
48
- error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
49
+ error_report("%s cannot lstat %s", __func__, tmpnam);
50
+ exit(1);
51
}
52
53
if (S_ISREG(st.st_mode)) {
54
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
55
gsize len;
56
57
if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
58
- error_setg(&error_fatal, "%s not able to extract info from %s",
59
- __func__, tmpnam);
60
+ error_report("%s not able to extract info from %s",
61
+ __func__, tmpnam);
62
+ exit(1);
63
}
64
65
if (strlen(parent_node) > 0) {
66
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void)
67
host_fdt = create_device_tree(&host_fdt_size);
68
read_fstree(host_fdt, SYSFS_DT_BASEDIR);
69
if (fdt_check_header(host_fdt)) {
70
- error_setg(&error_fatal,
71
- "%s host device tree extracted into memory is invalid",
72
- __func__);
73
+ error_report("%s host device tree extracted into memory is invalid",
74
+ __func__);
75
+ exit(1);
76
}
77
return host_fdt;
78
}
79
--
80
2.17.1
81
82
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
When running dtc on the guest /proc/device-tree we get the
3
The SMMUNotifierNode struct is not necessary and brings extra
4
following warnings: "Warning (unit_address_vs_reg): Node <name>
4
complexity so let's remove it. We now directly track the SMMUDevices
5
has a reg or ranges property, but no unit name", with name:
5
which have registered IOMMU MR notifiers.
6
/intc, /intc/its, /intc/v2m.
7
6
8
Nodes should have a name in the form <name>[@<unit-address>] where
7
This is inspired from the same transformation on intel-iommu
9
unit-address is the primary address used to access the device, listed
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
10
in the node's reg property. This fix seems to make dtc happy.
9
("intel-iommu: remove IntelIOMMUNotifierNode")
11
10
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Message-id: 1530044492-24921-3-git-send-email-eric.auger@redhat.com
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
15
---
17
hw/arm/virt.c | 63 +++++++++++++++++++++++++++++++--------------------
16
include/hw/arm/smmu-common.h | 8 ++------
18
1 file changed, 39 insertions(+), 24 deletions(-)
17
hw/arm/smmu-common.c | 6 +++---
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
19
20
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt.c
23
--- a/include/hw/arm/smmu-common.h
23
+++ b/hw/arm/virt.c
24
+++ b/include/hw/arm/smmu-common.h
24
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
25
26
AddressSpace as;
26
static void fdt_add_its_gic_node(VirtMachineState *vms)
27
uint32_t cfg_cache_hits;
28
uint32_t cfg_cache_misses;
29
+ QLIST_ENTRY(SMMUDevice) next;
30
} SMMUDevice;
31
32
-typedef struct SMMUNotifierNode {
33
- SMMUDevice *sdev;
34
- QLIST_ENTRY(SMMUNotifierNode) next;
35
-} SMMUNotifierNode;
36
-
37
typedef struct SMMUPciBus {
38
PCIBus *bus;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
27
{
56
{
28
+ char *nodename;
57
- SMMUNotifierNode *node;
29
+
58
+ SMMUDevice *sdev;
30
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
59
31
- qemu_fdt_add_subnode(vms->fdt, "/intc/its");
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
32
- qemu_fdt_setprop_string(vms->fdt, "/intc/its", "compatible",
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
33
+ nodename = g_strdup_printf("/intc/its@%" PRIx64,
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
34
+ vms->memmap[VIRT_GIC_ITS].base);
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
35
+ qemu_fdt_add_subnode(vms->fdt, nodename);
64
}
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
}
65
}
48
66
49
static void fdt_add_v2m_gic_node(VirtMachineState *vms)
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
50
{
74
{
51
+ char *nodename;
75
- SMMUNotifierNode *node;
52
+
76
+ SMMUDevice *sdev;
53
+ nodename = g_strdup_printf("/intc/v2m@%" PRIx64,
77
54
+ vms->memmap[VIRT_GIC_V2M].base);
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
55
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
56
- qemu_fdt_add_subnode(vms->fdt, "/intc/v2m");
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
57
- qemu_fdt_setprop_string(vms->fdt, "/intc/v2m", "compatible",
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
58
+ qemu_fdt_add_subnode(vms->fdt, nodename);
82
IOMMUNotifier *n;
59
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
83
60
"arm,gic-v2m-frame");
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
61
- qemu_fdt_setprop(vms->fdt, "/intc/v2m", "msi-controller", NULL, 0);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
62
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/v2m", "reg",
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
63
+ qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
87
SMMUv3State *s3 = sdev->smmu;
64
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
88
SMMUState *s = &(s3->smmu_state);
65
2, vms->memmap[VIRT_GIC_V2M].base,
89
- SMMUNotifierNode *node = NULL;
66
2, vms->memmap[VIRT_GIC_V2M].size);
90
- SMMUNotifierNode *next_node = NULL;
67
- qemu_fdt_setprop_cell(vms->fdt, "/intc/v2m", "phandle", vms->msi_phandle);
91
68
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
92
if (new & IOMMU_NOTIFIER_MAP) {
69
+ g_free(nodename);
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
70
}
119
}
71
120
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
--
121
--
146
2.17.1
122
2.20.1
147
123
148
124
diff view generated by jsdifflib
1
We don't actually implement SD command CRC checking, because
1
In the stripe8() function we use a variable length array; however
2
for almost all of our SD controllers the CRC generation is
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
done in hardware, and so modelling CRC generation and checking
3
a fixed-length array and an assert instead.
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
4
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20180626180324.5537-1-peter.maydell@linaro.org
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
20
---
11
---
21
hw/sd/core.c | 2 +-
12
hw/ssi/xilinx_spips.c | 6 ++++--
22
hw/sd/trace-events | 2 +-
13
1 file changed, 4 insertions(+), 2 deletions(-)
23
2 files changed, 2 insertions(+), 2 deletions(-)
24
14
25
diff --git a/hw/sd/core.c b/hw/sd/core.c
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/core.c
17
--- a/hw/ssi/xilinx_spips.c
28
+++ b/hw/sd/core.c
18
+++ b/hw/ssi/xilinx_spips.c
29
@@ -XXX,XX +XXX,XX @@ int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
30
{
22
{
31
SDState *card = get_card(sdbus);
23
- uint8_t r[num];
32
24
- memset(r, 0, sizeof(uint8_t) * num);
33
- trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg, req->crc);
25
+ uint8_t r[MAX_NUM_BUSSES];
34
+ trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg);
26
int idx[2] = {0, 0};
35
if (card) {
27
int bit[2] = {0, 7};
36
SDCardClass *sc = SD_CARD_GET_CLASS(card);
28
int d = dir;
37
29
38
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
30
+ assert(num <= MAX_NUM_BUSSES);
39
index XXXXXXX..XXXXXXX 100644
31
+ memset(r, 0, sizeof(uint8_t) * num);
40
--- a/hw/sd/trace-events
32
+
41
+++ b/hw/sd/trace-events
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
42
@@ -XXX,XX +XXX,XX @@ bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x"
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
43
bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n"
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
44
45
# hw/sd/core.c
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"
47
+sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
48
sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
49
sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
50
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
51
--
36
--
52
2.17.1
37
2.20.1
53
38
54
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Normally configure identifies the source path by looking
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
2
5
3
There is no need to re-set these 9 features already
6
There isn't really an obvious use case for the --source-path
4
implied by the call to aarch64_a57_initfn.
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
5
11
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
The fact that nobody complained suggests that there isn't
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
any use of this option and we aren't testing it either;
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
remove it. This allows us to move the "make $source_path
9
Message-id: 20180629001538.11415-4-richard.henderson@linaro.org
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
17
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
11
---
21
---
12
target/arm/cpu64.c | 9 ---------
22
configure | 10 ++--------
13
1 file changed, 9 deletions(-)
23
1 file changed, 2 insertions(+), 8 deletions(-)
14
24
15
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
diff --git a/configure b/configure
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100755
17
--- a/target/arm/cpu64.c
27
--- a/configure
18
+++ b/target/arm/cpu64.c
28
+++ b/configure
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
20
* whereas the architecture requires them to be present in both if
30
21
* present in either.
31
# default parameters
22
*/
32
source_path=$(dirname "$0")
23
- set_feature(&cpu->env, ARM_FEATURE_V8);
33
+# make source path absolute
24
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
34
+source_path=$(cd "$source_path"; pwd)
25
- set_feature(&cpu->env, ARM_FEATURE_NEON);
35
cpu=""
26
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
36
iasl="iasl"
27
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
37
interp_prefix="/usr/gnemul/qemu-%M"
28
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
38
@@ -XXX,XX +XXX,XX @@ for opt do
29
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
39
;;
30
set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
40
--cxx=*) CXX="$optarg"
31
set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
41
;;
32
set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
42
- --source-path=*) source_path="$optarg"
33
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
43
- ;;
34
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
44
--cpu=*) cpu="$optarg"
35
- set_feature(&cpu->env, ARM_FEATURE_CRC);
45
;;
36
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
37
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
38
set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
48
LDFLAGS="-g $LDFLAGS"
49
fi
50
51
-# make source path absolute
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
39
--
74
--
40
2.17.1
75
2.20.1
41
76
42
77
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Enforce that for M-profile various FPSCR bits which are RES0 there
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
2
5
3
When running dtc on the guest /proc/device-tree we get the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
following warning: Warning (unit_address_vs_reg): Node /memory
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
has a reg or ranges property, but no unit name".
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
10
target/arm/vfp_helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
6
12
7
Let's fix that by adding the unit address to the node name. We also
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
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
14
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
15
--- a/target/arm/vfp_helper.c
25
+++ b/hw/arm/boot.c
16
+++ b/target/arm/vfp_helper.c
26
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
27
hwaddr addr_limit, AddressSpace *as)
18
val &= ~FPCR_FZ16;
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
}
19
}
44
20
45
+ /* nop all root nodes matching /memory or /memory@unit-address */
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
46
+ node_path = qemu_fdt_node_unit_path(fdt, "memory", &err);
22
+ /*
47
+ if (err) {
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
48
+ error_report_err(err);
24
+ * and also for the trapped-exception-handling bits IxE.
49
+ goto fail;
25
+ */
26
+ val &= 0xf7c0009f;
50
+ }
27
+ }
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
+
28
+
59
if (nb_numa_nodes > 0) {
29
/*
60
- /*
30
* We don't implement trapped exception handling, so the
61
- * Turn the /memory node created before into a NOP node, then create
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
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
--
32
--
119
2.17.1
33
2.20.1
120
34
121
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
2
4
3
We already check for the same condition within the normal integer
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
sdiv and sdiv64 helpers. Use a slightly different formation that
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
does not require deducing the expression type.
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
10
1 file changed, 6 insertions(+)
6
11
7
Fixes: f97cfd596ed
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
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
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/sve_helper.c
14
--- a/hw/intc/armv7m_nvic.c
21
+++ b/target/arm/sve_helper.c
15
+++ b/hw/intc/armv7m_nvic.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
23
#define DO_MIN(N, M) ((N) >= (M) ? (M) : (N))
17
return 0;
24
#define DO_ABD(N, M) ((N) >= (M) ? (N) - (M) : (M) - (N))
18
}
25
#define DO_MUL(N, M) (N * M)
19
return cpu->env.v7m.sfar;
26
-#define DO_DIV(N, M) (M ? N / M : 0)
20
+ case 0xf40: /* MVFR0 */
27
+
21
+ return cpu->isar.mvfr0;
28
+
22
+ case 0xf44: /* MVFR1 */
29
+/*
23
+ return cpu->isar.mvfr1;
30
+ * We must avoid the C undefined behaviour cases: division by
24
+ case 0xf48: /* MVFR2 */
31
+ * zero and signed division of INT_MIN by -1. Both of these
25
+ return cpu->isar.mvfr2;
32
+ * have architecturally defined required results for Arm.
26
default:
33
+ * We special case all signed divisions by -1 to avoid having
27
bad_offset:
34
+ * to deduce the minimum integer for the type involved.
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
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
--
29
--
58
2.17.1
30
2.20.1
59
31
60
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile floating point support has three associated config
2
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
Enable ARM_FEATURE_SVE for the generic "max" cpu.
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
4
Add support for all of these as simple reads-as-written registers.
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
5
We will hook up actual functionality later.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
The main complexity here is handling the FPCCR register, which
8
Message-id: 20180627043328.11531-35-richard.henderson@linaro.org
8
has a mix of banked and unbanked bits.
9
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
9
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: 20190416125744.27770-4-peter.maydell@linaro.org
10
---
20
---
11
linux-user/elfload.c | 1 +
21
target/arm/cpu.h | 34 ++++++++++++
12
target/arm/cpu.c | 7 +++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
13
target/arm/cpu64.c | 1 +
23
target/arm/cpu.c | 5 ++
14
3 files changed, 9 insertions(+)
24
target/arm/machine.c | 16 ++++++
15
25
4 files changed, 180 insertions(+)
16
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
26
17
index XXXXXXX..XXXXXXX 100644
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
--- a/linux-user/elfload.c
28
index XXXXXXX..XXXXXXX 100644
19
+++ b/linux-user/elfload.c
29
--- a/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
30
+++ b/target/arm/cpu.h
21
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
32
uint32_t scr[M_REG_NUM_BANKS];
23
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
33
uint32_t msplim[M_REG_NUM_BANKS];
24
+ GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
34
uint32_t psplim[M_REG_NUM_BANKS];
25
#undef GET_FEATURE
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
26
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
27
return hwcaps;
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
39
+ uint32_t nsacr;
40
} v7m;
41
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
76
/*
77
* System register ID fields.
78
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
}
85
case 0xd84: /* CSSELR */
86
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd88: /* CPACR */
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ return 0;
90
+ }
91
+ return cpu->env.v7m.cpacr[attrs.secure];
92
+ case 0xd8c: /* NSACR */
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ return 0;
95
+ }
96
+ return cpu->env.v7m.nsacr;
97
/* TODO: Implement debug registers. */
98
case 0xd90: /* MPU_TYPE */
99
/* Unified MPU; if the MPU is not present this value is zero */
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
101
return 0;
102
}
103
return cpu->env.v7m.sfar;
104
+ case 0xf34: /* FPCCR */
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
106
+ return 0;
107
+ }
108
+ if (attrs.secure) {
109
+ return cpu->env.v7m.fpccr[M_REG_S];
110
+ } else {
111
+ /*
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
114
+ * other non-banked bits RAZ.
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
116
+ */
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
119
+ R_V7M_FPCCR_CLRONRET_MASK |
120
+ R_V7M_FPCCR_MONRDY_MASK;
121
+
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
124
+ }
125
+
126
+ value &= mask;
127
+
128
+ value |= cpu->env.v7m.fpccr[M_REG_NS];
129
+ return value;
130
+ }
131
+ case 0xf38: /* FPCAR */
132
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
133
+ return 0;
134
+ }
135
+ return cpu->env.v7m.fpcar[attrs.secure];
136
+ case 0xf3c: /* FPDSCR */
137
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
138
+ return 0;
139
+ }
140
+ return cpu->env.v7m.fpdscr[attrs.secure];
141
case 0xf40: /* MVFR0 */
142
return cpu->isar.mvfr0;
143
case 0xf44: /* MVFR1 */
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
146
}
147
break;
148
+ case 0xd88: /* CPACR */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
152
+ }
153
+ break;
154
+ case 0xd8c: /* NSACR */
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
158
+ }
159
+ break;
160
case 0xd90: /* MPU_TYPE */
161
return; /* RO */
162
case 0xd94: /* MPU_CTRL */
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
165
break;
166
}
167
+ case 0xf34: /* FPCCR */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
237
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
238
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
33
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
34
/* and to the FP/Neon instructions */
242
}
35
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
243
36
+ /* and to the SVE instructions */
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
37
+ env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
38
+ env->cp15.cptr_el[3] |= CPTR_EZ;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
39
+ /* with maximum vector length */
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
40
+ env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
248
+ }
41
+ env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
249
/* Unlike A/R profile, M profile defines the reset LR value */
42
+ env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
250
env->regs[14] = 0xffffffff;
43
#else
251
44
/* Reset into the highest available EL */
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
45
if (arm_feature(env, ARM_FEATURE_EL3)) {
253
index XXXXXXX..XXXXXXX 100644
46
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
254
--- a/target/arm/machine.c
47
index XXXXXXX..XXXXXXX 100644
255
+++ b/target/arm/machine.c
48
--- a/target/arm/cpu64.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
49
+++ b/target/arm/cpu64.c
257
}
50
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
258
};
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
259
52
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
260
+static const VMStateDescription vmstate_m_fp = {
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
261
+ .name = "cpu/m/fp",
54
+ set_feature(&cpu->env, ARM_FEATURE_SVE);
262
+ .version_id = 1,
55
/* For usermode -cpu max we can use a larger and more efficient DCZ
263
+ .minimum_version_id = 1,
56
* blocksize since we don't have to follow what the hardware does.
264
+ .needed = vfp_needed,
57
*/
265
+ .fields = (VMStateField[]) {
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
271
+ VMSTATE_END_OF_LIST()
272
+ }
273
+};
274
+
275
static const VMStateDescription vmstate_m = {
276
.name = "cpu/m",
277
.version_id = 4,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
279
&vmstate_m_scr,
280
&vmstate_m_other_sp,
281
&vmstate_m_v8m,
282
+ &vmstate_m_fp,
283
NULL
284
}
285
};
58
--
286
--
59
2.17.1
287
2.20.1
60
288
61
289
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The only "system register" that M-profile floating point exposes
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
2
5
3
The load/store API will ease further code movement.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
4
12
5
Per the Physical Layer Simplified Spec. "3.6 Bus Protocol":
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
6
7
"In the CMD line the Most Significant Bit (MSB) is transmitted
8
first, the Least Significant Bit (LSB) is the last."
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/sd/bcm2835_sdhost.c | 13 +++++--------
15
hw/sd/milkymist-memcard.c | 3 +--
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
22
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/sd/bcm2835_sdhost.c
15
--- a/target/arm/translate.c
25
+++ b/hw/sd/bcm2835_sdhost.c
16
+++ b/target/arm/translate.c
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
27
goto error;
18
}
28
}
19
}
29
if (!(s->cmd & SDCMD_NO_RESPONSE)) {
20
} else { /* !dp */
30
-#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
21
+ bool is_sysreg;
31
- | (rsp[n + 2] << 8) | rsp[n + 3])
22
+
32
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
23
if ((insn & 0x6f) != 0x00)
33
goto error;
24
return 1;
34
}
25
rn = VFP_SREG_N(insn);
35
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
26
+
36
goto error;
27
+ is_sysreg = extract32(insn, 21, 1);
37
}
28
+
38
if (rlen == 4) {
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
39
- s->rsp[0] = RWORD(0);
30
+ /*
40
+ s->rsp[0] = ldl_be_p(&rsp[0]);
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
41
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
42
} else {
33
+ */
43
- s->rsp[0] = RWORD(12);
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
44
- s->rsp[1] = RWORD(8);
35
+ return 1;
45
- s->rsp[2] = RWORD(4);
36
+ }
46
- s->rsp[3] = RWORD(0);
37
+ }
47
+ s->rsp[0] = ldl_be_p(&rsp[12]);
38
+
48
+ s->rsp[1] = ldl_be_p(&rsp[8]);
39
if (insn & ARM_CP_RW_BIT) {
49
+ s->rsp[2] = ldl_be_p(&rsp[4]);
40
/* vfp->arm */
50
+ s->rsp[3] = ldl_be_p(&rsp[0]);
41
- if (insn & (1 << 21)) {
51
}
42
+ if (is_sysreg) {
52
-#undef RWORD
43
/* system register */
53
}
44
rn >>= 1;
54
/* We never really delay commands, so if this was a 'busywait' command
45
55
* then we've completed it now and can raise the interrupt.
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
56
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
47
}
57
index XXXXXXX..XXXXXXX 100644
48
} else {
58
--- a/hw/sd/milkymist-memcard.c
49
/* arm->vfp */
59
+++ b/hw/sd/milkymist-memcard.c
50
- if (insn & (1 << 21)) {
60
@@ -XXX,XX +XXX,XX @@ static void memcard_sd_command(MilkymistMemcardState *s)
51
+ if (is_sysreg) {
61
SDRequest req;
52
rn >>= 1;
62
53
/* system register */
63
req.cmd = s->command[0] & 0x3f;
54
switch (rn) {
64
- req.arg = (s->command[1] << 24) | (s->command[2] << 16)
65
- | (s->command[3] << 8) | s->command[4];
66
+ req.arg = ldl_be_p(s->command + 1);
67
req.crc = s->command[5];
68
69
s->response[0] = req.cmd;
70
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/sd/omap_mmc.c
73
+++ b/hw/sd/omap_mmc.c
74
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
75
CID_CSD_OVERWRITE;
76
if (host->sdio & (1 << 13))
77
mask |= AKE_SEQ_ERROR;
78
- rspstatus = (response[0] << 24) | (response[1] << 16) |
79
- (response[2] << 8) | (response[3] << 0);
80
+ rspstatus = ldl_be_p(response);
81
break;
82
83
case sd_r2:
84
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
85
}
86
rsplen = 4;
87
88
- rspstatus = (response[0] << 24) | (response[1] << 16) |
89
- (response[2] << 8) | (response[3] << 0);
90
+ rspstatus = ldl_be_p(response);
91
if (rspstatus & 0x80000000)
92
host->status &= 0xe000;
93
else
94
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/sd/pl181.c
97
+++ b/hw/sd/pl181.c
98
@@ -XXX,XX +XXX,XX @@ static void pl181_send_command(PL181State *s)
99
if (rlen < 0)
100
goto error;
101
if (s->cmd & PL181_CMD_RESPONSE) {
102
-#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
103
- | (response[n + 2] << 8) | response[n + 3])
104
if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
105
goto error;
106
if (rlen != 4 && rlen != 16)
107
goto error;
108
- s->response[0] = RWORD(0);
109
+ s->response[0] = ldl_be_p(&response[0]);
110
if (rlen == 4) {
111
s->response[1] = s->response[2] = s->response[3] = 0;
112
} else {
113
- s->response[1] = RWORD(4);
114
- s->response[2] = RWORD(8);
115
- s->response[3] = RWORD(12) & ~1;
116
+ s->response[1] = ldl_be_p(&response[4]);
117
+ s->response[2] = ldl_be_p(&response[8]);
118
+ s->response[3] = ldl_be_p(&response[12]) & ~1;
119
}
120
DPRINTF("Response received\n");
121
s->status |= PL181_STATUS_CMDRESPEND;
122
-#undef RWORD
123
} else {
124
DPRINTF("Command sent\n");
125
s->status |= PL181_STATUS_CMDSENT;
126
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/sd/sdhci.c
129
+++ b/hw/sd/sdhci.c
130
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
131
132
if (s->cmdreg & SDHC_CMD_RESPONSE) {
133
if (rlen == 4) {
134
- s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
135
- (response[2] << 8) | response[3];
136
+ s->rspreg[0] = ldl_be_p(response);
137
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
138
trace_sdhci_response4(s->rspreg[0]);
139
} else if (rlen == 16) {
140
- s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
141
- (response[13] << 8) | response[14];
142
- s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
143
- (response[9] << 8) | response[10];
144
- s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
145
- (response[5] << 8) | response[6];
146
+ s->rspreg[0] = ldl_be_p(&response[11]);
147
+ s->rspreg[1] = ldl_be_p(&response[7]);
148
+ s->rspreg[2] = ldl_be_p(&response[3]);
149
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
150
response[2];
151
trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
152
@@ -XXX,XX +XXX,XX @@ static void sdhci_end_transfer(SDHCIState *s)
153
trace_sdhci_end_transfer(request.cmd, request.arg);
154
sdbus_do_command(&s->sdbus, &request, response);
155
/* Auto CMD12 response goes to the upper Response register */
156
- s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
157
- (response[2] << 8) | response[3];
158
+ s->rspreg[3] = ldl_be_p(response);
159
}
160
161
s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
162
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/sd/ssi-sd.c
165
+++ b/hw/sd/ssi-sd.c
166
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
167
uint8_t longresp[16];
168
/* FIXME: Check CRC. */
169
request.cmd = s->cmd;
170
- request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
171
- | (s->cmdarg[2] << 8) | s->cmdarg[3];
172
+ request.arg = ldl_be_p(s->cmdarg);
173
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
174
s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
175
if (s->arglen <= 0) {
176
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
177
/* CMD13 returns a 2-byte statuse work. Other commands
178
only return the first byte. */
179
s->arglen = (s->cmd == 13) ? 2 : 1;
180
- cardstatus = (longresp[0] << 24) | (longresp[1] << 16)
181
- | (longresp[2] << 8) | longresp[3];
182
+ cardstatus = ldl_be_p(longresp);
183
status = 0;
184
if (((cardstatus >> 9) & 0xf) < 4)
185
status |= SSI_SDR_IDLE;
186
--
55
--
187
2.17.1
56
2.20.1
188
57
189
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Like AArch64, M-profile floating point has no FPEXC enable
2
bit to gate floating point; so always set the VFPEN TB flag.
2
3
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
M-profile also has CPACR and NSACR similar to A-profile;
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
they behave slightly differently:
5
Message-id: 20180627043328.11531-10-richard.henderson@linaro.org
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
9
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
7
---
19
---
8
target/arm/helper-sve.h | 5 +++
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
9
target/arm/sve_helper.c | 41 +++++++++++++++++++++++++
21
target/arm/translate.c | 10 ++++++--
10
target/arm/translate-sve.c | 62 ++++++++++++++++++++++++++++++++++++++
22
2 files changed, 60 insertions(+), 5 deletions(-)
11
target/arm/sve.decode | 5 +++
12
4 files changed, 113 insertions(+)
13
23
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
26
--- a/target/arm/helper.c
17
+++ b/target/arm/helper-sve.h
27
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
19
DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
return target_el;
20
DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
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
+
27
DEF_HELPER_FLAGS_4(sve_asr_zpzi_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
DEF_HELPER_FLAGS_4(sve_asr_zpzi_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
DEF_HELPER_FLAGS_4(sve_asr_zpzi_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve_helper.c
33
+++ b/target/arm/sve_helper.c
34
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
35
}
36
}
30
}
37
31
38
+/* Copy Zn into Zd, and store zero into inactive elements. */
32
+/*
39
+void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
34
+ * security state and privilege level.
35
+ */
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
40
+{
37
+{
41
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
42
+ uint64_t *d = vd, *n = vn;
39
+ case 0:
43
+ uint8_t *pg = vg;
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
44
+ for (i = 0; i < opr_sz; i += 1) {
41
+ return false;
45
+ d[i] = n[i] & expand_pred_b(pg[H1(i)]);
42
+ case 1:
43
+ return is_priv;
44
+ case 3:
45
+ return true;
46
+ default:
47
+ g_assert_not_reached();
46
+ }
48
+ }
47
+}
49
+}
48
+
50
+
49
+void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
50
+{
52
ARMMMUIdx mmu_idx, bool ignfault)
51
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
53
{
52
+ uint64_t *d = vd, *n = vn;
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
53
+ uint8_t *pg = vg;
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
54
+ for (i = 0; i < opr_sz; i += 1) {
56
break;
55
+ d[i] = n[i] & expand_pred_h(pg[H1(i)]);
57
case EXCP_NOCP:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
56
+ }
76
+ }
57
+}
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
58
+
89
+
59
+void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
60
+{
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
61
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
62
+ uint64_t *d = vd, *n = vn;
93
+ return 3;
63
+ uint8_t *pg = vg;
94
+ }
64
+ for (i = 0; i < opr_sz; i += 1) {
95
+ }
65
+ d[i] = n[i] & expand_pred_s(pg[H1(i)]);
66
+ }
67
+}
68
+
96
+
69
+void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, uint32_t desc)
97
+ return 0;
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
84
--- a/target/arm/translate-sve.c
85
+++ b/target/arm/translate-sve.c
86
@@ -XXX,XX +XXX,XX @@ static bool do_clr_zp(DisasContext *s, int rd, int pg, int esz)
87
return true;
88
}
89
90
+/* Copy Zn into Zd, storing zeros into inactive elements. */
91
+static void do_movz_zpz(DisasContext *s, int rd, int rn, int pg, int esz)
92
+{
93
+ static gen_helper_gvec_3 * const fns[4] = {
94
+ gen_helper_sve_movz_b, gen_helper_sve_movz_h,
95
+ gen_helper_sve_movz_s, gen_helper_sve_movz_d,
96
+ };
97
+ unsigned vsz = vec_full_reg_size(s);
98
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
99
+ vec_full_reg_offset(s, rn),
100
+ pred_full_reg_offset(s, pg),
101
+ vsz, vsz, 0, fns[esz]);
102
+}
103
+
104
static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
105
gen_helper_gvec_3 *fn)
106
{
107
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
108
return true;
109
}
110
111
+/* Load and broadcast element. */
112
+static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
113
+{
114
+ if (!sve_access_check(s)) {
115
+ return true;
116
+ }
98
+ }
117
+
99
+
118
+ unsigned vsz = vec_full_reg_size(s);
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
119
+ unsigned psz = pred_full_reg_size(s);
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
120
+ unsigned esz = dtype_esz[a->dtype];
102
* 1 : trap only EL0 accesses
121
+ TCGLabel *over = gen_new_label();
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
122
+ TCGv_i64 temp;
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
123
+
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
124
+ /* If the guarding predicate has no bits set, no load occurs. */
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
125
+ if (psz <= 8) {
107
- || arm_el_is_aa64(env, 1)) {
126
+ /* Reduce the pred_esz_masks value simply to reduce the
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
127
+ * size of the code generated here.
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
128
+ */
110
}
129
+ uint64_t psz_mask = MAKE_64BIT_MASK(0, psz * 8);
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
130
+ temp = tcg_temp_new_i64();
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
131
+ tcg_gen_ld_i64(temp, cpu_env, pred_full_reg_offset(s, a->pg));
132
+ tcg_gen_andi_i64(temp, temp, pred_esz_masks[esz] & psz_mask);
133
+ tcg_gen_brcondi_i64(TCG_COND_EQ, temp, 0, over);
134
+ tcg_temp_free_i64(temp);
135
+ } else {
136
+ TCGv_i32 t32 = tcg_temp_new_i32();
137
+ find_last_active(s, t32, esz, a->pg);
138
+ tcg_gen_brcondi_i32(TCG_COND_LT, t32, 0, over);
139
+ tcg_temp_free_i32(t32);
140
+ }
141
+
142
+ /* Load the data. */
143
+ temp = tcg_temp_new_i64();
144
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
145
+ tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
146
+ s->be_data | dtype_mop[a->dtype]);
147
+
148
+ /* Broadcast to *all* elements. */
149
+ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
150
+ vsz, vsz, temp);
151
+ tcg_temp_free_i64(temp);
152
+
153
+ /* Zero the inactive elements. */
154
+ gen_set_label(over);
155
+ do_movz_zpz(s, a->rd, a->rd, a->pg, esz);
156
+ return true;
157
+}
158
+
159
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
160
int msz, int esz, int nreg)
161
{
162
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
163
index XXXXXXX..XXXXXXX 100644
113
index XXXXXXX..XXXXXXX 100644
164
--- a/target/arm/sve.decode
114
--- a/target/arm/translate.c
165
+++ b/target/arm/sve.decode
115
+++ b/target/arm/translate.c
166
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
167
%imm8_16_10 16:5 10:3
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
168
%imm9_16_10 16:s6 10:3
118
*/
169
%size_23 23:2
119
if (s->fp_excp_el) {
170
+%dtype_23_13 23:2 13:2
120
- gen_exception_insn(s, 4, EXCP_UDEF,
171
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
172
# A combination of tsz:imm3 -- extract esize.
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
173
%tszimm_esz 22:2 5:5 !function=tszimm_esz
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
174
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
124
+ s->fp_excp_el);
175
# SVE load vector register
125
+ } else {
176
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
177
127
+ syn_fp_access_trap(1, 0xe, false),
178
+# SVE load and broadcast element
128
+ s->fp_excp_el);
179
+LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
129
+ }
180
+ &rpri_load dtype=%dtype_23_13 nreg=0
130
return 0;
181
+
131
}
182
### SVE Memory Contiguous Load Group
132
183
184
# SVE contiguous load (scalar plus scalar)
185
--
133
--
186
2.17.1
134
2.20.1
187
135
188
136
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
2
6
3
KVM implies V7VE, which implies ARM_DIV and THUMB_DIV. The conditional
7
For the moment we leave VLLDM and VLSTM as NOPs; in
4
detection here is therefore unnecessary. Because V7VE is already
8
a later commit we will fill in the proper implementation
5
unconditionally specified for all KVM hosts, ARM_DIV and THUMB_DIV are
9
for the case where an FPU is present.
6
already indirectly specified and do not need to be included here at all.
7
10
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
11
---
14
---
12
target/arm/kvm32.c | 19 +------------------
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
13
1 file changed, 1 insertion(+), 18 deletions(-)
16
1 file changed, 22 insertions(+), 4 deletions(-)
14
17
15
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/kvm32.c
20
--- a/target/arm/translate.c
18
+++ b/target/arm/kvm32.c
21
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
20
* and then query that CPU for the relevant ID registers.
23
case 6: case 7: case 14: case 15:
21
*/
24
/* Coprocessor. */
22
int i, ret, fdarray[3];
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
23
- uint32_t midr, id_pfr0, id_isar0, mvfr1;
26
- /* We don't currently implement M profile FP support,
24
+ uint32_t midr, id_pfr0, mvfr1;
27
- * so this entire space should give a NOCP fault, with
25
uint64_t features = 0;
28
- * the exception of the v8M VLLDM and VLSTM insns, which
26
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
27
* we know these will only support creating one kind of guest CPU,
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
28
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
31
+ if (extract32(insn, 24, 2) == 3) {
29
| ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
30
.addr = (uintptr_t)&id_pfr0,
33
+ }
31
},
34
+
32
- {
35
+ /*
33
- .id = KVM_REG_ARM | KVM_REG_SIZE_U32
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
34
- | ENCODE_CP_REG(15, 0, 0, 0, 2, 0, 0),
37
+ * * if there is no FPU then these insns must NOP in
35
- .addr = (uintptr_t)&id_isar0,
38
+ * Secure state and UNDEF in Nonsecure state
36
- },
39
+ * * if there is an FPU then these insns do not have
37
{
40
+ * the usual behaviour that disas_vfp_insn() provides of
38
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
41
+ * being controlled by CPACR/NSACR enable bits or the
39
| KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
42
+ * lazy-stacking logic.
40
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
43
*/
41
set_feature(&features, ARM_FEATURE_VFP3);
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
42
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
45
(insn & 0xffa00f00) == 0xec200a00) {
43
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
44
- switch (extract32(id_isar0, 24, 4)) {
47
/* Just NOP since FP support is not implemented */
45
- case 1:
48
break;
46
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
49
}
47
- break;
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
48
- case 2:
51
+ ((insn >> 8) & 0xe) == 10) {
49
- set_feature(&features, ARM_FEATURE_ARM_DIV);
52
+ /* FP, and the CPU supports it */
50
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
53
+ if (disas_vfp_insn(s, insn)) {
51
- break;
54
+ goto illegal_op;
52
- default:
55
+ }
53
- break;
56
+ break;
54
- }
57
+ }
55
-
58
+
56
if (extract32(id_pfr0, 12, 4) == 1) {
59
/* All other insns: NOCP */
57
set_feature(&features, ARM_FEATURE_THUMB2EE);
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
58
}
61
default_exception_el(s));
59
--
62
--
60
2.17.1
63
2.20.1
61
64
62
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
2
3
3
Leave ARM_CP_SVE, removing ARM_CP_FPU; the sve_access_check
4
(On a no-FPU system the bit will always be zero, so we don't need
4
produced by the flag already includes fp_access_check. If
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
5
we also check ARM_CP_FPU the double fp_access_check asserts.
6
6
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>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
14
---
10
---
15
target/arm/helper.c | 8 ++++----
11
target/arm/helper.c | 1 +
16
target/arm/translate-a64.c | 5 ++---
12
1 file changed, 1 insertion(+)
17
2 files changed, 6 insertions(+), 7 deletions(-)
18
13
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
24
static const ARMCPRegInfo zcr_el1_reginfo = {
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
25
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
20
", executing it\n", env->regs[15]);
26
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
21
env->regs[14] &= ~1;
27
- .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
28
+ .access = PL1_RW, .type = ARM_CP_SVE,
23
switch_v7m_security_state(env, true);
29
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
24
xpsr_write(env, 0, XPSR_IT);
30
.writefn = zcr_write, .raw_writefn = raw_write
25
env->regs[15] += 4;
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
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
62
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
63
default:
64
break;
65
}
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
--
26
--
77
2.17.1
27
2.20.1
78
28
79
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
7
---
10
---
8
target/arm/translate-sve.c | 85 ++++++++++++++++++++++++++------------
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
9
target/arm/sve.decode | 11 +++++
12
1 file changed, 49 insertions(+), 8 deletions(-)
10
2 files changed, 70 insertions(+), 26 deletions(-)
11
13
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
16
--- a/target/arm/helper.c
15
+++ b/target/arm/translate-sve.c
17
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
17
return true;
19
return xpsr_read(env) & mask;
18
}
20
break;
19
21
case 20: /* CONTROL */
20
+/* Indexed by [xs][msz]. */
22
- return env->v7m.control[env->v7m.secure];
21
+static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][3] = {
23
+ {
22
+ { gen_helper_sve_stbs_zsu,
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
23
+ gen_helper_sve_sths_zsu,
25
+ if (!env->v7m.secure) {
24
+ gen_helper_sve_stss_zsu, },
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
25
+ { gen_helper_sve_stbs_zss,
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
26
+ gen_helper_sve_sths_zss,
28
+ }
27
+ gen_helper_sve_stss_zss, },
29
+ return value;
28
+};
30
+ }
29
+
31
case 0x94: /* CONTROL_NS */
30
+/* Note that we overload xs=2 to indicate 64-bit offset. */
32
/* We have to handle this here because unprivileged Secure code
31
+static gen_helper_gvec_mem_scatter * const scatter_store_fn64[3][4] = {
33
* can read the NS CONTROL register.
32
+ { gen_helper_sve_stbd_zsu,
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
33
+ gen_helper_sve_sthd_zsu,
35
if (!env->v7m.secure) {
34
+ gen_helper_sve_stsd_zsu,
36
return 0;
35
+ gen_helper_sve_stdd_zsu, },
37
}
36
+ { gen_helper_sve_stbd_zss,
38
- return env->v7m.control[M_REG_NS];
37
+ gen_helper_sve_sthd_zss,
39
+ return env->v7m.control[M_REG_NS] |
38
+ gen_helper_sve_stsd_zss,
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
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
}
41
}
77
switch (a->esz) {
42
78
case MO_32:
43
if (el == 0) {
79
- fn = fn32[a->xs][a->msz];
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
80
+ fn = scatter_store_fn32[a->xs][a->msz];
45
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
56
+ */
57
return;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
63
}
64
+ /*
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
66
+ * RES0 if the FPU is not present, and is stored in the S bank
67
+ */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
69
+ extract32(env->v7m.nsacr, 10, 1)) {
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
72
+ }
73
return;
74
case 0x98: /* SP_NS */
75
{
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
81
break;
78
break;
82
case MO_64:
79
case 20: /* CONTROL */
83
- fn = fn64[a->xs][a->msz];
80
- /* Writing to the SPSEL bit only has an effect if we are in
84
+ fn = scatter_store_fn64[a->xs][a->msz];
81
+ /*
82
+ * Writing to the SPSEL bit only has an effect if we are in
83
* thread mode; other bits can be updated by any privileged code.
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
85
* env->v7m.control, so we only need update the others.
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
87
* mode; for v8M the write is permitted but will have no effect.
88
+ * All these bits are writes-ignored from non-privileged code,
89
+ * except for SFPA.
90
*/
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
92
- !arm_v7m_is_handler_mode(env)) {
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
94
+ !arm_v7m_is_handler_mode(env))) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
96
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
101
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
103
+ /*
104
+ * SFPA is RAZ/WI from NS or if no FPU.
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
106
+ * Both are stored in the S bank.
107
+ */
108
+ if (env->v7m.secure) {
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
111
+ }
112
+ if (cur_el > 0 &&
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
114
+ extract32(env->v7m.nsacr, 10, 1))) {
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
117
+ }
118
+ }
85
break;
119
break;
86
default:
120
default:
87
g_assert_not_reached();
121
bad_reg:
88
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
89
return true;
90
}
91
92
+static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a, uint32_t insn)
93
+{
94
+ gen_helper_gvec_mem_scatter *fn = NULL;
95
+ TCGv_i64 imm;
96
+
97
+ if (a->esz < a->msz) {
98
+ return false;
99
+ }
100
+ if (!sve_access_check(s)) {
101
+ return true;
102
+ }
103
+
104
+ switch (a->esz) {
105
+ case MO_32:
106
+ fn = scatter_store_fn32[0][a->msz];
107
+ break;
108
+ case MO_64:
109
+ fn = scatter_store_fn64[2][a->msz];
110
+ break;
111
+ }
112
+ assert(fn != NULL);
113
+
114
+ /* Treat ST1_zpiz (zn[x] + imm) the same way as ST1_zprz (rn + zm[x])
115
+ * by loading the immediate into the scalar parameter.
116
+ */
117
+ imm = tcg_const_i64(a->imm << a->msz);
118
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
119
+ tcg_temp_free_i64(imm);
120
+ return true;
121
+}
122
+
123
/*
124
* Prefetches
125
*/
126
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/sve.decode
129
+++ b/target/arm/sve.decode
130
@@ -XXX,XX +XXX,XX @@
131
&rprr_gather_load rd pg rn rm esz msz u ff xs scale
132
&rpri_gather_load rd pg rn imm esz msz u ff
133
&rprr_scatter_store rd pg rn rm esz msz xs scale
134
+&rpri_scatter_store rd pg rn imm esz msz
135
136
###########################################################################
137
# Named instruction formats. These are generally used to
138
@@ -XXX,XX +XXX,XX @@
139
&rprr_store nreg=0
140
@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
141
&rprr_scatter_store
142
+@rpri_scatter_store ....... msz:2 .. imm:5 ... pg:3 rn:5 rd:5 \
143
+ &rpri_scatter_store
144
145
###########################################################################
146
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
147
@@ -XXX,XX +XXX,XX @@ ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
148
ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
149
@rprr_scatter_store xs=2 esz=3 scale=0
150
151
+# SVE 64-bit scatter store (vector plus immediate)
152
+ST1_zpiz 1110010 .. 10 ..... 101 ... ..... ..... \
153
+ @rpri_scatter_store esz=3
154
+
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
--
122
--
163
2.17.1
123
2.20.1
164
124
165
125
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Currently the code in v7m_push_stack() which detects a violation
2
of the v8M stack limit simply returns early if it does so. This
3
is OK for the current integer-only code, but won't work for the
4
floating point handling we're about to add. We need to continue
5
executing the rest of the function so that we check for other
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
2
9
3
Since kernel commit a86bd139f2 (arm64: arch_timer: Enable CNTVCT_EL0
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
trap..), released in kernel version v4.12, user-space has been able
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
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180625160009.17437-2-alex.bennee@linaro.org
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/helper.c | 27 ++++++++++++++++++++++++---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
15
1 file changed, 24 insertions(+), 3 deletions(-)
15
1 file changed, 18 insertions(+), 5 deletions(-)
16
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
};
22
* should ignore further stack faults trying to process
23
23
* that derived exception.)
24
#else
24
*/
25
-/* In user-mode none of the generic timer registers are accessible,
25
- bool stacked_ok;
26
- * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
26
+ bool stacked_ok = true, limitviol = false;
27
- * so instead just don't register any of them.
27
CPUARMState *env = &cpu->env;
28
+
28
uint32_t xpsr = xpsr_read(env);
29
+/* In user-mode most of the generic timer registers are inaccessible
29
uint32_t frameptr = env->regs[13];
30
+ * however modern kernels (4.12+) allow access to cntvct_el0
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
*/
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
+
32
env->v7m.secure);
33
+static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
33
env->regs[13] = limit;
34
+{
34
- return true;
35
+ /* Currently we have no support for QEMUTimer in linux-user so we
35
+ /*
36
+ * can't call gt_get_countervalue(env), instead we directly
36
+ * We won't try to perform any further memory accesses but
37
+ * call the lower level functions.
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
47
* (which may be taken in preference to the one we started with
48
* if it has higher priority).
49
*/
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
38
+ */
65
+ */
39
+ return cpu_get_clock() / GTIMER_SCALE;
66
+ if (!limitviol) {
40
+}
67
+ env->regs[13] = frameptr;
41
+
68
+ }
42
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
69
43
+ { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
70
return !stacked_ok;
44
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
71
}
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
57
--
72
--
58
2.17.1
73
2.20.1
59
74
60
75
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
2
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
5
Message-id: 20180627043328.11531-11-richard.henderson@linaro.org
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: 20190416125744.27770-11-peter.maydell@linaro.org
7
---
10
---
8
target/arm/translate-sve.c | 103 +++++++++++++++++++++++++++++++++++++
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
9
target/arm/sve.decode | 6 +++
12
1 file changed, 95 insertions(+), 3 deletions(-)
10
2 files changed, 109 insertions(+)
11
13
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
16
--- a/target/arm/helper.c
15
+++ b/target/arm/translate-sve.c
17
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
17
tcg_temp_free_i64(t0);
19
switch_v7m_security_state(env, targets_secure);
18
}
20
write_v7m_control_spsel(env, 0);
19
21
arm_clear_exclusive(env);
20
+/* Similarly for stores. */
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
21
+static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
23
+ env->v7m.control[M_REG_S] &=
22
+ int rn, int imm)
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
23
+{
25
/* Clear IT bits */
24
+ uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
26
env->condexec_bits = 0;
25
+ uint32_t len_remain = len % 8;
27
env->regs[14] = lr;
26
+ uint32_t nparts = len / 8 + ctpop8(len_remain);
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
27
+ int midx = get_mem_index(s);
29
uint32_t xpsr = xpsr_read(env);
28
+ TCGv_i64 addr, t0;
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
29
+
34
+
30
+ addr = tcg_temp_new_i64();
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
31
+ t0 = tcg_temp_new_i64();
36
+ (env->v7m.secure || nsacr_cp10)) {
32
+
37
+ if (env->v7m.secure &&
33
+ /* Note that unpredicated load/store of vector/predicate registers
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
34
+ * are defined as a stream of bytes, which equates to little-endian
39
+ framesize = 0xa8;
35
+ * operations on larger quantities. There is no nice way to force
40
+ } else {
36
+ * a little-endian store for aarch64_be-linux-user out of line.
41
+ framesize = 0x68;
37
+ *
38
+ * Attempt to keep code expansion to a minimum by limiting the
39
+ * amount of unrolling done.
40
+ */
41
+ if (nparts <= 4) {
42
+ int i;
43
+
44
+ for (i = 0; i < len_align; i += 8) {
45
+ tcg_gen_ld_i64(t0, cpu_env, vofs + i);
46
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + i);
47
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
48
+ }
42
+ }
49
+ } else {
43
+ } else {
50
+ TCGLabel *loop = gen_new_label();
44
+ framesize = 0x20;
51
+ TCGv_ptr t2, i = tcg_const_local_ptr(0);
45
+ }
52
+
46
53
+ gen_set_label(loop);
47
/* Align stack pointer if the guest wants that */
54
+
48
if ((frameptr & 4) &&
55
+ t2 = tcg_temp_new_ptr();
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
+ tcg_gen_add_ptr(t2, cpu_env, i);
50
xpsr |= XPSR_SPREALIGN;
57
+ tcg_gen_ld_i64(t0, t2, vofs);
51
}
58
+
52
59
+ /* Minimize the number of local temps that must be re-read from
53
- frameptr -= 0x20;
60
+ * the stack each iteration. Instead, re-compute values other
54
+ xpsr &= ~XPSR_SFPA;
61
+ * than the loop counter.
55
+ if (env->v7m.secure &&
62
+ */
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
63
+ tcg_gen_addi_ptr(t2, i, imm);
57
+ xpsr |= XPSR_SFPA;
64
+ tcg_gen_extu_ptr_i64(addr, t2);
65
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, rn));
66
+ tcg_temp_free_ptr(t2);
67
+
68
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
69
+
70
+ tcg_gen_addi_ptr(i, i, 8);
71
+
72
+ tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
73
+ tcg_temp_free_ptr(i);
74
+ }
58
+ }
75
+
59
+
76
+ /* Predicate register stores can be any multiple of 2. */
60
+ frameptr -= framesize;
77
+ if (len_remain) {
61
78
+ tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
62
if (arm_feature(env, ARM_FEATURE_V8)) {
79
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + len_align);
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
80
+
72
+
81
+ switch (len_remain) {
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
82
+ case 2:
74
+ qemu_log_mask(CPU_LOG_INT,
83
+ case 4:
75
+ "...SecureFault because LSPACT and FPCA both set\n");
84
+ case 8:
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
85
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LE | ctz32(len_remain));
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
86
+ break;
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
87
+
90
+
88
+ case 6:
91
+ if (stacked_ok && !cpacr_pass) {
89
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUL);
92
+ /*
90
+ tcg_gen_addi_i64(addr, addr, 4);
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
91
+ tcg_gen_shri_i64(t0, t0, 32);
94
+ * here does a full CheckCPEnabled() but we know the NSACR
92
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUW);
95
+ * check can never fail as we have already handled that.
93
+ break;
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
94
+
105
+
95
+ default:
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
96
+ g_assert_not_reached();
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
97
+ }
132
+ }
98
+ }
133
+ }
99
+ tcg_temp_free_i64(addr);
100
+ tcg_temp_free_i64(t0);
101
+}
102
+
134
+
103
static bool trans_LDR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
135
/*
104
{
136
* If we broke a stack limit then SP was already updated earlier;
105
if (sve_access_check(s)) {
137
* otherwise we update SP regardless of whether any of the stack
106
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
107
return true;
139
108
}
140
if (arm_feature(env, ARM_FEATURE_V8)) {
109
141
lr = R_V7M_EXCRET_RES1_MASK |
110
+static bool trans_STR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
142
- R_V7M_EXCRET_DCRS_MASK |
111
+{
143
- R_V7M_EXCRET_FTYPE_MASK;
112
+ if (sve_access_check(s)) {
144
+ R_V7M_EXCRET_DCRS_MASK;
113
+ int size = vec_full_reg_size(s);
145
/* The S bit indicates whether we should return to Secure
114
+ int off = vec_full_reg_offset(s, a->rd);
146
* or NonSecure (ie our current state).
115
+ do_str(s, off, size, a->rn, a->imm * size);
147
* The ES bit indicates whether we're taking this exception
116
+ }
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
117
+ return true;
149
if (env->v7m.secure) {
118
+}
150
lr |= R_V7M_EXCRET_S_MASK;
119
+
151
}
120
+static bool trans_STR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
121
+{
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
122
+ if (sve_access_check(s)) {
154
+ }
123
+ int size = pred_full_reg_size(s);
155
} else {
124
+ int off = pred_full_reg_offset(s, a->rd);
156
lr = R_V7M_EXCRET_RES1_MASK |
125
+ do_str(s, off, size, a->rn, a->imm * size);
157
R_V7M_EXCRET_S_MASK |
126
+ }
127
+ return true;
128
+}
129
+
130
/*
131
*** SVE Memory - Contiguous Load Group
132
*/
133
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
134
index XXXXXXX..XXXXXXX 100644
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
--
158
--
151
2.17.1
159
2.20.1
152
160
153
161
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the code which updates the FPCCR register on an
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
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-28-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
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-
9
target/arm/cpu.h | 14 +++++++++
9
target/arm/sve.decode | 7 +++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
10
2 files changed, 66 insertions(+), 1 deletion(-)
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
12
3 files changed, 114 insertions(+), 1 deletion(-)
11
13
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
16
--- a/target/arm/cpu.h
15
+++ b/target/arm/translate-sve.c
17
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
17
return true;
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
44
return ret;
18
}
45
}
19
46
20
+/* Select active elememnts from Zn and inactive elements from Zm,
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
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
+{
48
+{
25
+ static gen_helper_gvec_4 * const fns[4] = {
49
+ /*
26
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
27
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
51
+ * configured at a priority which would allow it to interrupt the
28
+ };
52
+ * current execution priority.
29
+ unsigned vsz = vec_full_reg_size(s);
53
+ *
30
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
31
+ vec_full_reg_offset(s, rn),
55
+ * for non-banked exceptions secure is always false; for banked exceptions
32
+ vec_full_reg_offset(s, rm),
56
+ * it indicates which of the exceptions is required.
33
+ pred_full_reg_offset(s, pg),
57
+ */
34
+ vsz, vsz, 0, fns[esz]);
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
35
+}
79
+}
36
+
80
+
37
#define DO_ZPZZ(NAME, name) \
81
/* callback when external interrupt line is changed */
38
static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a, \
82
static void set_irq_level(void *opaque, int n, int level)
39
uint32_t insn) \
83
{
40
@@ -XXX,XX +XXX,XX @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
return do_zpzz_ool(s, a, fns[a->esz]);
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
42
}
90
}
43
91
44
-DO_ZPZZ(SEL, sel)
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
45
+static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
93
+ bool apply_splim)
46
+{
94
+{
47
+ if (sve_access_check(s)) {
95
+ /*
48
+ do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
97
+ * that we will need later in order to do lazy FP reg stacking.
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
49
+ }
122
+ }
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
+
123
+
60
+/*
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
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
+
125
+
74
+static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
75
+{
127
+
76
+ return do_mov_z(s, a->rd, a->rn);
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
77
+}
155
+}
78
+
156
+
79
+static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
157
static bool v7m_push_stack(ARMCPU *cpu)
80
+{
158
{
81
+ if (sve_access_check(s)) {
159
/* Do the "set up stack frame" part of exception entry,
82
+ do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
83
+ }
161
}
84
+ return true;
162
} else {
85
+}
163
/* Lazy stacking enabled, save necessary info to stack later */
86
+
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
87
+static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
88
+{
166
}
89
+ if (sve_access_check(s)) {
167
}
90
+ do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
168
}
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
--
169
--
120
2.17.1
170
2.20.1
121
171
122
172
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
For v8M floating point support, transitions from Secure
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
2
5
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper.c | 2 +-
10
target/arm/helper.c | 4 ++++
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 4 insertions(+)
11
12
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
17
.writefn = pmuserenr_write, .raw_writefn = raw_write },
18
/* translate.c should have made BXNS UNDEF unless we're secure */
18
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
19
assert(env->v7m.secure);
19
.access = PL1_RW, .accessfn = access_tpm,
20
20
- .type = ARM_CP_ALIAS,
21
+ if (!(dest & 1)) {
21
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
22
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
23
+ }
23
.resetvalue = 0,
24
switch_v7m_security_state(env, dest & 1);
24
.writefn = pmintenset_write, .raw_writefn = raw_write },
25
env->thumb = 1;
26
env->regs[15] = dest & ~1;
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
28
*/
29
write_v7m_exception(env, 1);
30
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
32
switch_v7m_security_state(env, 0);
33
env->thumb = 1;
34
env->regs[15] = dest;
25
--
35
--
26
2.17.1
36
2.20.1
27
37
28
38
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The TailChain() pseudocode specifies that a tail chaining
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
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-8-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: 20190416125744.27770-14-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper-sve.h | 16 ++++
10
target/arm/helper.c | 8 ++++++++
10
target/arm/sve_helper.c | 158 +++++++++++++++++++++++++++++++++++++
11
1 file changed, 8 insertions(+)
11
target/arm/translate-sve.c | 49 ++++++++++++
12
target/arm/sve.decode | 18 +++++
13
4 files changed, 241 insertions(+)
14
12
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
15
--- a/target/arm/helper.c
18
+++ b/target/arm/helper-sve.h
16
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
20
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
21
void, ptr, ptr, ptr, ptr, i32)
19
targets_secure ? "secure" : "nonsecure", exc);
22
20
23
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
+ if (dotailchain) {
24
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
+ /* Sanitize LR FType and PREFIX bits */
25
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
26
+
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
27
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
+ }
28
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
26
+ lr = deposit32(lr, 24, 8, 0xff);
29
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
33
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
37
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
38
+
39
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve_helper.c
45
+++ b/target/arm/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
47
48
#undef DO_ZPZ_FP
49
50
+/* 4-operand predicated multiply-add. This requires 7 operands to pass
51
+ * "properly", so we need to encode some of the registers into DESC.
52
+ */
53
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 20 > 32);
54
+
55
+static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
56
+ uint16_t neg1, uint16_t neg3)
57
+{
58
+ intptr_t i = simd_oprsz(desc);
59
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
60
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
61
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
62
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
63
+ void *vd = &env->vfp.zregs[rd];
64
+ void *vn = &env->vfp.zregs[rn];
65
+ void *vm = &env->vfp.zregs[rm];
66
+ void *va = &env->vfp.zregs[ra];
67
+ uint64_t *g = vg;
68
+
69
+ do {
70
+ uint64_t pg = g[(i - 1) >> 6];
71
+ do {
72
+ i -= 2;
73
+ if (likely((pg >> (i & 63)) & 1)) {
74
+ float16 e1, e2, e3, r;
75
+
76
+ e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
77
+ e2 = *(uint16_t *)(vm + H1_2(i));
78
+ e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
79
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
80
+ *(uint16_t *)(vd + H1_2(i)) = r;
81
+ }
82
+ } while (i & 63);
83
+ } while (i != 0);
84
+}
85
+
86
+void HELPER(sve_fmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
87
+{
88
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0);
89
+}
90
+
91
+void HELPER(sve_fmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
92
+{
93
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0);
94
+}
95
+
96
+void HELPER(sve_fnmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
97
+{
98
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0x8000);
99
+}
100
+
101
+void HELPER(sve_fnmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
102
+{
103
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0x8000);
104
+}
105
+
106
+static void do_fmla_zpzzz_s(CPUARMState *env, void *vg, uint32_t desc,
107
+ uint32_t neg1, uint32_t neg3)
108
+{
109
+ intptr_t i = simd_oprsz(desc);
110
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
111
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
112
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
113
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
114
+ void *vd = &env->vfp.zregs[rd];
115
+ void *vn = &env->vfp.zregs[rn];
116
+ void *vm = &env->vfp.zregs[rm];
117
+ void *va = &env->vfp.zregs[ra];
118
+ uint64_t *g = vg;
119
+
120
+ do {
121
+ uint64_t pg = g[(i - 1) >> 6];
122
+ do {
123
+ i -= 4;
124
+ if (likely((pg >> (i & 63)) & 1)) {
125
+ float32 e1, e2, e3, r;
126
+
127
+ e1 = *(uint32_t *)(vn + H1_4(i)) ^ neg1;
128
+ e2 = *(uint32_t *)(vm + H1_4(i));
129
+ e3 = *(uint32_t *)(va + H1_4(i)) ^ neg3;
130
+ r = float32_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
131
+ *(uint32_t *)(vd + H1_4(i)) = r;
132
+ }
133
+ } while (i & 63);
134
+ } while (i != 0);
135
+}
136
+
137
+void HELPER(sve_fmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
138
+{
139
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0);
140
+}
141
+
142
+void HELPER(sve_fmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
143
+{
144
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0);
145
+}
146
+
147
+void HELPER(sve_fnmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
148
+{
149
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0x80000000);
150
+}
151
+
152
+void HELPER(sve_fnmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
153
+{
154
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0x80000000);
155
+}
156
+
157
+static void do_fmla_zpzzz_d(CPUARMState *env, void *vg, uint32_t desc,
158
+ uint64_t neg1, uint64_t neg3)
159
+{
160
+ intptr_t i = simd_oprsz(desc);
161
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
162
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
163
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
164
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
165
+ void *vd = &env->vfp.zregs[rd];
166
+ void *vn = &env->vfp.zregs[rn];
167
+ void *vm = &env->vfp.zregs[rm];
168
+ void *va = &env->vfp.zregs[ra];
169
+ uint64_t *g = vg;
170
+
171
+ do {
172
+ uint64_t pg = g[(i - 1) >> 6];
173
+ do {
174
+ i -= 8;
175
+ if (likely((pg >> (i & 63)) & 1)) {
176
+ float64 e1, e2, e3, r;
177
+
178
+ e1 = *(uint64_t *)(vn + i) ^ neg1;
179
+ e2 = *(uint64_t *)(vm + i);
180
+ e3 = *(uint64_t *)(va + i) ^ neg3;
181
+ r = float64_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
182
+ *(uint64_t *)(vd + i) = r;
183
+ }
184
+ } while (i & 63);
185
+ } while (i != 0);
186
+}
187
+
188
+void HELPER(sve_fmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
189
+{
190
+ do_fmla_zpzzz_d(env, vg, desc, 0, 0);
191
+}
192
+
193
+void HELPER(sve_fmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
194
+{
195
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, 0);
196
+}
197
+
198
+void HELPER(sve_fnmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
199
+{
200
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, INT64_MIN);
201
+}
202
+
203
+void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
204
+{
205
+ do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
206
+}
207
+
208
/*
209
* Load contiguous data, protected by a governing predicate.
210
*/
211
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate-sve.c
214
+++ b/target/arm/translate-sve.c
215
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
216
217
#undef DO_FP3
218
219
+typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
220
+
221
+static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
222
+{
223
+ if (fn == NULL) {
224
+ return false;
225
+ }
226
+ if (!sve_access_check(s)) {
227
+ return true;
228
+ }
27
+ }
229
+
28
+
230
+ unsigned vsz = vec_full_reg_size(s);
29
if (arm_feature(env, ARM_FEATURE_V8)) {
231
+ unsigned desc;
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
232
+ TCGv_i32 t_desc;
31
(lr & R_V7M_EXCRET_S_MASK)) {
233
+ TCGv_ptr pg = tcg_temp_new_ptr();
234
+
235
+ /* We would need 7 operands to pass these arguments "properly".
236
+ * So we encode all the register numbers into the descriptor.
237
+ */
238
+ desc = deposit32(a->rd, 5, 5, a->rn);
239
+ desc = deposit32(desc, 10, 5, a->rm);
240
+ desc = deposit32(desc, 15, 5, a->ra);
241
+ desc = simd_desc(vsz, vsz, desc);
242
+
243
+ t_desc = tcg_const_i32(desc);
244
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
245
+ fn(cpu_env, pg, t_desc);
246
+ tcg_temp_free_i32(t_desc);
247
+ tcg_temp_free_ptr(pg);
248
+ return true;
249
+}
250
+
251
+#define DO_FMLA(NAME, name) \
252
+static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a, uint32_t insn) \
253
+{ \
254
+ static gen_helper_sve_fmla * const fns[4] = { \
255
+ NULL, gen_helper_sve_##name##_h, \
256
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
257
+ }; \
258
+ return do_fmla(s, a, fns[a->esz]); \
259
+}
260
+
261
+DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
262
+DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
263
+DO_FMLA(FNMLA_zpzzz, fnmla_zpzzz)
264
+DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
265
+
266
+#undef DO_FMLA
267
+
268
/*
269
*** SVE Floating Point Unary Operations Predicated Group
270
*/
271
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
272
index XXXXXXX..XXXXXXX 100644
273
--- a/target/arm/sve.decode
274
+++ b/target/arm/sve.decode
275
@@ -XXX,XX +XXX,XX @@
276
&rprrr_esz ra=%reg_movprfx
277
@rdn_pg_ra_rm ........ esz:2 . rm:5 ... pg:3 ra:5 rd:5 \
278
&rprrr_esz rn=%reg_movprfx
279
+@rdn_pg_rm_ra ........ esz:2 . ra:5 ... pg:3 rm:5 rd:5 \
280
+ &rprrr_esz rn=%reg_movprfx
281
282
# One register operand, with governing predicate, vector element size
283
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
284
@@ -XXX,XX +XXX,XX @@ FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
285
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
286
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
287
288
+### SVE FP Multiply-Add Group
289
+
290
+# SVE floating-point multiply-accumulate writing addend
291
+FMLA_zpzzz 01100101 .. 1 ..... 000 ... ..... ..... @rda_pg_rn_rm
292
+FMLS_zpzzz 01100101 .. 1 ..... 001 ... ..... ..... @rda_pg_rn_rm
293
+FNMLA_zpzzz 01100101 .. 1 ..... 010 ... ..... ..... @rda_pg_rn_rm
294
+FNMLS_zpzzz 01100101 .. 1 ..... 011 ... ..... ..... @rda_pg_rn_rm
295
+
296
+# SVE floating-point multiply-accumulate writing multiplicand
297
+# Alter the operand extraction order and reuse the helpers from above.
298
+# FMAD, FMSB, FNMAD, FNMS
299
+FMLA_zpzzz 01100101 .. 1 ..... 100 ... ..... ..... @rdn_pg_rm_ra
300
+FMLS_zpzzz 01100101 .. 1 ..... 101 ... ..... ..... @rdn_pg_rm_ra
301
+FNMLA_zpzzz 01100101 .. 1 ..... 110 ... ..... ..... @rdn_pg_rm_ra
302
+FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
303
+
304
### SVE FP Unary Operations Predicated Group
305
306
# SVE integer convert to floating-point
307
--
32
--
308
2.17.1
33
2.20.1
309
34
310
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The magic value pushed onto the callee stack as an integrity
2
check is different if floating point is present.
2
3
3
Enhance the existing helpers to support SVE, which takes the
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
index from each 128-bit segment. The change has no effect
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
for AdvSIMD, since there is only one such segment.
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
1 file changed, 19 insertions(+), 3 deletions(-)
6
10
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180627043328.11531-32-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 23 ++++++++++++++++++
14
target/arm/vec_helper.c | 50 +++++++++++++++++++++++---------------
15
target/arm/sve.decode | 6 +++++
16
3 files changed, 59 insertions(+), 20 deletions(-)
17
18
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-sve.c
13
--- a/target/arm/helper.c
21
+++ b/target/arm/translate-sve.c
14
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zpzzz(DisasContext *s,
15
@@ -XXX,XX +XXX,XX @@ load_fail:
23
return true;
16
return false;
24
}
17
}
25
18
26
+static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a, uint32_t insn)
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
27
+{
20
+{
28
+ static gen_helper_gvec_3_ptr * const fns[2] = {
21
+ /*
29
+ gen_helper_gvec_fcmlah_idx,
22
+ * Return the integrity signature value for the callee-saves
30
+ gen_helper_gvec_fcmlas_idx,
23
+ * stack frame section. @lr is the exception return payload/LR value
31
+ };
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
32
+
27
+
33
+ tcg_debug_assert(a->esz == 1 || a->esz == 2);
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
34
+ tcg_debug_assert(a->rd == a->ra);
29
+ sig |= 1;
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
+ }
30
+ }
46
+ return true;
31
+ return sig;
47
+}
32
+}
48
+
33
+
49
/*
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
50
*** SVE Floating Point Unary Operations Predicated Group
35
bool ignore_faults)
51
*/
36
{
52
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
53
index XXXXXXX..XXXXXXX 100644
38
bool stacked_ok;
54
--- a/target/arm/vec_helper.c
39
uint32_t limit;
55
+++ b/target/arm/vec_helper.c
40
bool want_psp;
56
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
41
+ uint32_t sig;
57
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
42
58
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
43
if (dotailchain) {
59
uint32_t neg_real = flip ^ neg_imag;
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
60
- uintptr_t i;
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
61
- float16 e1 = m[H2(2 * index + flip)];
46
/* Write as much of the stack frame as we can. A write failure may
62
- float16 e3 = m[H2(2 * index + 1 - flip)];
47
* cause us to pend a derived exception.
63
+ intptr_t elements = opr_sz / sizeof(float16);
48
*/
64
+ intptr_t eltspersegment = 16 / sizeof(float16);
49
+ sig = v7m_integrity_sig(env, lr);
65
+ intptr_t i, j;
50
stacked_ok =
66
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
67
/* Shift boolean to the sign bit so we can xor to negate. */
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
68
neg_real <<= 15;
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
69
neg_imag <<= 15;
54
ignore_faults) &&
70
- e1 ^= neg_real;
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
71
- e3 ^= neg_imag;
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
72
57
if (return_to_secure &&
73
- for (i = 0; i < opr_sz / 2; i += 2) {
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
74
- float16 e2 = n[H2(i + flip)];
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
75
- float16 e4 = e2;
60
- uint32_t expected_sig = 0xfefa125b;
76
+ for (i = 0; i < elements; i += eltspersegment) {
61
uint32_t actual_sig;
77
+ float16 mr = m[H2(i + 2 * index + 0)];
62
78
+ float16 mi = m[H2(i + 2 * index + 1)];
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
79
+ float16 e1 = neg_real ^ (flip ? mi : mr);
64
80
+ float16 e3 = neg_imag ^ (flip ? mr : mi);
65
- if (pop_ok && expected_sig != actual_sig) {
81
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
82
- d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst);
67
/* Take a SecureFault on the current stack */
83
- d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst);
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
84
+ for (j = i; j < i + eltspersegment; j += 2) {
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
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
--
70
--
150
2.17.1
71
2.20.1
151
72
152
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Handle floating point registers in exception return.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
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: 20190416125744.27770-16-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-sve.h | 7 +++++
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/sve_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
10
1 file changed, 141 insertions(+), 1 deletion(-)
10
target/arm/translate-sve.c | 45 ++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 5 ++++
12
4 files changed, 113 insertions(+)
13
11
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
14
--- a/target/arm/helper.c
17
+++ b/target/arm/helper-sve.h
15
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
17
bool rettobase = false;
20
void, ptr, ptr, ptr, ptr, i32)
18
bool exc_secure = false;
21
19
bool return_to_secure;
22
+DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
20
+ bool ftype;
23
+ i64, i64, ptr, ptr, ptr, i32)
21
+ bool restore_s16_s31;
24
+DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
22
25
+ i64, i64, ptr, ptr, ptr, i32)
23
/* If we're not in Handler mode then jumps to magic exception-exit
26
+DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
24
* addresses don't have magic behaviour. However for the v8M
27
+ i64, i64, ptr, ptr, ptr, i32)
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
28
+
30
+
29
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
30
void, ptr, ptr, ptr, ptr, ptr, i32)
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
31
DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
32
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
34
+ "if FPU not present\n",
33
index XXXXXXX..XXXXXXX 100644
35
+ excret);
34
--- a/target/arm/sve_helper.c
36
+ ftype = true;
35
+++ b/target/arm/sve_helper.c
37
+ }
36
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
37
return predtest_ones(d, oprsz, esz_mask);
38
}
39
40
+uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
41
+ void *status, uint32_t desc)
42
+{
43
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
44
+ float16 result = nn;
45
+
38
+
46
+ do {
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
47
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
48
+ do {
41
* we pick which FAULTMASK to clear.
49
+ if (pg & 1) {
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
50
+ float16 mm = *(float16 *)(vm + H1_2(i));
43
*/
51
+ result = float16_add(result, mm, status);
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
52
+ }
65
+ }
53
+ i += sizeof(float16), pg >>= sizeof(float16);
66
+ vfp_set_fpscr(env, 0);
54
+ } while (i & 15);
55
+ } while (i < opr_sz);
56
+
57
+ return result;
58
+}
59
+
60
+uint64_t HELPER(sve_fadda_s)(uint64_t nn, void *vm, void *vg,
61
+ void *status, uint32_t desc)
62
+{
63
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
64
+ float32 result = nn;
65
+
66
+ do {
67
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
68
+ do {
69
+ if (pg & 1) {
70
+ float32 mm = *(float32 *)(vm + H1_2(i));
71
+ result = float32_add(result, mm, status);
72
+ }
73
+ i += sizeof(float32), pg >>= sizeof(float32);
74
+ } while (i & 15);
75
+ } while (i < opr_sz);
76
+
77
+ return result;
78
+}
79
+
80
+uint64_t HELPER(sve_fadda_d)(uint64_t nn, void *vm, void *vg,
81
+ void *status, uint32_t desc)
82
+{
83
+ intptr_t i = 0, opr_sz = simd_oprsz(desc) / 8;
84
+ uint64_t *m = vm;
85
+ uint8_t *pg = vg;
86
+
87
+ for (i = 0; i < opr_sz; i++) {
88
+ if (pg[H1(i)] & 1) {
89
+ nn = float64_add(nn, m[i], status);
90
+ }
67
+ }
91
+ }
68
+ }
92
+
69
+
93
+ return nn;
70
if (sfault) {
94
+}
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
95
+
90
+
96
/* Fully general three-operand expander, controlled by a predicate,
91
+ restore_s16_s31 = return_to_secure &&
97
* With the extra float_status parameter.
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
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
+
93
+
111
+static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
112
+{
95
+ /* State in FPU is still valid, just clear LSPACT */
113
+ typedef void fadda_fn(TCGv_i64, TCGv_i64, TCGv_ptr,
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
114
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
97
+ } else {
115
+ static fadda_fn * const fns[3] = {
98
+ int i;
116
+ gen_helper_sve_fadda_h,
99
+ uint32_t fpscr;
117
+ gen_helper_sve_fadda_s,
100
+ bool cpacr_pass, nsacr_pass;
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
+
101
+
125
+ if (a->esz == 0) {
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
126
+ return false;
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
127
+ }
191
+ }
128
+ if (!sve_access_check(s)) {
192
129
+ return true;
193
/* The restored xPSR exception field will be zero if we're
130
+ }
194
* resuming in Thread mode. If that doesn't match what the
131
+
132
+ t_val = load_esz(cpu_env, vec_reg_offset(s, a->rn, 0, a->esz), a->esz);
133
+ t_rm = tcg_temp_new_ptr();
134
+ t_pg = tcg_temp_new_ptr();
135
+ tcg_gen_addi_ptr(t_rm, cpu_env, vec_full_reg_offset(s, a->rm));
136
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
137
+ t_fpst = get_fpstatus_ptr(a->esz == MO_16);
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;
150
+}
151
+
152
/*
153
*** SVE Floating Point Arithmetic - Unpredicated Group
154
*/
155
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/sve.decode
158
+++ b/target/arm/sve.decode
159
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
160
# SVE integer multiply immediate (unpredicated)
161
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
162
163
+### SVE FP Accumulating Reduction Group
164
+
165
+# SVE floating-point serial reduction (predicated)
166
+FADDA 01100101 .. 011 000 001 ... ..... ..... @rdn_pg_rm
167
+
168
### SVE Floating Point Arithmetic - Unpredicated Group
169
170
# SVE floating-point arithmetic (unpredicated)
171
--
195
--
172
2.17.1
196
2.20.1
173
197
174
198
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
2
been used since commit c1e3781090b9d36c60 in 2015, when we
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
2
5
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
6
This rearrangement is not strictly necessary, but means that
4
Message-id: 1529699547-17044-5-git-send-email-alindsay@codeaurora.org
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
6
---
13
---
7
target/arm/cpu.h | 1 +
14
target/arm/cpu.h | 11 ++++++-----
8
target/arm/cpu.c | 21 ++++++++++++++-------
15
1 file changed, 6 insertions(+), 5 deletions(-)
9
target/arm/kvm32.c | 8 ++++----
10
3 files changed, 19 insertions(+), 11 deletions(-)
11
16
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ enum arm_features {
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
17
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
18
ARM_FEATURE_THUMB2EE,
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
19
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
20
+ ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
25
+/*
21
ARM_FEATURE_V4T,
26
+ * Indicates whether cp register reads and writes by guest code should access
22
ARM_FEATURE_V5,
27
+ * the secure or nonsecure bank of banked registers; note that this is not
23
ARM_FEATURE_STRONGARM,
28
+ * the same thing as the current security state of the processor!
24
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
+ */
25
index XXXXXXX..XXXXXXX 100644
30
+FIELD(TBFLAG_A32, NS, 6, 1)
26
--- a/target/arm/cpu.c
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
27
+++ b/target/arm/cpu.c
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
28
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
/* Some features automatically imply others: */
35
* checks on the other bits at runtime
31
if (arm_feature(env, ARM_FEATURE_V8)) {
36
*/
32
- set_feature(env, ARM_FEATURE_V7);
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
33
+ set_feature(env, ARM_FEATURE_V7VE);
38
-/* Indicates whether cp register reads and writes by guest code should access
34
+ }
39
- * the secure or nonsecure bank of banked registers; note that this is not
35
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
40
- * the same thing as the current security state of the processor!
36
+ /* v7 Virtualization Extensions. In real hardware this implies
41
- */
37
+ * EL2 and also the presence of the Security Extensions.
42
-FIELD(TBFLAG_A32, NS, 19, 1)
38
+ * For QEMU, for backwards-compatibility we implement some
43
/* For M profile only, Handler (ie not Thread) mode */
39
+ * CPUs or CPU configs which have no actual EL2 or EL3 but do
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
40
+ * include the various other features that V7VE implies.
45
/* For M profile only, whether we should generate stack-limit checks */
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
--
46
--
106
2.17.1
47
2.20.1
107
48
108
49
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We are close to running out of TB flags for AArch32; we could
2
start using the cs_base word, but before we do that we can
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
2
6
3
We've already added the helpers with an SVE patch, all that remains
4
is to wire up the aa64 and aa32 translators. Enable the feature
5
within -cpu max for CONFIG_USER_ONLY.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 1 +
11
target/arm/cpu.h | 10 ++++++----
13
linux-user/elfload.c | 1 +
12
target/arm/cpu.c | 7 +++++++
14
target/arm/cpu.c | 1 +
13
target/arm/helper.c | 6 +++++-
15
target/arm/cpu64.c | 1 +
14
target/arm/translate.c | 9 +++++++--
16
target/arm/translate-a64.c | 36 +++++++++++++++++++
15
4 files changed, 25 insertions(+), 7 deletions(-)
17
target/arm/translate.c | 74 +++++++++++++++++++++++++++-----------
18
6 files changed, 93 insertions(+), 21 deletions(-)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
25
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
26
ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
27
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
28
+ ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
25
+/*
29
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
30
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
27
+ * checks on the other bits at runtime. This shares the same bits as
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
29
+ */
33
index XXXXXXX..XXXXXXX 100644
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
34
--- a/linux-user/elfload.c
31
/*
35
+++ b/linux-user/elfload.c
32
* Indicates whether cp register reads and writes by guest code should access
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
33
* the secure or nonsecure bank of banked registers; note that this is not
37
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
38
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
39
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
40
+ GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
41
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
42
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
39
- * checks on the other bits at runtime
43
#undef GET_FEATURE
40
- */
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
47
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
49
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
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
}
51
}
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
52
53
+ /*
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
56
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
59
+
60
if (arm_feature(env, ARM_FEATURE_V7) &&
61
!arm_feature(env, ARM_FEATURE_M) &&
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu64.c
65
--- a/target/arm/helper.c
59
+++ b/target/arm/cpu64.c
66
+++ b/target/arm/helper.c
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
61
set_feature(&cpu->env, ARM_FEATURE_CRC);
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
62
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
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
}
75
76
+/* Expand a 3-operand operation using an out-of-line helper. */
77
+static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
78
+ int rn, int rm, int data, gen_helper_gvec_3 *fn)
79
+{
80
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
81
+ vec_full_reg_offset(s, rn),
82
+ vec_full_reg_offset(s, rm),
83
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
84
+}
85
+
86
/* Expand a 3-operand + env pointer operation using
87
* an out-of-line helper.
88
*/
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
90
}
70
}
91
feature = ARM_FEATURE_V8_RDM;
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
92
break;
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
93
+ case 0x02: /* SDOT (vector) */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
94
+ case 0x12: /* UDOT (vector) */
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
95
+ if (size != MO_32) {
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
96
+ unallocated_encoding(s);
97
+ return;
98
+ }
76
+ }
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
}
77
}
132
78
133
switch (16 * u + opcode) {
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
134
+ case 0x0e: /* SDOT */
135
+ case 0x1e: /* UDOT */
136
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, index,
137
+ u ? gen_helper_gvec_udot_idx_b
138
+ : gen_helper_gvec_sdot_idx_b);
139
+ return;
140
case 0x11: /* FCMLA #0 */
141
case 0x13: /* FCMLA #90 */
142
case 0x15: /* FCMLA #180 */
143
diff --git a/target/arm/translate.c b/target/arm/translate.c
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
144
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate.c
82
--- a/target/arm/translate.c
146
+++ b/target/arm/translate.c
83
+++ b/target/arm/translate.c
147
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
148
*/
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
149
static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
150
{
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
151
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
152
- int rd, rn, rm, rot, size, opr_sz;
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
153
- TCGv_ptr fpst;
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
154
+ gen_helper_gvec_3 *fn_gvec = NULL;
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
155
+ gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
92
+ dc->vec_stride = 0;
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 {
93
+ } else {
213
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
214
+ vfp_reg_offset(1, rn),
95
+ dc->c15_cpar = 0;
215
+ vfp_reg_offset(1, rm),
216
+ opr_sz, opr_sz, data, fn_gvec);
217
+ }
96
+ }
218
return 0;
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
219
}
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
220
99
regime_is_secure(env, dc->mmu_idx);
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
--
100
--
277
2.17.1
101
2.20.1
278
102
279
103
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile FPCCR.S bit indicates the security status of
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
function it is unconditionally set to match the current
4
security state whenever a floating point instruction is
5
executed.
2
6
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Implement this by adding a new TB flag which tracks whether
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
FPCCR.S is different from the current security state, so
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
that we only need to emit the code to update it in the
6
Message-id: 20180627043328.11531-14-richard.henderson@linaro.org
10
less-common case when it is not already set correctly.
11
12
Note that we will add the handling for the other work done
13
by ExecuteFPCheck() in later commits.
14
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
8
---
18
---
9
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++
19
target/arm/cpu.h | 2 ++
10
target/arm/sve_helper.c | 77 ++++++++++++++++++++++++++++
20
target/arm/translate.h | 1 +
11
target/arm/translate-sve.c | 100 +++++++++++++++++++++++++++++++++++++
21
target/arm/helper.c | 5 +++++
12
target/arm/sve.decode | 57 +++++++++++++++++++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
13
4 files changed, 301 insertions(+)
23
4 files changed, 28 insertions(+)
14
24
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
27
--- a/target/arm/cpu.h
18
+++ b/target/arm/helper-sve.h
28
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
20
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
22
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
23
+DEF_HELPER_FLAGS_6(sve_ldbsu_zsu, TCG_CALL_NO_WG,
33
+/* For M profile only, set if FPCCR.S does not match current security state */
24
+ void, env, ptr, ptr, ptr, tl, i32)
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
25
+DEF_HELPER_FLAGS_6(sve_ldhsu_zsu, TCG_CALL_NO_WG,
35
/* For M profile only, Handler (ie not Thread) mode */
26
+ void, env, ptr, ptr, ptr, tl, i32)
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
27
+DEF_HELPER_FLAGS_6(sve_ldssu_zsu, TCG_CALL_NO_WG,
37
/* For M profile only, whether we should generate stack-limit checks */
28
+ void, env, ptr, ptr, ptr, tl, i32)
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
+DEF_HELPER_FLAGS_6(sve_ldbss_zsu, TCG_CALL_NO_WG,
30
+ void, env, ptr, ptr, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_6(sve_ldhss_zsu, TCG_CALL_NO_WG,
32
+ void, env, ptr, ptr, ptr, tl, i32)
33
+
34
+DEF_HELPER_FLAGS_6(sve_ldbsu_zss, TCG_CALL_NO_WG,
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_6(sve_ldhsu_zss, TCG_CALL_NO_WG,
37
+ void, env, ptr, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_6(sve_ldssu_zss, TCG_CALL_NO_WG,
39
+ void, env, ptr, ptr, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_6(sve_ldbss_zss, TCG_CALL_NO_WG,
41
+ void, env, ptr, ptr, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_6(sve_ldhss_zss, TCG_CALL_NO_WG,
43
+ void, env, ptr, ptr, ptr, tl, i32)
44
+
45
+DEF_HELPER_FLAGS_6(sve_ldbdu_zsu, TCG_CALL_NO_WG,
46
+ void, env, ptr, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_6(sve_ldhdu_zsu, TCG_CALL_NO_WG,
48
+ void, env, ptr, ptr, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_6(sve_ldsdu_zsu, TCG_CALL_NO_WG,
50
+ void, env, ptr, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_6(sve_ldddu_zsu, TCG_CALL_NO_WG,
52
+ void, env, ptr, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_6(sve_ldbds_zsu, TCG_CALL_NO_WG,
54
+ void, env, ptr, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_6(sve_ldhds_zsu, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_6(sve_ldsds_zsu, TCG_CALL_NO_WG,
58
+ void, env, ptr, ptr, ptr, tl, i32)
59
+
60
+DEF_HELPER_FLAGS_6(sve_ldbdu_zss, TCG_CALL_NO_WG,
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_6(sve_ldhdu_zss, TCG_CALL_NO_WG,
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_6(sve_ldsdu_zss, TCG_CALL_NO_WG,
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_6(sve_ldddu_zss, TCG_CALL_NO_WG,
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+DEF_HELPER_FLAGS_6(sve_ldbds_zss, TCG_CALL_NO_WG,
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_6(sve_ldhds_zss, TCG_CALL_NO_WG,
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+DEF_HELPER_FLAGS_6(sve_ldsds_zss, TCG_CALL_NO_WG,
73
+ void, env, ptr, ptr, ptr, tl, i32)
74
+
75
+DEF_HELPER_FLAGS_6(sve_ldbdu_zd, TCG_CALL_NO_WG,
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_6(sve_ldhdu_zd, TCG_CALL_NO_WG,
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_6(sve_ldsdu_zd, TCG_CALL_NO_WG,
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+DEF_HELPER_FLAGS_6(sve_ldddu_zd, TCG_CALL_NO_WG,
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_6(sve_ldbds_zd, TCG_CALL_NO_WG,
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
88
+ void, env, ptr, ptr, ptr, tl, i32)
89
+
90
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
91
void, env, ptr, ptr, ptr, tl, i32)
92
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
40
--- a/target/arm/translate.h
96
+++ b/target/arm/sve_helper.c
41
+++ b/target/arm/translate.h
97
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
43
bool v7m_handler_mode;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
48
* so that top level loop can generate correct syndrome information.
49
*/
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
98
}
56
}
99
}
57
100
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
101
+/* Loads with a vector index. */
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
102
+
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
103
+#define DO_LD1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
105
+ target_ulong base, uint32_t desc) \
106
+{ \
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
108
+ unsigned scale = simd_data(desc); \
109
+ uintptr_t ra = GETPC(); \
110
+ for (i = 0; i < oprsz; i++) { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ TYPEM m = 0; \
114
+ if (pg & 1) { \
115
+ target_ulong off = *(TYPEI *)(vm + H1_4(i)); \
116
+ m = FN(env, base + (off << scale), ra); \
117
+ } \
118
+ *(uint32_t *)(vd + H1_4(i)) = m; \
119
+ i += 4, pg >>= 4; \
120
+ } while (i & 15); \
121
+ } \
122
+}
123
+
124
+#define DO_LD1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
125
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
126
+ target_ulong base, uint32_t desc) \
127
+{ \
128
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
129
+ unsigned scale = simd_data(desc); \
130
+ uintptr_t ra = GETPC(); \
131
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
132
+ for (i = 0; i < oprsz; i++) { \
133
+ TYPEM mm = 0; \
134
+ if (pg[H1(i)] & 1) { \
135
+ target_ulong off = (TYPEI)m[i]; \
136
+ mm = FN(env, base + (off << scale), ra); \
137
+ } \
138
+ d[i] = mm; \
139
+ } \
140
+}
141
+
142
+DO_LD1_ZPZ_S(sve_ldbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
143
+DO_LD1_ZPZ_S(sve_ldhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
144
+DO_LD1_ZPZ_S(sve_ldssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
145
+DO_LD1_ZPZ_S(sve_ldbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
146
+DO_LD1_ZPZ_S(sve_ldhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
147
+
148
+DO_LD1_ZPZ_S(sve_ldbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
149
+DO_LD1_ZPZ_S(sve_ldhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
150
+DO_LD1_ZPZ_S(sve_ldssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
151
+DO_LD1_ZPZ_S(sve_ldbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
152
+DO_LD1_ZPZ_S(sve_ldhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
153
+
154
+DO_LD1_ZPZ_D(sve_ldbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
155
+DO_LD1_ZPZ_D(sve_ldhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
156
+DO_LD1_ZPZ_D(sve_ldsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
157
+DO_LD1_ZPZ_D(sve_ldddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
158
+DO_LD1_ZPZ_D(sve_ldbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
159
+DO_LD1_ZPZ_D(sve_ldhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
160
+DO_LD1_ZPZ_D(sve_ldsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
161
+
162
+DO_LD1_ZPZ_D(sve_ldbdu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
163
+DO_LD1_ZPZ_D(sve_ldhdu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
164
+DO_LD1_ZPZ_D(sve_ldsdu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
165
+DO_LD1_ZPZ_D(sve_ldddu_zss, int32_t, uint64_t, cpu_ldq_data_ra)
166
+DO_LD1_ZPZ_D(sve_ldbds_zss, int32_t, int8_t, cpu_ldub_data_ra)
167
+DO_LD1_ZPZ_D(sve_ldhds_zss, int32_t, int16_t, cpu_lduw_data_ra)
168
+DO_LD1_ZPZ_D(sve_ldsds_zss, int32_t, int32_t, cpu_ldl_data_ra)
169
+
170
+DO_LD1_ZPZ_D(sve_ldbdu_zd, uint64_t, uint8_t, cpu_ldub_data_ra)
171
+DO_LD1_ZPZ_D(sve_ldhdu_zd, uint64_t, uint16_t, cpu_lduw_data_ra)
172
+DO_LD1_ZPZ_D(sve_ldsdu_zd, uint64_t, uint32_t, cpu_ldl_data_ra)
173
+DO_LD1_ZPZ_D(sve_ldddu_zd, uint64_t, uint64_t, cpu_ldq_data_ra)
174
+DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
175
+DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
176
+DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
177
+
178
/* Stores with a vector index. */
179
180
#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
181
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate-sve.c
184
+++ b/target/arm/translate-sve.c
185
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
186
tcg_temp_free_i32(desc);
187
}
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
+ }
61
+ }
242
+
62
+
243
+ switch (a->esz) {
63
*pflags = flags;
244
+ case MO_32:
64
*cs_base = 0;
245
+ fn = gather_load_fn32[a->ff][a->xs][a->u][a->msz];
65
}
246
+ break;
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
247
+ case MO_64:
67
index XXXXXXX..XXXXXXX 100644
248
+ fn = gather_load_fn64[a->ff][a->xs][a->u][a->msz];
68
--- a/target/arm/translate.c
249
+ break;
69
+++ b/target/arm/translate.c
250
+ }
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
251
+ assert(fn != NULL);
71
}
72
}
73
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
75
+ /* Handle M-profile lazy FP state mechanics */
252
+
76
+
253
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
254
+ cpu_reg_sp(s, a->rn), fn);
78
+ if (s->v8m_fpccr_s_wrong) {
255
+ return true;
79
+ TCGv_i32 tmp;
256
+}
257
+
80
+
258
+static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
259
+{
82
+ if (s->v8m_secure) {
260
+ gen_helper_gvec_mem_scatter *fn = NULL;
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
261
+ TCGv_i64 imm;
84
+ } else {
262
+
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
263
+ if (a->esz < a->msz || (a->esz == a->msz && !a->u)) {
86
+ }
264
+ return false;
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
265
+ }
88
+ /* Don't need to do this for any further FP insns in this TB */
266
+ if (!sve_access_check(s)) {
89
+ s->v8m_fpccr_s_wrong = false;
267
+ return true;
90
+ }
268
+ }
91
+ }
269
+
92
+
270
+ switch (a->esz) {
93
if (extract32(insn, 28, 4) == 0xf) {
271
+ case MO_32:
94
/*
272
+ fn = gather_load_fn32[a->ff][0][a->u][a->msz];
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
273
+ break;
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
274
+ case MO_64:
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
275
+ fn = gather_load_fn64[a->ff][2][a->u][a->msz];
98
regime_is_secure(env, dc->mmu_idx);
276
+ break;
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
277
+ }
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
278
+ assert(fn != NULL);
101
dc->cp_regs = cpu->cp_regs;
279
+
102
dc->features = env->features;
280
+ /* Treat LD1_zpiz (zn[x] + imm) the same way as LD1_zprz (rn + zm[x])
281
+ * by loading the immediate into the scalar parameter.
282
+ */
283
+ imm = tcg_const_i64(a->imm << a->msz);
284
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
285
+ tcg_temp_free_i64(imm);
286
+ return true;
287
+}
288
+
289
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
290
{
291
/* Indexed by [xs][msz]. */
292
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
293
index XXXXXXX..XXXXXXX 100644
294
--- a/target/arm/sve.decode
295
+++ b/target/arm/sve.decode
296
@@ -XXX,XX +XXX,XX @@
297
&rpri_load rd pg rn imm dtype nreg
298
&rprr_store rd pg rn rm msz esz nreg
299
&rpri_store rd pg rn imm msz esz nreg
300
+&rprr_gather_load rd pg rn rm esz msz u ff xs scale
301
+&rpri_gather_load rd pg rn imm esz msz u ff
302
&rprr_scatter_store rd pg rn rm esz msz xs scale
303
304
###########################################################################
305
@@ -XXX,XX +XXX,XX @@
306
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
307
&rpri_load dtype=%msz_dtype
308
309
+# Gather Loads.
310
+@rprr_g_load_u ....... .. . . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
311
+ &rprr_gather_load xs=2
312
+@rprr_g_load_xs_u ....... .. xs:1 . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
313
+ &rprr_gather_load
314
+@rprr_g_load_xs_u_sc ....... .. xs:1 scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
315
+ &rprr_gather_load
316
+@rprr_g_load_xs_sc ....... .. xs:1 scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
317
+ &rprr_gather_load
318
+@rprr_g_load_u_sc ....... .. . scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
319
+ &rprr_gather_load xs=2
320
+@rprr_g_load_sc ....... .. . scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
321
+ &rprr_gather_load xs=2
322
+@rpri_g_load ....... msz:2 .. imm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
323
+ &rpri_gather_load
324
+
325
# Stores; user must fill in ESZ, MSZ, NREG as needed.
326
@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
327
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
328
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
329
LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
330
&rpri_load dtype=%dtype_23_13 nreg=0
331
332
+# SVE 32-bit gather load (scalar plus 32-bit unscaled offsets)
333
+# SVE 32-bit gather load (scalar plus 32-bit scaled offsets)
334
+LD1_zprz 1000010 00 .0 ..... 0.. ... ..... ..... \
335
+ @rprr_g_load_xs_u esz=2 msz=0 scale=0
336
+LD1_zprz 1000010 01 .. ..... 0.. ... ..... ..... \
337
+ @rprr_g_load_xs_u_sc esz=2 msz=1
338
+LD1_zprz 1000010 10 .. ..... 01. ... ..... ..... \
339
+ @rprr_g_load_xs_sc esz=2 msz=2 u=1
340
+
341
+# SVE 32-bit gather load (vector plus immediate)
342
+LD1_zpiz 1000010 .. 01 ..... 1.. ... ..... ..... \
343
+ @rpri_g_load esz=2
344
+
345
### SVE Memory Contiguous Load Group
346
347
# SVE contiguous load (scalar plus scalar)
348
@@ -XXX,XX +XXX,XX @@ PRF_rr 1000010 -- 00 rm:5 110 --- ----- 0 ----
349
350
### SVE Memory 64-bit Gather Group
351
352
+# SVE 64-bit gather load (scalar plus 32-bit unpacked unscaled offsets)
353
+# SVE 64-bit gather load (scalar plus 32-bit unpacked scaled offsets)
354
+LD1_zprz 1100010 00 .0 ..... 0.. ... ..... ..... \
355
+ @rprr_g_load_xs_u esz=3 msz=0 scale=0
356
+LD1_zprz 1100010 01 .. ..... 0.. ... ..... ..... \
357
+ @rprr_g_load_xs_u_sc esz=3 msz=1
358
+LD1_zprz 1100010 10 .. ..... 0.. ... ..... ..... \
359
+ @rprr_g_load_xs_u_sc esz=3 msz=2
360
+LD1_zprz 1100010 11 .. ..... 01. ... ..... ..... \
361
+ @rprr_g_load_xs_sc esz=3 msz=3 u=1
362
+
363
+# SVE 64-bit gather load (scalar plus 64-bit unscaled offsets)
364
+# SVE 64-bit gather load (scalar plus 64-bit scaled offsets)
365
+LD1_zprz 1100010 00 10 ..... 1.. ... ..... ..... \
366
+ @rprr_g_load_u esz=3 msz=0 scale=0
367
+LD1_zprz 1100010 01 1. ..... 1.. ... ..... ..... \
368
+ @rprr_g_load_u_sc esz=3 msz=1
369
+LD1_zprz 1100010 10 1. ..... 1.. ... ..... ..... \
370
+ @rprr_g_load_u_sc esz=3 msz=2
371
+LD1_zprz 1100010 11 1. ..... 11. ... ..... ..... \
372
+ @rprr_g_load_sc esz=3 msz=3 u=1
373
+
374
+# SVE 64-bit gather load (vector plus immediate)
375
+LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
376
+ @rpri_g_load esz=3
377
+
378
# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
379
PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
380
103
381
--
104
--
382
2.17.1
105
2.20.1
383
106
384
107
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
2
context preservation is enabled. Before executing any floating-point
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
2
8
3
For aa64 advsimd, we had been passing the pre-indexed vector.
9
Implement this with a new TB flag which tracks whether we
4
However, sve applies the index to each 128-bit segment, so we
10
need to create a new FP context.
5
need to pass in the index separately.
6
11
7
For aa32 advsimd, the fp32 operation always has index 0, but
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
we failed to interpret the fp16 index correctly.
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 2 ++
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
9
21
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20180627043328.11531-31-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/translate-a64.c | 21 ++++++++++++---------
17
target/arm/translate.c | 32 +++++++++++++++++++++++---------
18
target/arm/vec_helper.c | 10 ++++++----
19
3 files changed, 41 insertions(+), 22 deletions(-)
20
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
24
--- a/target/arm/cpu.h
24
+++ b/target/arm/translate-a64.c
25
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
26
case 0x13: /* FCMLA #90 */
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
27
case 0x15: /* FCMLA #180 */
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
28
case 0x17: /* FCMLA #270 */
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
30
+/* For M profile only, set if we must create a new FP context */
30
- vec_full_reg_offset(s, rn),
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
31
- vec_reg_offset(s, rm, index, size), fpst,
32
/* For M profile only, set if FPCCR.S does not match current security state */
32
- is_q ? 16 : 8, vec_full_reg_size(s),
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
33
- extract32(insn, 13, 2), /* rot */
34
/* For M profile only, Handler (ie not Thread) mode */
34
- size == MO_64
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
35
- ? gen_helper_gvec_fcmlas_idx
36
index XXXXXXX..XXXXXXX 100644
36
- : gen_helper_gvec_fcmlah_idx);
37
--- a/target/arm/translate.h
37
- tcg_temp_free_ptr(fpst);
38
+++ b/target/arm/translate.h
38
+ {
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
39
+ int rot = extract32(insn, 13, 2);
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
40
+ int data = (index << 2) | rot;
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
41
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
42
+ vec_full_reg_offset(s, rn),
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
43
+ vec_full_reg_offset(s, rm), fpst,
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
44
+ is_q ? 16 : 8, vec_full_reg_size(s), data,
45
* so that top level loop can generate correct syndrome information.
45
+ size == MO_64
46
*/
46
+ ? gen_helper_gvec_fcmlas_idx
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
+ : gen_helper_gvec_fcmlah_idx);
48
index XXXXXXX..XXXXXXX 100644
48
+ tcg_temp_free_ptr(fpst);
49
--- a/target/arm/helper.c
49
+ }
50
+++ b/target/arm/helper.c
50
return;
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
51
}
53
}
52
54
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
54
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.c
73
--- a/target/arm/translate.c
56
+++ b/target/arm/translate.c
74
+++ b/target/arm/translate.c
57
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
58
76
/* Don't need to do this for any further FP insns in this TB */
59
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
77
s->v8m_fpccr_s_wrong = false;
60
{
78
}
61
- int rd, rn, rm, rot, size, opr_sz;
79
+
62
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
80
+ if (s->v7m_new_fp_ctxt_needed) {
63
+ int rd, rn, rm, opr_sz, data;
81
+ /*
64
TCGv_ptr fpst;
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
65
bool q;
83
+ * and the FPSCR.
66
84
+ */
67
q = extract32(insn, 6, 1);
85
+ TCGv_i32 control, fpscr;
68
VFP_DREG_D(rd, insn);
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
69
VFP_DREG_N(rn, insn);
87
+
70
- VFP_DREG_M(rm, insn);
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
71
if ((rd | rn) & q) {
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
72
return 1;
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
99
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
73
}
106
}
74
107
75
if ((insn & 0xff000f10) == 0xfe000800) {
108
if (extract32(insn, 28, 4) == 0xf) {
76
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
77
- rot = extract32(insn, 20, 2);
110
regime_is_secure(env, dc->mmu_idx);
78
- size = extract32(insn, 23, 1);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
79
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
80
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
113
+ dc->v7m_new_fp_ctxt_needed =
81
+ int rot = extract32(insn, 20, 2);
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
82
+ int size = extract32(insn, 23, 1);
115
dc->cp_regs = cpu->cp_regs;
83
+ int index;
116
dc->features = env->features;
84
+
117
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
+ }
92
+ /* For fp16, rm is just Vm, and index is M. */
93
+ rm = extract32(insn, 0, 4);
94
+ index = extract32(insn, 5, 1);
95
+ } else {
96
+ /* For fp32, rm is the usual M:Vm, and index is 0. */
97
+ VFP_DREG_M(rm, insn);
98
+ index = 0;
99
+ }
100
+ data = (index << 2) | rot;
101
+ fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
102
+ : gen_helper_gvec_fcmlah_idx);
103
} else {
104
return 1;
105
}
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
107
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
108
vfp_reg_offset(1, rn),
109
vfp_reg_offset(1, rm), fpst,
110
- opr_sz, opr_sz, rot,
111
- size ? gen_helper_gvec_fcmlas_idx
112
- : gen_helper_gvec_fcmlah_idx);
113
+ opr_sz, opr_sz, data, fn_gvec_ptr);
114
tcg_temp_free_ptr(fpst);
115
return 0;
116
}
117
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/vec_helper.c
120
+++ b/target/arm/vec_helper.c
121
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
122
float_status *fpst = vfpst;
123
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
124
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
125
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
126
uint32_t neg_real = flip ^ neg_imag;
127
uintptr_t i;
128
- float16 e1 = m[H2(flip)];
129
- float16 e3 = m[H2(1 - flip)];
130
+ float16 e1 = m[H2(2 * index + flip)];
131
+ float16 e3 = m[H2(2 * index + 1 - flip)];
132
133
/* Shift boolean to the sign bit so we can xor to negate. */
134
neg_real <<= 15;
135
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
136
float_status *fpst = vfpst;
137
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
138
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
139
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
140
uint32_t neg_real = flip ^ neg_imag;
141
uintptr_t i;
142
- float32 e1 = m[H4(flip)];
143
- float32 e3 = m[H4(1 - flip)];
144
+ float32 e1 = m[H4(2 * index + flip)];
145
+ float32 e3 = m[H4(2 * index + 1 - flip)];
146
147
/* Shift boolean to the sign bit so we can xor to negate. */
148
neg_real <<= 31;
149
--
118
--
150
2.17.1
119
2.20.1
151
120
152
121
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add a new helper function which returns the MMU index to use
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
2
6
3
This register was added to aa32 state by ARMv8.2.
7
We are going to need this for the lazy-FP-stacking code.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180629001538.11415-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
9
---
12
---
10
target/arm/cpu.h | 1 +
13
target/arm/cpu.h | 7 +++++++
11
target/arm/cpu.c | 4 ++++
14
target/arm/helper.c | 14 +++++++++++---
12
target/arm/cpu64.c | 2 ++
15
2 files changed, 18 insertions(+), 3 deletions(-)
13
target/arm/helper.c | 5 ++---
14
4 files changed, 9 insertions(+), 3 deletions(-)
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
21
uint32_t id_isar3;
22
}
22
uint32_t id_isar4;
23
uint32_t id_isar5;
24
+ uint32_t id_isar6;
25
uint64_t id_aa64pfr0;
26
uint64_t id_aa64pfr1;
27
uint64_t id_aa64dfr0;
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 cortex_m3_initfn(Object *obj)
33
cpu->id_isar3 = 0x01111110;
34
cpu->id_isar4 = 0x01310102;
35
cpu->id_isar5 = 0x00000000;
36
+ cpu->id_isar6 = 0x00000000;
37
}
23
}
38
24
39
static void cortex_m4_initfn(Object *obj)
25
+/*
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
26
+ * Return the MMU index for a v7M CPU with all relevant information
41
cpu->id_isar3 = 0x01111110;
27
+ * manually specified.
42
cpu->id_isar4 = 0x01310102;
28
+ */
43
cpu->id_isar5 = 0x00000000;
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
44
+ cpu->id_isar6 = 0x00000000;
30
+ bool secstate, bool priv, bool negpri);
45
}
31
+
46
32
/* Return the MMU index for a v7M CPU in the specified security and
47
static void cortex_m33_initfn(Object *obj)
33
* privilege state.
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
34
*/
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
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
37
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
38
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
89
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
40
return 0;
90
.access = PL1_R, .type = ARM_CP_CONST,
41
}
91
.resetvalue = cpu->id_mmfr4 },
42
92
- /* 7 is as yet unallocated and must RAZ */
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
93
- { .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,
44
- bool secstate, bool priv)
94
+ { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
95
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
46
+ bool secstate, bool priv, bool negpri)
96
.access = PL1_R, .type = ARM_CP_CONST,
47
{
97
- .resetvalue = 0 },
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
98
+ .resetvalue = cpu->id_isar6 },
49
99
REGINFO_SENTINEL
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
100
};
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
101
define_arm_cp_regs(cpu, v6_idregs);
52
}
53
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
55
+ if (negpri) {
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
57
}
58
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
60
return mmu_idx;
61
}
62
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
64
+ bool secstate, bool priv)
65
+{
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
67
+
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
69
+}
70
+
71
/* Return the MMU index for a v7M CPU in the specified security state */
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
73
{
102
--
74
--
103
2.17.1
75
2.20.1
104
76
105
77
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
In the v7M architecture, if an exception is generated in the process
2
of doing the lazy stacking of FP registers, the handling of
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
2
9
3
This helper allows to retrieve the paths of nodes whose name
10
This corresponds to the pseudocode TakePreserveFPException().
4
match node-name or node-name@unit-address patterns.
5
11
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
10
---
15
---
11
include/sysemu/device_tree.h | 16 +++++++++++
16
target/arm/cpu.h | 12 ++++++
12
device_tree.c | 55 ++++++++++++++++++++++++++++++++++++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 71 insertions(+)
18
2 files changed, 108 insertions(+)
14
19
15
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/include/sysemu/device_tree.h
22
--- a/target/arm/cpu.h
18
+++ b/include/sysemu/device_tree.h
23
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
20
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
25
* a different exception).
21
Error **errp);
26
*/
22
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
23
+/**
28
+/**
24
+ * qemu_fdt_node_unit_path: return the paths of nodes matching a given
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
25
+ * node-name, ie. node-name and node-name@unit-address
30
+ * @opaque: the NVIC
26
+ * @fdt: pointer to the dt blob
31
+ * @irq: the exception number to mark pending
27
+ * @name: node name
32
+ * @secure: false for non-banked exceptions or for the nonsecure
28
+ * @errp: handle to an error object
33
+ * version of a banked exception, true for the secure version of a banked
34
+ * exception.
29
+ *
35
+ *
30
+ * returns a newly allocated NULL-terminated array of node paths.
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
31
+ * Use g_strfreev() to free it. If one or more nodes were found, the
37
+ * generated in the course of lazy stacking of FP registers.
32
+ * array contains the path of each node and the last element equals to
33
+ * NULL. If there is no error but no matching node was found, the
34
+ * returned array contains a single element equal to NULL. If an error
35
+ * was encountered when parsing the blob, the function returns NULL
36
+ */
38
+ */
37
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
50
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
52
+{
53
+ /*
54
+ * Pend an exception during lazy FP stacking. This differs
55
+ * from the usual exception pending because the logic for
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
59
+ NVICState *s = (NVICState *)opaque;
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
38
+
71
+
39
int qemu_fdt_setprop(void *fdt, const char *node_path,
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
40
const char *property, const void *val, int size);
73
+ assert(!secure || banked);
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
44
--- a/device_tree.c
45
+++ b/device_tree.c
46
@@ -XXX,XX +XXX,XX @@ static int findnode_nofail(void *fdt, const char *node_path)
47
return offset;
48
}
49
50
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
51
+{
52
+ char *prefix = g_strdup_printf("%s@", name);
53
+ unsigned int path_len = 16, n = 0;
54
+ GSList *path_list = NULL, *iter;
55
+ const char *iter_name;
56
+ int offset, len, ret;
57
+ char **path_array;
58
+
74
+
59
+ offset = fdt_next_node(fdt, -1, NULL);
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
60
+
76
+
61
+ while (offset >= 0) {
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
62
+ iter_name = fdt_get_name(fdt, offset, &len);
78
+
63
+ if (!iter_name) {
79
+ switch (irq) {
64
+ offset = len;
80
+ case ARMV7M_EXCP_DEBUG:
65
+ break;
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
66
+ }
84
+ }
67
+ if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
85
+ break;
68
+ char *path;
86
+ case ARMV7M_EXCP_MEM:
69
+
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
70
+ path = g_malloc(path_len);
88
+ break;
71
+ while ((ret = fdt_get_path(fdt, offset, path, path_len))
89
+ case ARMV7M_EXCP_USAGE:
72
+ == -FDT_ERR_NOSPACE) {
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
73
+ path_len += 16;
91
+ break;
74
+ path = g_realloc(path, path_len);
92
+ case ARMV7M_EXCP_BUS:
75
+ }
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
76
+ path_list = g_slist_prepend(path_list, path);
94
+ break;
77
+ n++;
95
+ case ARMV7M_EXCP_SECURE:
78
+ }
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
79
+ offset = fdt_next_node(fdt, offset, NULL);
97
+ break;
80
+ }
98
+ default:
81
+ g_free(prefix);
99
+ g_assert_not_reached();
82
+
83
+ if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
84
+ error_setg(errp, "%s: abort parsing dt for %s node units: %s",
85
+ __func__, name, fdt_strerror(offset));
86
+ for (iter = path_list; iter; iter = iter->next) {
87
+ g_free(iter->data);
88
+ }
89
+ g_slist_free(path_list);
90
+ return NULL;
91
+ }
100
+ }
92
+
101
+
93
+ path_array = g_new(char *, n + 1);
102
+ if (escalate) {
94
+ path_array[n--] = NULL;
103
+ /*
95
+
104
+ * Escalate to HardFault: faults that initially targeted Secure
96
+ for (iter = path_list; iter; iter = iter->next) {
105
+ * continue to do so, even if HF normally targets NonSecure.
97
+ path_array[n--] = iter->data;
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
98
+ }
115
+ }
99
+
116
+
100
+ g_slist_free(path_list);
117
+ if (!vec->enabled ||
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
101
+
129
+
102
+ return path_array;
130
+ if (escalate) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
132
+ }
133
+ if (!vec->pending) {
134
+ vec->pending = 1;
135
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
144
+ }
103
+}
145
+}
104
+
146
+
105
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
147
/* Make pending IRQ active. */
106
Error **errp)
148
void armv7m_nvic_acknowledge_irq(void *opaque)
107
{
149
{
108
--
150
--
109
2.17.1
151
2.20.1
110
152
111
153
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180627043328.11531-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 35 +++++++++
10
target/arm/sve_helper.c | 153 +++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 121 +++++++++++++++++++++++++++++
12
target/arm/sve.decode | 34 +++++++++
13
4 files changed, 343 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
22
void, ptr, ptr, ptr, ptr, i32)
23
+
24
+DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(sve_ld4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve_ld1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_ld2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(sve_ld3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+DEF_HELPER_FLAGS_4(sve_ld4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
+
34
+DEF_HELPER_FLAGS_4(sve_ld1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_ld2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_ld3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+DEF_HELPER_FLAGS_4(sve_ld4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
38
+
39
+DEF_HELPER_FLAGS_4(sve_ld1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_ld2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_ld3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_4(sve_ld4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_ld1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_ld1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_4(sve_ld1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(sve_ld1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_ld1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_4(sve_ld1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+
51
+DEF_HELPER_FLAGS_4(sve_ld1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_4(sve_ld1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(sve_ld1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+
56
+DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
63
64
return predtest_ones(d, oprsz, esz_mask);
65
}
66
+
67
+/*
68
+ * Load contiguous data, protected by a governing predicate.
69
+ */
70
+#define DO_LD1(NAME, FN, TYPEE, TYPEM, H) \
71
+static void do_##NAME(CPUARMState *env, void *vd, void *vg, \
72
+ target_ulong addr, intptr_t oprsz, \
73
+ uintptr_t ra) \
74
+{ \
75
+ intptr_t i = 0; \
76
+ do { \
77
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
78
+ do { \
79
+ TYPEM m = 0; \
80
+ if (pg & 1) { \
81
+ m = FN(env, addr, ra); \
82
+ } \
83
+ *(TYPEE *)(vd + H(i)) = m; \
84
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
85
+ addr += sizeof(TYPEM); \
86
+ } while (i & 15); \
87
+ } while (i < oprsz); \
88
+} \
89
+void HELPER(NAME)(CPUARMState *env, void *vg, \
90
+ target_ulong addr, uint32_t desc) \
91
+{ \
92
+ do_##NAME(env, &env->vfp.zregs[simd_data(desc)], vg, \
93
+ addr, simd_oprsz(desc), GETPC()); \
94
+}
95
+
96
+#define DO_LD2(NAME, FN, TYPEE, TYPEM, H) \
97
+void HELPER(NAME)(CPUARMState *env, void *vg, \
98
+ target_ulong addr, uint32_t desc) \
99
+{ \
100
+ intptr_t i, oprsz = simd_oprsz(desc); \
101
+ intptr_t ra = GETPC(); \
102
+ unsigned rd = simd_data(desc); \
103
+ void *d1 = &env->vfp.zregs[rd]; \
104
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
105
+ for (i = 0; i < oprsz; ) { \
106
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
107
+ do { \
108
+ TYPEM m1 = 0, m2 = 0; \
109
+ if (pg & 1) { \
110
+ m1 = FN(env, addr, ra); \
111
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
112
+ } \
113
+ *(TYPEE *)(d1 + H(i)) = m1; \
114
+ *(TYPEE *)(d2 + H(i)) = m2; \
115
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
116
+ addr += 2 * sizeof(TYPEM); \
117
+ } while (i & 15); \
118
+ } \
119
+}
120
+
121
+#define DO_LD3(NAME, FN, TYPEE, TYPEM, H) \
122
+void HELPER(NAME)(CPUARMState *env, void *vg, \
123
+ target_ulong addr, uint32_t desc) \
124
+{ \
125
+ intptr_t i, oprsz = simd_oprsz(desc); \
126
+ intptr_t ra = GETPC(); \
127
+ unsigned rd = simd_data(desc); \
128
+ void *d1 = &env->vfp.zregs[rd]; \
129
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
130
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
131
+ for (i = 0; i < oprsz; ) { \
132
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
133
+ do { \
134
+ TYPEM m1 = 0, m2 = 0, m3 = 0; \
135
+ if (pg & 1) { \
136
+ m1 = FN(env, addr, ra); \
137
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
138
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
139
+ } \
140
+ *(TYPEE *)(d1 + H(i)) = m1; \
141
+ *(TYPEE *)(d2 + H(i)) = m2; \
142
+ *(TYPEE *)(d3 + H(i)) = m3; \
143
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
144
+ addr += 3 * sizeof(TYPEM); \
145
+ } while (i & 15); \
146
+ } \
147
+}
148
+
149
+#define DO_LD4(NAME, FN, TYPEE, TYPEM, H) \
150
+void HELPER(NAME)(CPUARMState *env, void *vg, \
151
+ target_ulong addr, uint32_t desc) \
152
+{ \
153
+ intptr_t i, oprsz = simd_oprsz(desc); \
154
+ intptr_t ra = GETPC(); \
155
+ unsigned rd = simd_data(desc); \
156
+ void *d1 = &env->vfp.zregs[rd]; \
157
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
158
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
159
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
160
+ for (i = 0; i < oprsz; ) { \
161
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
162
+ do { \
163
+ TYPEM m1 = 0, m2 = 0, m3 = 0, m4 = 0; \
164
+ if (pg & 1) { \
165
+ m1 = FN(env, addr, ra); \
166
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
167
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
168
+ m4 = FN(env, addr + 3 * sizeof(TYPEM), ra); \
169
+ } \
170
+ *(TYPEE *)(d1 + H(i)) = m1; \
171
+ *(TYPEE *)(d2 + H(i)) = m2; \
172
+ *(TYPEE *)(d3 + H(i)) = m3; \
173
+ *(TYPEE *)(d4 + H(i)) = m4; \
174
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
175
+ addr += 4 * sizeof(TYPEM); \
176
+ } while (i & 15); \
177
+ } \
178
+}
179
+
180
+DO_LD1(sve_ld1bhu_r, cpu_ldub_data_ra, uint16_t, uint8_t, H1_2)
181
+DO_LD1(sve_ld1bhs_r, cpu_ldsb_data_ra, uint16_t, int8_t, H1_2)
182
+DO_LD1(sve_ld1bsu_r, cpu_ldub_data_ra, uint32_t, uint8_t, H1_4)
183
+DO_LD1(sve_ld1bss_r, cpu_ldsb_data_ra, uint32_t, int8_t, H1_4)
184
+DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
185
+DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
186
+
187
+DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
188
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
189
+DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
190
+DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
191
+
192
+DO_LD1(sve_ld1sdu_r, cpu_ldl_data_ra, uint64_t, uint32_t, )
193
+DO_LD1(sve_ld1sds_r, cpu_ldl_data_ra, uint64_t, int32_t, )
194
+
195
+DO_LD1(sve_ld1bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
196
+DO_LD2(sve_ld2bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
197
+DO_LD3(sve_ld3bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
198
+DO_LD4(sve_ld4bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
199
+
200
+DO_LD1(sve_ld1hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
201
+DO_LD2(sve_ld2hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
202
+DO_LD3(sve_ld3hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
203
+DO_LD4(sve_ld4hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
204
+
205
+DO_LD1(sve_ld1ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
206
+DO_LD2(sve_ld2ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
207
+DO_LD3(sve_ld3ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
208
+DO_LD4(sve_ld4ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
209
+
210
+DO_LD1(sve_ld1dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
211
+DO_LD2(sve_ld2dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
212
+DO_LD3(sve_ld3dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
213
+DO_LD4(sve_ld4dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
214
+
215
+#undef DO_LD1
216
+#undef DO_LD2
217
+#undef DO_LD3
218
+#undef DO_LD4
219
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/arm/translate-sve.c
222
+++ b/target/arm/translate-sve.c
223
@@ -XXX,XX +XXX,XX @@ typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
224
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
225
TCGv_ptr, TCGv_ptr, TCGv_i32);
226
227
+typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32);
228
+
229
/*
230
* Helpers for extracting complex instruction fields.
231
*/
232
@@ -XXX,XX +XXX,XX @@ static inline int expand_imm_sh8u(int x)
233
return (uint8_t)x << (x & 0x100 ? 8 : 0);
234
}
235
236
+/* Convert a 2-bit memory size (msz) to a 4-bit data type (dtype)
237
+ * with unsigned data. C.f. SVE Memory Contiguous Load Group.
238
+ */
239
+static inline int msz_dtype(int msz)
240
+{
241
+ static const uint8_t dtype[4] = { 0, 5, 10, 15 };
242
+ return dtype[msz];
243
+}
244
+
245
/*
246
* Include the generated decoder.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
249
}
250
return true;
251
}
252
+
253
+/*
254
+ *** SVE Memory - Contiguous Load Group
255
+ */
256
+
257
+/* The memory mode of the dtype. */
258
+static const TCGMemOp dtype_mop[16] = {
259
+ MO_UB, MO_UB, MO_UB, MO_UB,
260
+ MO_SL, MO_UW, MO_UW, MO_UW,
261
+ MO_SW, MO_SW, MO_UL, MO_UL,
262
+ MO_SB, MO_SB, MO_SB, MO_Q
263
+};
264
+
265
+#define dtype_msz(x) (dtype_mop[x] & MO_SIZE)
266
+
267
+/* The vector element size of dtype. */
268
+static const uint8_t dtype_esz[16] = {
269
+ 0, 1, 2, 3,
270
+ 3, 1, 2, 3,
271
+ 3, 2, 2, 3,
272
+ 3, 2, 1, 3
273
+};
274
+
275
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
276
+ gen_helper_gvec_mem *fn)
277
+{
278
+ unsigned vsz = vec_full_reg_size(s);
279
+ TCGv_ptr t_pg;
280
+ TCGv_i32 desc;
281
+
282
+ /* For e.g. LD4, there are not enough arguments to pass all 4
283
+ * registers as pointers, so encode the regno into the data field.
284
+ * For consistency, do this even for LD1.
285
+ */
286
+ desc = tcg_const_i32(simd_desc(vsz, vsz, zt));
287
+ t_pg = tcg_temp_new_ptr();
288
+
289
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
290
+ fn(cpu_env, t_pg, addr, desc);
291
+
292
+ tcg_temp_free_ptr(t_pg);
293
+ tcg_temp_free_i32(desc);
294
+}
295
+
296
+static void do_ld_zpa(DisasContext *s, int zt, int pg,
297
+ TCGv_i64 addr, int dtype, int nreg)
298
+{
299
+ static gen_helper_gvec_mem * const fns[16][4] = {
300
+ { gen_helper_sve_ld1bb_r, gen_helper_sve_ld2bb_r,
301
+ gen_helper_sve_ld3bb_r, gen_helper_sve_ld4bb_r },
302
+ { gen_helper_sve_ld1bhu_r, NULL, NULL, NULL },
303
+ { gen_helper_sve_ld1bsu_r, NULL, NULL, NULL },
304
+ { gen_helper_sve_ld1bdu_r, NULL, NULL, NULL },
305
+
306
+ { gen_helper_sve_ld1sds_r, NULL, NULL, NULL },
307
+ { gen_helper_sve_ld1hh_r, gen_helper_sve_ld2hh_r,
308
+ gen_helper_sve_ld3hh_r, gen_helper_sve_ld4hh_r },
309
+ { gen_helper_sve_ld1hsu_r, NULL, NULL, NULL },
310
+ { gen_helper_sve_ld1hdu_r, NULL, NULL, NULL },
311
+
312
+ { gen_helper_sve_ld1hds_r, NULL, NULL, NULL },
313
+ { gen_helper_sve_ld1hss_r, NULL, NULL, NULL },
314
+ { gen_helper_sve_ld1ss_r, gen_helper_sve_ld2ss_r,
315
+ gen_helper_sve_ld3ss_r, gen_helper_sve_ld4ss_r },
316
+ { gen_helper_sve_ld1sdu_r, NULL, NULL, NULL },
317
+
318
+ { gen_helper_sve_ld1bds_r, NULL, NULL, NULL },
319
+ { gen_helper_sve_ld1bss_r, NULL, NULL, NULL },
320
+ { gen_helper_sve_ld1bhs_r, NULL, NULL, NULL },
321
+ { gen_helper_sve_ld1dd_r, gen_helper_sve_ld2dd_r,
322
+ gen_helper_sve_ld3dd_r, gen_helper_sve_ld4dd_r },
323
+ };
324
+ gen_helper_gvec_mem *fn = fns[dtype][nreg];
325
+
326
+ /* While there are holes in the table, they are not
327
+ * accessible via the instruction encoding.
328
+ */
329
+ assert(fn != NULL);
330
+ do_mem_zpa(s, zt, pg, addr, fn);
331
+}
332
+
333
+static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
334
+{
335
+ if (a->rm == 31) {
336
+ return false;
337
+ }
338
+ if (sve_access_check(s)) {
339
+ TCGv_i64 addr = new_tmp_a64(s);
340
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
341
+ (a->nreg + 1) << dtype_msz(a->dtype));
342
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
343
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
344
+ }
345
+ return true;
346
+}
347
+
348
+static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
349
+{
350
+ if (sve_access_check(s)) {
351
+ int vsz = vec_full_reg_size(s);
352
+ int elements = vsz >> dtype_esz[a->dtype];
353
+ TCGv_i64 addr = new_tmp_a64(s);
354
+
355
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
356
+ (a->imm * elements * (a->nreg + 1))
357
+ << dtype_msz(a->dtype));
358
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
359
+ }
360
+ return true;
361
+}
362
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
363
index XXXXXXX..XXXXXXX 100644
364
--- a/target/arm/sve.decode
365
+++ b/target/arm/sve.decode
366
@@ -XXX,XX +XXX,XX @@
367
# Unsigned 8-bit immediate, optionally shifted left by 8.
368
%sh8_i8u 5:9 !function=expand_imm_sh8u
369
370
+# Unsigned load of msz into esz=2, represented as a dtype.
371
+%msz_dtype 23:2 !function=msz_dtype
372
+
373
# Either a copy of rd (at bit 0), or a different source
374
# as propagated via the MOVPRFX instruction.
375
%reg_movprfx 0:5
376
@@ -XXX,XX +XXX,XX @@
377
&incdec2_cnt rd rn pat esz imm d u
378
&incdec_pred rd pg esz d u
379
&incdec2_pred rd rn pg esz d u
380
+&rprr_load rd pg rn rm dtype nreg
381
+&rpri_load rd pg rn imm dtype nreg
382
383
###########################################################################
384
# Named instruction formats. These are generally used to
385
@@ -XXX,XX +XXX,XX @@
386
@incdec2_pred ........ esz:2 .... .. ..... .. pg:4 rd:5 \
387
&incdec2_pred rn=%reg_movprfx
388
389
+# Loads; user must fill in NREG.
390
+@rprr_load_dt ....... dtype:4 rm:5 ... pg:3 rn:5 rd:5 &rprr_load
391
+@rpri_load_dt ....... dtype:4 . imm:s4 ... pg:3 rn:5 rd:5 &rpri_load
392
+
393
+@rprr_load_msz ....... .... rm:5 ... pg:3 rn:5 rd:5 \
394
+ &rprr_load dtype=%msz_dtype
395
+@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
396
+ &rpri_load dtype=%msz_dtype
397
+
398
###########################################################################
399
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
400
401
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
402
403
# SVE load vector register
404
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
405
+
406
+### SVE Memory Contiguous Load Group
407
+
408
+# SVE contiguous load (scalar plus scalar)
409
+LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
410
+
411
+# SVE contiguous load (scalar plus immediate)
412
+LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
413
+
414
+# SVE contiguous non-temporal load (scalar plus scalar)
415
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
416
+# SVE load multiple structures (scalar plus scalar)
417
+# LD2B, LD2H, LD2W, LD2D; etc.
418
+LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
419
+
420
+# SVE contiguous non-temporal load (scalar plus immediate)
421
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
422
+# SVE load multiple structures (scalar plus immediate)
423
+# LD2B, LD2H, LD2W, LD2D; etc.
424
+LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
425
--
426
2.17.1
427
428
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Pushing registers to the stack for v7M needs to handle three cases:
2
2
* the "normal" case where we pend exceptions
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
* an "ignore faults" case where we set FSR bits but
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
do not pend exceptions (this is used when we are
5
Message-id: 20180627043328.11531-29-richard.henderson@linaro.org
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
9
Implement this by changing the existing flag argument that
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
7
---
16
---
8
target/arm/helper-sve.h | 7 +++
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
9
target/arm/sve_helper.c | 100 +++++++++++++++++++++++++++++++++++++
18
1 file changed, 79 insertions(+), 39 deletions(-)
10
target/arm/translate-sve.c | 24 +++++++++
19
11
target/arm/sve.decode | 4 ++
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
4 files changed, 135 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
22
--- a/target/arm/helper.c
17
+++ b/target/arm/helper-sve.h
23
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
19
DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fcadd_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
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
}
25
}
38
}
26
}
39
27
40
+/*
28
+/*
41
+ * FP Complex Add
29
+ * What kind of stack write are we doing? This affects how exceptions
30
+ * generated during the stacking are treated.
42
+ */
31
+ */
32
+typedef enum StackingMode {
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
43
+
37
+
44
+void HELPER(sve_fcadd_h)(void *vd, void *vn, void *vm, void *vg,
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
+ void *vs, uint32_t desc)
39
- ARMMMUIdx mmu_idx, bool ignfault)
46
+{
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
47
+ intptr_t j, i = simd_oprsz(desc);
41
{
48
+ uint64_t *g = vg;
42
CPUState *cs = CPU(cpu);
49
+ float16 neg_imag = float16_set_sign(0, simd_data(desc));
43
CPUARMState *env = &cpu->env;
50
+ float16 neg_real = float16_chs(neg_imag);
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
51
+
45
&attrs, &prot, &page_size, &fi, NULL)) {
52
+ do {
46
/* MPU/SAU lookup failed */
53
+ uint64_t pg = g[(i - 1) >> 6];
47
if (fi.type == ARMFault_QEMU_SFault) {
54
+ do {
48
- qemu_log_mask(CPU_LOG_INT,
55
+ float16 e0, e1, e2, e3;
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
56
+
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
57
+ /* I holds the real index; J holds the imag index. */
51
+ if (mode == STACK_LAZYFP) {
58
+ j = i - sizeof(float16);
52
+ qemu_log_mask(CPU_LOG_INT,
59
+ i -= 2 * sizeof(float16);
53
+ "...SecureFault with SFSR.LSPERR "
60
+
54
+ "during lazy stacking\n");
61
+ e0 = *(float16 *)(vn + H1_2(i));
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
62
+ e1 = *(float16 *)(vm + H1_2(j)) ^ neg_real;
56
+ } else {
63
+ e2 = *(float16 *)(vn + H1_2(j));
57
+ qemu_log_mask(CPU_LOG_INT,
64
+ e3 = *(float16 *)(vm + H1_2(i)) ^ neg_imag;
58
+ "...SecureFault with SFSR.AUVIOL "
65
+
59
+ "during stacking\n");
66
+ if (likely((pg >> (i & 63)) & 1)) {
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
67
+ *(float16 *)(vd + H1_2(i)) = float16_add(e0, e1, vs);
68
+ }
61
+ }
69
+ if (likely((pg >> (j & 63)) & 1)) {
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
70
+ *(float16 *)(vd + H1_2(j)) = float16_add(e2, e3, vs);
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
71
+ }
77
+ }
72
+ } while (i & 63);
78
exc = ARMV7M_EXCP_MEM;
73
+ } while (i != 0);
79
exc_secure = secure;
74
+}
80
}
75
+
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
76
+void HELPER(sve_fcadd_s)(void *vd, void *vn, void *vm, void *vg,
82
attrs, &txres);
77
+ void *vs, uint32_t desc)
83
if (txres != MEMTX_OK) {
78
+{
84
/* BusFault trying to write the data */
79
+ intptr_t j, i = simd_oprsz(desc);
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
80
+ uint64_t *g = vg;
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
81
+ float32 neg_imag = float32_set_sign(0, simd_data(desc));
87
+ if (mode == STACK_LAZYFP) {
82
+ float32 neg_real = float32_chs(neg_imag);
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
83
+
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
84
+ do {
90
+ } else {
85
+ uint64_t pg = g[(i - 1) >> 6];
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
+ do {
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ float32 e0, e1, e2, e3;
93
+ }
88
+
94
exc = ARMV7M_EXCP_BUS;
89
+ /* I holds the real index; J holds the imag index. */
95
exc_secure = false;
90
+ j = i - sizeof(float32);
96
goto pend_fault;
91
+ i -= 2 * sizeof(float32);
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
92
+
98
* later if we have two derived exceptions.
93
+ e0 = *(float32 *)(vn + H1_2(i));
99
* The only case when we must not pend the exception but instead
94
+ e1 = *(float32 *)(vm + H1_2(j)) ^ neg_real;
100
* throw it away is if we are doing the push of the callee registers
95
+ e2 = *(float32 *)(vn + H1_2(j));
101
- * and we've already generated a derived exception. Even in this
96
+ e3 = *(float32 *)(vm + H1_2(i)) ^ neg_imag;
102
- * case we will still update the fault status registers.
97
+
103
+ * and we've already generated a derived exception (this is indicated
98
+ if (likely((pg >> (i & 63)) & 1)) {
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
99
+ *(float32 *)(vd + H1_2(i)) = float32_add(e0, e1, vs);
105
+ * still update the fault status registers.
100
+ }
106
*/
101
+ if (likely((pg >> (j & 63)) & 1)) {
107
- if (!ignfault) {
102
+ *(float32 *)(vd + H1_2(j)) = float32_add(e2, e3, vs);
108
+ switch (mode) {
103
+ }
109
+ case STACK_NORMAL:
104
+ } while (i & 63);
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
105
+ } while (i != 0);
111
+ break;
106
+}
112
+ case STACK_LAZYFP:
107
+
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
108
+void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
114
+ break;
109
+ void *vs, uint32_t desc)
115
+ case STACK_IGNFAULTS:
110
+{
116
+ break;
111
+ intptr_t j, i = simd_oprsz(desc);
117
}
112
+ uint64_t *g = vg;
118
return false;
113
+ float64 neg_imag = float64_set_sign(0, simd_data(desc));
119
}
114
+ float64 neg_real = float64_chs(neg_imag);
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
115
+
121
uint32_t limit;
116
+ do {
122
bool want_psp;
117
+ uint64_t pg = g[(i - 1) >> 6];
123
uint32_t sig;
118
+ do {
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
119
+ float64 e0, e1, e2, e3;
125
120
+
126
if (dotailchain) {
121
+ /* I holds the real index; J holds the imag index. */
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
122
+ j = i - sizeof(float64);
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
123
+ i -= 2 * sizeof(float64);
129
*/
124
+
130
sig = v7m_integrity_sig(env, lr);
125
+ e0 = *(float64 *)(vn + H1_2(i));
131
stacked_ok =
126
+ e1 = *(float64 *)(vm + H1_2(j)) ^ neg_real;
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
127
+ e2 = *(float64 *)(vn + H1_2(j));
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
128
+ e3 = *(float64 *)(vm + H1_2(i)) ^ neg_imag;
134
- ignore_faults) &&
129
+
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
130
+ if (likely((pg >> (i & 63)) & 1)) {
136
- ignore_faults) &&
131
+ *(float64 *)(vd + H1_2(i)) = float64_add(e0, e1, vs);
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
132
+ }
138
- ignore_faults) &&
133
+ if (likely((pg >> (j & 63)) & 1)) {
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
134
+ *(float64 *)(vd + H1_2(j)) = float64_add(e2, e3, vs);
140
- ignore_faults) &&
135
+ }
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
136
+ } while (i & 63);
142
- ignore_faults) &&
137
+ } while (i != 0);
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
138
+}
144
- ignore_faults) &&
139
+
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
140
/*
146
- ignore_faults) &&
141
* Load contiguous data, protected by a governing predicate.
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
142
*/
148
- ignore_faults);
143
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
144
index XXXXXXX..XXXXXXX 100644
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
145
--- a/target/arm/translate-sve.c
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
146
+++ b/target/arm/translate-sve.c
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
147
@@ -XXX,XX +XXX,XX @@ DO_FPCMP(FACGT, facgt)
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
148
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
149
#undef DO_FPCMP
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
150
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
151
+static bool trans_FCADD(DisasContext *s, arg_FCADD *a, uint32_t insn)
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
152
+{
158
153
+ static gen_helper_gvec_4_ptr * const fns[3] = {
159
/* Update SP regardless of whether any of the stack accesses failed. */
154
+ gen_helper_sve_fcadd_h,
160
*frame_sp_p = frameptr;
155
+ gen_helper_sve_fcadd_s,
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
156
+ gen_helper_sve_fcadd_d
162
* if it has higher priority).
157
+ };
163
*/
158
+
164
stacked_ok = stacked_ok &&
159
+ if (a->esz == 0) {
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
160
+ return false;
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
161
+ }
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
162
+ if (sve_access_check(s)) {
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
163
+ unsigned vsz = vec_full_reg_size(s);
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
164
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
165
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
166
+ vec_full_reg_offset(s, a->rn),
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
167
+ vec_full_reg_offset(s, a->rm),
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
168
+ pred_full_reg_offset(s, a->pg),
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
169
+ status, vsz, vsz, a->rot, fns[a->esz - 1]);
175
+ mmu_idx, STACK_NORMAL) &&
170
+ tcg_temp_free_ptr(status);
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
171
+ }
177
+ mmu_idx, STACK_NORMAL) &&
172
+ return true;
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
173
+}
179
+ mmu_idx, STACK_NORMAL) &&
174
+
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
175
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
181
+ mmu_idx, STACK_NORMAL) &&
176
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
177
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
183
+ mmu_idx, STACK_NORMAL) &&
178
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
179
index XXXXXXX..XXXXXXX 100644
185
+ mmu_idx, STACK_NORMAL) &&
180
--- a/target/arm/sve.decode
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
181
+++ b/target/arm/sve.decode
187
182
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
183
# SVE integer multiply immediate (unpredicated)
189
/* FPU is active, try to save its registers */
184
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
185
191
faddr += 8; /* skip the slot for the FPSCR */
186
+# SVE floating-point complex add (predicated)
192
}
187
+FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
193
stacked_ok = stacked_ok &&
188
+ rn=%reg_movprfx
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
189
+
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
190
### SVE FP Multiply-Add Indexed Group
196
+ v7m_stack_write(cpu, faddr, slo,
191
197
+ mmu_idx, STACK_NORMAL) &&
192
# SVE floating-point multiply-add (indexed)
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
193
--
208
--
194
2.17.1
209
2.20.1
195
210
196
211
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile architecture floating point system supports
2
2
lazy FP state preservation, where FP registers are not
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
pushed to the stack when an exception occurs but are instead
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
only saved if and when the first FP instruction in the exception
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
handler is executed. Implement this in QEMU, corresponding
6
Message-id: 20180627043328.11531-34-richard.henderson@linaro.org
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
7
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: 20190416125744.27770-24-peter.maydell@linaro.org
8
---
11
---
9
target/arm/helper.h | 5 ++
12
target/arm/cpu.h | 3 ++
10
target/arm/translate-sve.c | 18 ++++++
13
target/arm/helper.h | 2 +
11
target/arm/vec_helper.c | 124 +++++++++++++++++++++++++++++++++++++
14
target/arm/translate.h | 1 +
12
target/arm/sve.decode | 6 ++
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
13
4 files changed, 153 insertions(+)
16
target/arm/translate.c | 22 ++++++++
14
17
5 files changed, 140 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
42
--- a/target/arm/helper.h
18
+++ b/target/arm/helper.h
43
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
20
DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
21
DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
22
47
23
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
24
+DEF_HELPER_FLAGS_4(gvec_udot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+
25
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
26
+DEF_HELPER_FLAGS_4(gvec_udot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
27
+
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
void, ptr, ptr, ptr, ptr, i32)
54
index XXXXXXX..XXXXXXX 100644
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
55
--- a/target/arm/translate.h
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
56
+++ b/target/arm/translate.h
32
index XXXXXXX..XXXXXXX 100644
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
33
--- a/target/arm/translate-sve.c
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
34
+++ b/target/arm/translate-sve.c
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
35
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
36
return true;
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
37
}
71
}
38
72
39
+static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a, uint32_t insn)
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
40
+{
74
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
75
+ /* translate.c should never generate calls here in user-only mode */
42
+ { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
76
+ g_assert_not_reached();
43
+ { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_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, a->index, fns[a->u][a->sz]);
52
+ }
53
+ return true;
54
+}
77
+}
55
+
78
+
56
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
57
/*
80
{
58
*** SVE Floating Point Multiply-Add Indexed Group
81
/* The TT instructions can be used by unprivileged code, but in
59
*/
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
60
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
83
return false;
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
}
84
}
67
85
68
+void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
69
+{
87
+{
70
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
88
+ /*
71
+ intptr_t index = simd_data(desc);
89
+ * Preserve FP state (because LSPACT was set and we are about
72
+ uint32_t *d = vd;
90
+ * to execute an FP instruction). This corresponds to the
73
+ int8_t *n = vn;
91
+ * PreserveFPState() pseudocode.
74
+ int8_t *m_indexed = (int8_t *)vm + index * 4;
92
+ * We may throw an exception if the stacking fails.
75
+
76
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
77
+ * Otherwise opr_sz is a multiple of 16.
78
+ */
93
+ */
79
+ segend = MIN(4, opr_sz_4);
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
80
+ i = 0;
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
81
+ do {
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
82
+ int8_t m0 = m_indexed[i * 4 + 0];
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
83
+ int8_t m1 = m_indexed[i * 4 + 1];
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
84
+ int8_t m2 = m_indexed[i * 4 + 2];
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
85
+ int8_t m3 = m_indexed[i * 4 + 3];
100
+ bool stacked_ok = true;
86
+
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
87
+ do {
102
+ bool take_exception;
88
+ d[i] += n[i * 4 + 0] * m0
103
+
89
+ + n[i * 4 + 1] * m1
104
+ /* Take the iothread lock as we are going to touch the NVIC */
90
+ + n[i * 4 + 2] * m2
105
+ qemu_mutex_lock_iothread();
91
+ + n[i * 4 + 3] * m3;
106
+
92
+ } while (++i < segend);
107
+ /* Check the background context had access to the FPU */
93
+ segend = i + 4;
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
94
+ } while (i < opr_sz_4);
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
95
+
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
96
+ clear_tail(d, opr_sz, simd_maxsz(desc));
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
97
+}
175
+}
98
+
176
+
99
+void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
100
+{
178
* This may change the current stack pointer between Main and Process
101
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
179
* stack pointers if it is done for the CONTROL register for the current
102
+ intptr_t index = simd_data(desc);
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
103
+ uint32_t *d = vd;
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
104
+ uint8_t *n = vn;
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
105
+ uint8_t *m_indexed = (uint8_t *)vm + index * 4;
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
106
+
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
107
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
185
};
108
+ * Otherwise opr_sz is a multiple of 16.
186
109
+ */
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
110
+ segend = MIN(4, opr_sz_4);
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
111
+ i = 0;
189
return;
112
+ do {
190
}
113
+ uint8_t m0 = m_indexed[i * 4 + 0];
191
break;
114
+ uint8_t m1 = m_indexed[i * 4 + 1];
192
+ case EXCP_LAZYFP:
115
+ uint8_t m2 = m_indexed[i * 4 + 2];
193
+ /*
116
+ uint8_t m3 = m_indexed[i * 4 + 3];
194
+ * We already pended the specific exception in the NVIC in the
117
+
195
+ * v7m_preserve_fp_state() helper function.
118
+ do {
196
+ */
119
+ d[i] += n[i * 4 + 0] * m0
197
+ break;
120
+ + n[i * 4 + 1] * m1
198
default:
121
+ + n[i * 4 + 2] * m2
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
122
+ + n[i * 4 + 3] * m3;
200
return; /* Never happens. Keep compiler happy. */
123
+ } while (++i < segend);
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
124
+ segend = i + 4;
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
125
+ } while (i < opr_sz_4);
203
}
126
+
204
127
+ clear_tail(d, opr_sz, simd_maxsz(desc));
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
128
+}
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
129
+
207
+
130
+void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
131
+{
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
132
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
210
+ }
133
+ intptr_t index = simd_data(desc);
211
+ }
134
+ uint64_t *d = vd;
212
+
135
+ int16_t *n = vn;
213
*pflags = flags;
136
+ int16_t *m_indexed = (int16_t *)vm + index * 4;
214
*cs_base = 0;
137
+
215
}
138
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
139
+ * Process the entire segment all at once, writing back the results
217
index XXXXXXX..XXXXXXX 100644
140
+ * only after we've consumed all of the inputs.
218
--- a/target/arm/translate.c
141
+ */
219
+++ b/target/arm/translate.c
142
+ for (i = 0; i < opr_sz_8 ; i += 2) {
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
143
+ uint64_t d0, d1;
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
144
+
222
/* Handle M-profile lazy FP state mechanics */
145
+ d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
223
146
+ d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
224
+ /* Trigger lazy-state preservation if necessary */
147
+ d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
225
+ if (s->v7m_lspact) {
148
+ d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3];
226
+ /*
149
+ d1 = n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
227
+ * Lazy state saving affects external memory and also the NVIC,
150
+ d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1];
228
+ * so we must mark it as an IO operation for icount.
151
+ d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2];
229
+ */
152
+ d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3];
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
153
+
231
+ gen_io_start();
154
+ d[i + 0] += d0;
232
+ }
155
+ d[i + 1] += d1;
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
156
+ }
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
157
+
235
+ gen_io_end();
158
+ clear_tail(d, opr_sz, simd_maxsz(desc));
236
+ }
159
+}
237
+ /*
160
+
238
+ * If the preserve_fp_state helper doesn't throw an exception
161
+void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
239
+ * then it will clear LSPACT; we don't need to repeat this for
162
+{
240
+ * any further FP insns in this TB.
163
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
241
+ */
164
+ intptr_t index = simd_data(desc);
242
+ s->v7m_lspact = false;
165
+ uint64_t *d = vd;
243
+ }
166
+ uint16_t *n = vn;
244
+
167
+ uint16_t *m_indexed = (uint16_t *)vm + index * 4;
245
/* Update ownership of FP context: set FPCCR.S to match current state */
168
+
246
if (s->v8m_fpccr_s_wrong) {
169
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
247
TCGv_i32 tmp;
170
+ * Process the entire segment all at once, writing back the results
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
171
+ * only after we've consumed all of the inputs.
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
172
+ */
250
dc->v7m_new_fp_ctxt_needed =
173
+ for (i = 0; i < opr_sz_8 ; i += 2) {
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
174
+ uint64_t d0, d1;
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
175
+
253
dc->cp_regs = cpu->cp_regs;
176
+ d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
254
dc->features = env->features;
177
+ d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1];
255
178
+ d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2];
179
+ d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3];
180
+ d1 = n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
181
+ d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1];
182
+ d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2];
183
+ d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3];
184
+
185
+ d[i + 0] += d0;
186
+ d[i + 1] += d1;
187
+ }
188
+
189
+ clear_tail(d, opr_sz, simd_maxsz(desc));
190
+}
191
+
192
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
193
void *vfpst, uint32_t desc)
194
{
195
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/sve.decode
198
+++ b/target/arm/sve.decode
199
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
200
# SVE integer dot product (unpredicated)
201
DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
202
203
+# SVE integer dot product (indexed)
204
+DOT_zzx 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
205
+ sz=0 ra=%reg_movprfx
206
+DOT_zzx 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
207
+ sz=1 ra=%reg_movprfx
208
+
209
# SVE floating-point complex add (predicated)
210
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
211
rn=%reg_movprfx
212
--
256
--
213
2.17.1
257
2.20.1
214
258
215
259
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-sve.h | 30 +++++++++++++
7
target/arm/cpu.h | 2 +
9
target/arm/helper.h | 12 +++---
8
target/arm/helper.h | 2 +
10
target/arm/helper.c | 2 +-
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
11
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 15 +++++++-
12
target/arm/translate-sve.c | 70 ++++++++++++++++++++++++++++++
11
4 files changed, 102 insertions(+), 1 deletion(-)
13
target/arm/sve.decode | 16 +++++++
14
6 files changed, 211 insertions(+), 7 deletions(-)
15
12
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
15
--- a/target/arm/cpu.h
19
+++ b/target/arm/helper-sve.h
16
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@
21
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
22
void, ptr, ptr, ptr, ptr, i32)
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
23
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
24
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
25
+ void, ptr, ptr, ptr, ptr, i32)
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
26
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hs, TCG_CALL_NO_RWG,
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
27
+ void, ptr, ptr, ptr, ptr, i32)
24
28
+DEF_HELPER_FLAGS_5(sve_fcvtzs_ss, TCG_CALL_NO_RWG,
25
#define ARMV7M_EXCP_RESET 1
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
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
58
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/helper.h
28
--- a/target/arm/helper.h
60
+++ b/target/arm/helper.h
29
+++ b/target/arm/helper.h
61
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(vfp_touid, i32, f64, ptr)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
62
DEF_HELPER_2(vfp_touizh, i32, f16, ptr)
31
63
DEF_HELPER_2(vfp_touizs, i32, f32, ptr)
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
64
DEF_HELPER_2(vfp_touizd, i32, f64, ptr)
33
65
-DEF_HELPER_2(vfp_tosih, i32, f16, ptr)
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
66
-DEF_HELPER_2(vfp_tosis, i32, f32, ptr)
35
+
67
-DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
68
-DEF_HELPER_2(vfp_tosizh, i32, f16, ptr)
37
69
-DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
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
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ ftype HELPER(name)(uint32_t x, void *fpstp) \
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
44
g_assert_not_reached();
85
}
45
}
86
46
87
#define CONV_FTOI(name, ftype, fsz, sign, round) \
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
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
+{
48
+{
103
+ if (float16_is_any_nan(f)) {
49
+ /* translate.c should never generate calls here in user-only mode */
104
+ float_raise(float_flag_invalid, s);
50
+ g_assert_not_reached();
105
+ return 0;
106
+ }
107
+ return float16_to_int16_round_to_zero(f, s);
108
+}
51
+}
109
+
52
+
110
+static inline int64_t vfp_float16_to_int64_rtz(float16 f, float_status *s)
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
54
{
55
/* The TT instructions can be used by unprivileged code, but in
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
57
}
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
111
+{
61
+{
112
+ if (float16_is_any_nan(f)) {
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
113
+ float_raise(float_flag_invalid, s);
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
114
+ return 0;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
65
+
66
+ assert(env->v7m.secure);
67
+
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
69
+ return;
115
+ }
70
+ }
116
+ return float16_to_int64_round_to_zero(f, s);
71
+
72
+ /* Check access to the coprocessor is permitted */
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
85
+
86
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
88
+ * accesses should not set the FSR bits for stacking errors if they
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
95
+ int i;
96
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
117
+}
126
+}
118
+
127
+
119
+static inline int64_t vfp_float32_to_int64_rtz(float32 f, float_status *s)
128
static bool v7m_push_stack(ARMCPU *cpu)
120
+{
129
{
121
+ if (float32_is_any_nan(f)) {
130
/* Do the "set up stack frame" part of exception entry,
122
+ float_raise(float_flag_invalid, s);
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
123
+ return 0;
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
124
+ }
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
125
+ return float32_to_int64_round_to_zero(f, s);
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
126
+}
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
127
+
164
+
128
+static inline int64_t vfp_float64_to_int64_rtz(float64 f, float_status *s)
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
129
+{
166
+ TCGv_i32 fptr = load_reg(s, rn);
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
+
167
+
137
+static inline uint16_t vfp_float16_to_uint16_rtz(float16 f, float_status *s)
168
+ if (extract32(insn, 20, 1)) {
138
+{
169
+ /* VLLDM */
139
+ if (float16_is_any_nan(f)) {
170
+ } else {
140
+ float_raise(float_flag_invalid, s);
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
141
+ return 0;
172
+ }
142
+ }
173
+ tcg_temp_free_i32(fptr);
143
+ return float16_to_uint16_round_to_zero(f, s);
144
+}
145
+
174
+
146
+static inline uint64_t vfp_float16_to_uint64_rtz(float16 f, float_status *s)
175
+ /* End the TB, because we have updated FP control bits */
147
+{
176
+ s->base.is_jmp = DISAS_UPDATE;
148
+ if (float16_is_any_nan(f)) {
177
+ }
149
+ float_raise(float_flag_invalid, s);
178
break;
150
+ return 0;
179
}
151
+ }
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
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
--
181
--
308
2.17.1
182
2.20.1
309
183
310
184
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLLDM instruction for v7M for the FPU present cas.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-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>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
8
---
6
---
9
target/arm/helper.h | 5 +++
7
target/arm/helper.h | 1 +
10
target/arm/translate-sve.c | 17 ++++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
11
target/arm/vec_helper.c | 67 ++++++++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
12
target/arm/sve.decode | 3 ++
10
3 files changed, 56 insertions(+), 1 deletion(-)
13
4 files changed, 92 insertions(+)
14
11
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
14
--- a/target/arm/helper.h
18
+++ b/target/arm/helper.h
15
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
20
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG,
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
21
void, ptr, ptr, ptr, ptr, i32)
18
22
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
23
+DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
24
+DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
25
+DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
26
+DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
27
+
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
25
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
26
--- a/target/arm/helper.c
34
+++ b/target/arm/translate-sve.c
27
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
36
29
g_assert_not_reached();
37
#undef DO_ZZI
30
}
38
31
39
+static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
40
+{
33
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
34
+ /* translate.c should never generate calls here in user-only mode */
42
+ { gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h },
35
+ g_assert_not_reached();
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
+}
36
+}
55
+
37
+
56
/*
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
57
*** SVE Floating Point Multiply-Add Indexed Group
39
{
58
*/
40
/* The TT instructions can be used by unprivileged code, but in
59
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
60
index XXXXXXX..XXXXXXX 100644
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
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
}
43
}
66
44
67
+/* Integer 8 and 16-bit dot-product.
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
68
+ *
46
+{
69
+ * Note that for the loops herein, host endianness does not matter
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
70
+ * with respect to the ordering of data within the 64-bit lanes.
48
+ assert(env->v7m.secure);
71
+ * All elements are treated equally, no matter where they are.
72
+ */
73
+
49
+
74
+void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, uint32_t desc)
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
75
+{
51
+ return;
76
+ intptr_t i, opr_sz = simd_oprsz(desc);
52
+ }
77
+ uint32_t *d = vd;
78
+ int8_t *n = vn, *m = vm;
79
+
53
+
80
+ for (i = 0; i < opr_sz / 4; ++i) {
54
+ /* Check access to the coprocessor is permitted */
81
+ d[i] += n[i * 4 + 0] * m[i * 4 + 0]
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
82
+ + n[i * 4 + 1] * m[i * 4 + 1]
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
83
+ + n[i * 4 + 2] * m[i * 4 + 2]
84
+ + n[i * 4 + 3] * m[i * 4 + 3];
85
+ }
57
+ }
86
+ clear_tail(d, opr_sz, simd_maxsz(desc));
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
60
+ /* State in FP is still valid */
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
87
+}
91
+}
88
+
92
+
89
+void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, uint32_t desc)
93
static bool v7m_push_stack(ARMCPU *cpu)
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
{
94
{
137
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
95
/* Do the "set up stack frame" part of exception entry,
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
138
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/sve.decode
98
--- a/target/arm/translate.c
140
+++ b/target/arm/sve.decode
99
+++ b/target/arm/translate.c
141
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
142
# SVE integer multiply immediate (unpredicated)
101
TCGv_i32 fptr = load_reg(s, rn);
143
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
102
144
103
if (extract32(insn, 20, 1)) {
145
+# SVE integer dot product (unpredicated)
104
- /* VLLDM */
146
+DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
147
+
106
} else {
148
# SVE floating-point complex add (predicated)
107
gen_helper_v7m_vlstm(cpu_env, fptr);
149
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
108
}
150
rn=%reg_movprfx
151
--
109
--
152
2.17.1
110
2.20.1
153
111
154
112
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
2
2
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>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
11
---
6
---
12
target/arm/cpu.c | 3 ---
7
target/arm/cpu.c | 8 ++++++++
13
1 file changed, 3 deletions(-)
8
1 file changed, 8 insertions(+)
14
9
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
12
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
13
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
20
* since we don't correctly set the ID registers to advertise them,
15
set_feature(&cpu->env, ARM_FEATURE_M);
21
*/
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
22
set_feature(&cpu->env, ARM_FEATURE_V8);
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
23
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
24
- set_feature(&cpu->env, ARM_FEATURE_NEON);
19
cpu->midr = 0x410fc240; /* r0p0 */
25
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
20
cpu->pmsav7_dregion = 8;
26
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
21
+ cpu->isar.mvfr0 = 0x10110021;
27
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
22
+ cpu->isar.mvfr1 = 0x11000011;
28
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
23
+ cpu->isar.mvfr2 = 0x00000000;
24
cpu->id_pfr0 = 0x00000030;
25
cpu->id_pfr1 = 0x00000200;
26
cpu->id_dfr0 = 0x00100000;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
32
cpu->midr = 0x410fd213; /* r0p3 */
33
cpu->pmsav7_dregion = 16;
34
cpu->sau_sregion = 8;
35
+ cpu->isar.mvfr0 = 0x10110021;
36
+ cpu->isar.mvfr1 = 0x11000011;
37
+ cpu->isar.mvfr2 = 0x00000040;
38
cpu->id_pfr0 = 0x00000030;
39
cpu->id_pfr1 = 0x00000210;
40
cpu->id_dfr0 = 0x00200000;
29
--
41
--
30
2.17.1
42
2.20.1
31
43
32
44
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
11
---
7
hw/arm/fsl-imx7.c | 2 +-
12
hw/dma/Makefile.objs | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
9
14
10
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/fsl-imx7.c
17
--- a/hw/dma/Makefile.objs
13
+++ b/hw/arm/fsl-imx7.c
18
+++ b/hw/dma/Makefile.objs
14
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
15
/*
20
16
* SRC
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
17
*/
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
18
- create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
19
+ create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
20
21
/*
22
* Watchdog
23
--
25
--
24
2.17.1
26
2.20.1
25
27
26
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Message-id: 20180627043328.11531-30-richard.henderson@linaro.org
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/helper-sve.h | 4 +
10
hw/arm/aspeed.c | 13 +++++++++----
9
target/arm/sve_helper.c | 162 +++++++++++++++++++++++++++++++++++++
11
1 file changed, 9 insertions(+), 4 deletions(-)
10
target/arm/translate-sve.c | 37 +++++++++
11
target/arm/sve.decode | 4 +
12
4 files changed, 207 insertions(+)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/hw/arm/aspeed.c
17
+++ b/target/arm/helper-sve.h
16
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
18
#include "hw/arm/aspeed_soc.h"
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
19
#include "hw/boards.h"
21
20
#include "hw/i2c/smbus_eeprom.h"
22
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
+#include "hw/misc/pca9552.h"
23
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
+#include "hw/misc/tmp105.h"
24
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
23
#include "qemu/log.h"
25
+
24
#include "sysemu/block-backend.h"
26
DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
#include "hw/loader.h"
27
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
28
DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
eeprom_buf);
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
28
30
index XXXXXXX..XXXXXXX 100644
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
31
--- a/target/arm/sve_helper.c
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
32
+++ b/target/arm/sve_helper.c
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
32
+ TYPE_TMP105, 0x4d);
34
} while (i != 0);
33
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
* plugged on the I2C bus header */
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
AspeedSoCState *soc = &bmc->soc;
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
+ 0x60);
43
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ 0x4a);
51
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
eeprom_buf);
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
35
}
61
}
36
62
37
+/*
38
+ * FP Complex Multiply
39
+ */
40
+
41
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 22 > 32);
42
+
43
+void HELPER(sve_fcmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
44
+{
45
+ intptr_t j, i = simd_oprsz(desc);
46
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
47
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
48
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
49
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
50
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
51
+ bool flip = rot & 1;
52
+ float16 neg_imag, neg_real;
53
+ void *vd = &env->vfp.zregs[rd];
54
+ void *vn = &env->vfp.zregs[rn];
55
+ void *vm = &env->vfp.zregs[rm];
56
+ void *va = &env->vfp.zregs[ra];
57
+ uint64_t *g = vg;
58
+
59
+ neg_imag = float16_set_sign(0, (rot & 2) != 0);
60
+ neg_real = float16_set_sign(0, rot == 1 || rot == 2);
61
+
62
+ do {
63
+ uint64_t pg = g[(i - 1) >> 6];
64
+ do {
65
+ float16 e1, e2, e3, e4, nr, ni, mr, mi, d;
66
+
67
+ /* I holds the real index; J holds the imag index. */
68
+ j = i - sizeof(float16);
69
+ i -= 2 * sizeof(float16);
70
+
71
+ nr = *(float16 *)(vn + H1_2(i));
72
+ ni = *(float16 *)(vn + H1_2(j));
73
+ mr = *(float16 *)(vm + H1_2(i));
74
+ mi = *(float16 *)(vm + H1_2(j));
75
+
76
+ e2 = (flip ? ni : nr);
77
+ e1 = (flip ? mi : mr) ^ neg_real;
78
+ e4 = e2;
79
+ e3 = (flip ? mr : mi) ^ neg_imag;
80
+
81
+ if (likely((pg >> (i & 63)) & 1)) {
82
+ d = *(float16 *)(va + H1_2(i));
83
+ d = float16_muladd(e2, e1, d, 0, &env->vfp.fp_status_f16);
84
+ *(float16 *)(vd + H1_2(i)) = d;
85
+ }
86
+ if (likely((pg >> (j & 63)) & 1)) {
87
+ d = *(float16 *)(va + H1_2(j));
88
+ d = float16_muladd(e4, e3, d, 0, &env->vfp.fp_status_f16);
89
+ *(float16 *)(vd + H1_2(j)) = d;
90
+ }
91
+ } while (i & 63);
92
+ } while (i != 0);
93
+}
94
+
95
+void HELPER(sve_fcmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
96
+{
97
+ intptr_t j, i = simd_oprsz(desc);
98
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
99
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
100
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
101
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
102
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
103
+ bool flip = rot & 1;
104
+ float32 neg_imag, neg_real;
105
+ void *vd = &env->vfp.zregs[rd];
106
+ void *vn = &env->vfp.zregs[rn];
107
+ void *vm = &env->vfp.zregs[rm];
108
+ void *va = &env->vfp.zregs[ra];
109
+ uint64_t *g = vg;
110
+
111
+ neg_imag = float32_set_sign(0, (rot & 2) != 0);
112
+ neg_real = float32_set_sign(0, rot == 1 || rot == 2);
113
+
114
+ do {
115
+ uint64_t pg = g[(i - 1) >> 6];
116
+ do {
117
+ float32 e1, e2, e3, e4, nr, ni, mr, mi, d;
118
+
119
+ /* I holds the real index; J holds the imag index. */
120
+ j = i - sizeof(float32);
121
+ i -= 2 * sizeof(float32);
122
+
123
+ nr = *(float32 *)(vn + H1_2(i));
124
+ ni = *(float32 *)(vn + H1_2(j));
125
+ mr = *(float32 *)(vm + H1_2(i));
126
+ mi = *(float32 *)(vm + H1_2(j));
127
+
128
+ e2 = (flip ? ni : nr);
129
+ e1 = (flip ? mi : mr) ^ neg_real;
130
+ e4 = e2;
131
+ e3 = (flip ? mr : mi) ^ neg_imag;
132
+
133
+ if (likely((pg >> (i & 63)) & 1)) {
134
+ d = *(float32 *)(va + H1_2(i));
135
+ d = float32_muladd(e2, e1, d, 0, &env->vfp.fp_status);
136
+ *(float32 *)(vd + H1_2(i)) = d;
137
+ }
138
+ if (likely((pg >> (j & 63)) & 1)) {
139
+ d = *(float32 *)(va + H1_2(j));
140
+ d = float32_muladd(e4, e3, d, 0, &env->vfp.fp_status);
141
+ *(float32 *)(vd + H1_2(j)) = d;
142
+ }
143
+ } while (i & 63);
144
+ } while (i != 0);
145
+}
146
+
147
+void HELPER(sve_fcmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
148
+{
149
+ intptr_t j, i = simd_oprsz(desc);
150
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
151
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
152
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
153
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
154
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
155
+ bool flip = rot & 1;
156
+ float64 neg_imag, neg_real;
157
+ void *vd = &env->vfp.zregs[rd];
158
+ void *vn = &env->vfp.zregs[rn];
159
+ void *vm = &env->vfp.zregs[rm];
160
+ void *va = &env->vfp.zregs[ra];
161
+ uint64_t *g = vg;
162
+
163
+ neg_imag = float64_set_sign(0, (rot & 2) != 0);
164
+ neg_real = float64_set_sign(0, rot == 1 || rot == 2);
165
+
166
+ do {
167
+ uint64_t pg = g[(i - 1) >> 6];
168
+ do {
169
+ float64 e1, e2, e3, e4, nr, ni, mr, mi, d;
170
+
171
+ /* I holds the real index; J holds the imag index. */
172
+ j = i - sizeof(float64);
173
+ i -= 2 * sizeof(float64);
174
+
175
+ nr = *(float64 *)(vn + H1_2(i));
176
+ ni = *(float64 *)(vn + H1_2(j));
177
+ mr = *(float64 *)(vm + H1_2(i));
178
+ mi = *(float64 *)(vm + H1_2(j));
179
+
180
+ e2 = (flip ? ni : nr);
181
+ e1 = (flip ? mi : mr) ^ neg_real;
182
+ e4 = e2;
183
+ e3 = (flip ? mr : mi) ^ neg_imag;
184
+
185
+ if (likely((pg >> (i & 63)) & 1)) {
186
+ d = *(float64 *)(va + H1_2(i));
187
+ d = float64_muladd(e2, e1, d, 0, &env->vfp.fp_status);
188
+ *(float64 *)(vd + H1_2(i)) = d;
189
+ }
190
+ if (likely((pg >> (j & 63)) & 1)) {
191
+ d = *(float64 *)(va + H1_2(j));
192
+ d = float64_muladd(e4, e3, d, 0, &env->vfp.fp_status);
193
+ *(float64 *)(vd + H1_2(j)) = d;
194
+ }
195
+ } while (i & 63);
196
+ } while (i != 0);
197
+}
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
204
--- a/target/arm/translate-sve.c
205
+++ b/target/arm/translate-sve.c
206
@@ -XXX,XX +XXX,XX @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
207
208
#undef DO_FMLA
209
210
+static bool trans_FCMLA_zpzzz(DisasContext *s,
211
+ arg_FCMLA_zpzzz *a, uint32_t insn)
212
+{
213
+ static gen_helper_sve_fmla * const fns[3] = {
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
--
63
--
266
2.17.1
64
2.20.1
267
65
268
66
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The qdev_get_gpio_in() function accept an int as second parameter.
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/arm/fsl-imx7.c | 6 +++---
9
hw/arm/nseries.c | 3 ++-
11
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
11
13
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx7.c
14
--- a/hw/arm/nseries.c
16
+++ b/hw/arm/fsl-imx7.c
15
+++ b/hw/arm/nseries.c
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@
18
FSL_IMX7_ECSPI4_ADDR,
17
#include "hw/boards.h"
19
};
18
#include "hw/i2c/i2c.h"
20
19
#include "hw/devices.h"
21
- static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
20
+#include "hw/misc/tmp105.h"
22
+ static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
21
#include "hw/block/flash.h"
23
FSL_IMX7_ECSPI1_IRQ,
22
#include "hw/hw.h"
24
FSL_IMX7_ECSPI2_IRQ,
23
#include "hw/bt.h"
25
FSL_IMX7_ECSPI3_IRQ,
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
26
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
27
FSL_IMX7_I2C4_ADDR,
26
28
};
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
29
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
30
- static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
31
+ static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
32
FSL_IMX7_I2C1_IRQ,
31
}
33
FSL_IMX7_I2C2_IRQ,
32
34
FSL_IMX7_I2C3_IRQ,
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
36
FSL_IMX7_USB3_ADDR,
37
};
38
39
- static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
40
+ static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
41
FSL_IMX7_USB1_IRQ,
42
FSL_IMX7_USB2_IRQ,
43
FSL_IMX7_USB3_IRQ,
44
--
33
--
45
2.17.1
34
2.20.1
46
35
47
36
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
6
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
12
---
7
hw/arm/mcimx7d-sabre.c | 2 --
13
include/hw/devices.h | 3 ---
8
1 file changed, 2 deletions(-)
14
hw/display/tc6393xb.c | 16 ----------------
15
2 files changed, 19 deletions(-)
9
16
10
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
11
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mcimx7d-sabre.c
19
--- a/include/hw/devices.h
13
+++ b/hw/arm/mcimx7d-sabre.c
20
+++ b/include/hw/devices.h
14
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
15
#include "hw/arm/fsl-imx7.h"
22
typedef struct TC6393xbState TC6393xbState;
16
#include "hw/boards.h"
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
17
#include "sysemu/sysemu.h"
24
uint32_t base, qemu_irq irq);
18
-#include "sysemu/device_tree.h"
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
19
#include "qemu/error-report.h"
26
- qemu_irq handler);
20
#include "sysemu/qtest.h"
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
21
-#include "net/net.h"
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
22
29
23
typedef struct {
30
#endif
24
FslIMX7State soc;
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
34
+++ b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
41
- return s->gpio_in;
42
-}
43
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
45
{
46
// TC6393xbState *s = opaque;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
48
// FIXME: how does the chip reflect the GPIO input level change?
49
}
50
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
52
- qemu_irq handler)
53
-{
54
- if (line >= TC6393XB_GPIOS) {
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
56
- return;
57
- }
58
-
59
- s->handler[line] = handler;
60
-}
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
25
--
65
--
26
2.17.1
66
2.20.1
27
67
28
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180627043328.11531-23-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 4 +++
8
include/hw/devices.h | 6 ------
9
target/arm/sve_helper.c | 70 ++++++++++++++++++++++++++++++++++++++
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
target/arm/translate-sve.c | 27 +++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
target/arm/sve.decode | 3 ++
11
hw/display/tc6393xb.c | 2 +-
12
4 files changed, 104 insertions(+)
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
13
15
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
18
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
19
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
void retu_key_event(void *retu, int state);
21
23
22
+DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
-/* tc6393xb.c */
23
+DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
-typedef struct TC6393xbState TC6393xbState;
24
+DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
25
+
27
- uint32_t base, qemu_irq irq);
26
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
27
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
-
28
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
#endif
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
30
index XXXXXXX..XXXXXXX 100644
32
new file mode 100644
31
--- a/target/arm/sve_helper.c
33
index XXXXXXX..XXXXXXX
32
+++ b/target/arm/sve_helper.c
34
--- /dev/null
33
@@ -XXX,XX +XXX,XX @@ DO_FPCMP_PPZ0_ALL(sve_fcmlt0, DO_FCMLT)
35
+++ b/include/hw/display/tc6393xb.h
34
DO_FPCMP_PPZ0_ALL(sve_fcmeq0, DO_FCMEQ)
36
@@ -XXX,XX +XXX,XX @@
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
+/*
37
+/*
119
+ *** SVE floating-point trig multiply-add coefficient
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
120
+ */
46
+ */
121
+
47
+
122
+static bool trans_FTMAD(DisasContext *s, arg_FTMAD *a, uint32_t insn)
48
+#ifndef HW_DISPLAY_TC6393XB_H
123
+{
49
+#define HW_DISPLAY_TC6393XB_H
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
+
50
+
130
+ if (a->esz == 0) {
51
+#include "exec/memory.h"
131
+ return false;
52
+#include "hw/irq.h"
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
+
53
+
145
/*
54
+typedef struct TC6393xbState TC6393xbState;
146
*** SVE Floating Point Accumulating Reduction Group
55
+
147
*/
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
148
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
149
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/sve.decode
63
--- a/hw/arm/tosa.c
151
+++ b/target/arm/sve.decode
64
+++ b/hw/arm/tosa.c
152
@@ -XXX,XX +XXX,XX @@ FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1
65
@@ -XXX,XX +XXX,XX @@
153
FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1
66
#include "hw/hw.h"
154
FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1
67
#include "hw/arm/pxa.h"
155
68
#include "hw/arm/arm.h"
156
+# SVE floating-point trig multiply-add coefficient
69
-#include "hw/devices.h"
157
+FTMAD 01100101 esz:2 010 imm:3 100000 rm:5 rd:5 rn=%reg_movprfx
70
#include "hw/arm/sharpsl.h"
158
+
71
#include "hw/pcmcia.h"
159
### SVE FP Multiply-Add Group
72
#include "hw/boards.h"
160
73
+#include "hw/display/tc6393xb.h"
161
# SVE floating-point multiply-accumulate writing addend
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
84
#include "hw/hw.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/tc6393xb.h"
87
#include "hw/block/flash.h"
88
#include "ui/console.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
162
--
102
--
163
2.17.1
103
2.20.1
164
104
165
105
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Add an entries the Blizzard device in MAINTAINERS.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180627043328.11531-22-richard.henderson@linaro.org
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 42 +++++++++++++++++++++++++++++++++++++
11
include/hw/devices.h | 7 -------
9
target/arm/sve_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
10
target/arm/translate-sve.c | 43 ++++++++++++++++++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
11
target/arm/sve.decode | 10 +++++++++
14
hw/display/blizzard.c | 2 +-
12
4 files changed, 138 insertions(+)
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
13
18
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
21
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
22
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
19
DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
24
/* stellaris_input.c */
20
i64, i64, ptr, ptr, ptr, i32)
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
21
26
22
+DEF_HELPER_FLAGS_5(sve_fcmge0_h, TCG_CALL_NO_RWG,
27
-/* blizzard.c */
23
+ void, ptr, ptr, ptr, ptr, i32)
28
-void *s1d13745_init(qemu_irq gpio_int);
24
+DEF_HELPER_FLAGS_5(sve_fcmge0_s, TCG_CALL_NO_RWG,
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
25
+ void, ptr, ptr, ptr, ptr, i32)
30
-void s1d13745_write_block(void *opaque, int dc,
26
+DEF_HELPER_FLAGS_5(sve_fcmge0_d, TCG_CALL_NO_RWG,
31
- void *buf, size_t len, int pitch);
27
+ void, ptr, ptr, ptr, ptr, i32)
32
-uint16_t s1d13745_read(void *opaque, int dc);
28
+
33
-
29
+DEF_HELPER_FLAGS_5(sve_fcmgt0_h, TCG_CALL_NO_RWG,
34
/* cbus.c */
30
+ void, ptr, ptr, ptr, ptr, i32)
35
typedef struct {
31
+DEF_HELPER_FLAGS_5(sve_fcmgt0_s, TCG_CALL_NO_RWG,
36
qemu_irq clk;
32
+ void, ptr, ptr, ptr, ptr, i32)
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
33
+DEF_HELPER_FLAGS_5(sve_fcmgt0_d, TCG_CALL_NO_RWG,
38
new file mode 100644
34
+ void, ptr, ptr, ptr, ptr, i32)
39
index XXXXXXX..XXXXXXX
35
+
40
--- /dev/null
36
+DEF_HELPER_FLAGS_5(sve_fcmlt0_h, TCG_CALL_NO_RWG,
41
+++ b/include/hw/display/blizzard.h
37
+ void, ptr, ptr, ptr, ptr, i32)
42
@@ -XXX,XX +XXX,XX @@
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
+/*
43
+/*
137
+ *** SVE Floating Point Compare with Zero Group
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
138
+ */
51
+ */
139
+
52
+
140
+static void do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
53
+#ifndef HW_DISPLAY_BLIZZARD_H
141
+ gen_helper_gvec_3_ptr *fn)
54
+#define HW_DISPLAY_BLIZZARD_H
142
+{
143
+ unsigned vsz = vec_full_reg_size(s);
144
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
145
+
55
+
146
+ tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
56
+#include "hw/irq.h"
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
+
57
+
153
+#define DO_PPZ(NAME, name) \
58
+void *s1d13745_init(qemu_irq gpio_int);
154
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
155
+{ \
60
+void s1d13745_write_block(void *opaque, int dc,
156
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
61
+ void *buf, size_t len, int pitch);
157
+ gen_helper_sve_##name##_h, \
62
+uint16_t s1d13745_read(void *opaque, int dc);
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
+
63
+
170
+DO_PPZ(FCMGE_ppz0, fcmge0)
64
+#endif
171
+DO_PPZ(FCMGT_ppz0, fcmgt0)
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
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
66
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/sve.decode
67
--- a/hw/arm/nseries.c
185
+++ b/target/arm/sve.decode
68
+++ b/hw/arm/nseries.c
186
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@
187
# One register operand, with governing predicate, vector element size
70
#include "hw/boards.h"
188
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
71
#include "hw/i2c/i2c.h"
189
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
72
#include "hw/devices.h"
190
+@pd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 . rd:4 &rpr_esz
73
+#include "hw/display/blizzard.h"
191
74
#include "hw/misc/tmp105.h"
192
# One register operand, with governing predicate, no vector element size
75
#include "hw/block/flash.h"
193
@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
76
#include "hw/hw.h"
194
@@ -XXX,XX +XXX,XX @@ FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
195
FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
78
index XXXXXXX..XXXXXXX 100644
196
FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
79
--- a/hw/display/blizzard.c
197
80
+++ b/hw/display/blizzard.c
198
+### SVE FP Compare with Zero Group
81
@@ -XXX,XX +XXX,XX @@
199
+
82
#include "qemu/osdep.h"
200
+FCMGE_ppz0 01100101 .. 0100 00 001 ... ..... 0 .... @pd_pg_rn
83
#include "qemu-common.h"
201
+FCMGT_ppz0 01100101 .. 0100 00 001 ... ..... 1 .... @pd_pg_rn
84
#include "ui/console.h"
202
+FCMLT_ppz0 01100101 .. 0100 01 001 ... ..... 0 .... @pd_pg_rn
85
-#include "hw/devices.h"
203
+FCMLE_ppz0 01100101 .. 0100 01 001 ... ..... 1 .... @pd_pg_rn
86
+#include "hw/display/blizzard.h"
204
+FCMEQ_ppz0 01100101 .. 0100 10 001 ... ..... 0 .... @pd_pg_rn
87
#include "ui/pixel_ops.h"
205
+FCMNE_ppz0 01100101 .. 0100 11 001 ... ..... 0 .... @pd_pg_rn
88
206
+
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
207
### SVE FP Accumulating Reduction Group
90
diff --git a/MAINTAINERS b/MAINTAINERS
208
91
index XXXXXXX..XXXXXXX 100644
209
# SVE floating-point serial reduction (predicated)
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
210
--
107
--
211
2.17.1
108
2.20.1
212
109
213
110
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Message-id: 20180627043328.11531-21-richard.henderson@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/helper.h | 8 +++++++
9
include/hw/devices.h | 14 --------------
9
target/arm/translate-sve.c | 47 ++++++++++++++++++++++++++++++++++++++
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
10
target/arm/vec_helper.c | 20 ++++++++++++++++
11
hw/arm/nseries.c | 1 +
11
target/arm/sve.decode | 5 ++++
12
hw/misc/cbus.c | 2 +-
12
4 files changed, 80 insertions(+)
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
13
16
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
19
--- a/include/hw/devices.h
17
+++ b/target/arm/helper.h
20
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
19
DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
22
/* stellaris_input.c */
20
void, ptr, ptr, ptr, ptr, i32)
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
21
24
22
+DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
-/* cbus.c */
23
+DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
-typedef struct {
24
+DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
- qemu_irq clk;
25
+
28
- qemu_irq dat;
26
+DEF_HELPER_FLAGS_4(gvec_frsqrte_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
- qemu_irq sel;
27
+DEF_HELPER_FLAGS_4(gvec_frsqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
-} CBus;
28
+DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
-CBus *cbus_init(qemu_irq dat_out);
29
+
32
-void cbus_attach(CBus *bus, void *slave_opaque);
30
DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
-
31
DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
-void *retu_init(qemu_irq irq, int vilma);
32
DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
35
-void *tahvo_init(qemu_irq irq, int betty);
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
36
-
34
index XXXXXXX..XXXXXXX 100644
37
-void retu_key_event(void *retu, int state);
35
--- a/target/arm/translate-sve.c
38
-
36
+++ b/target/arm/translate-sve.c
39
#endif
37
@@ -XXX,XX +XXX,XX @@ DO_VPZ(FMAXNMV, fmaxnmv)
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
38
DO_VPZ(FMINV, fminv)
41
new file mode 100644
39
DO_VPZ(FMAXV, fmaxv)
42
index XXXXXXX..XXXXXXX
40
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
41
+/*
46
+/*
42
+ *** SVE Floating Point Unary Operations - Unpredicated Group
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
49
+ * Based on reverse-engineering of a linux driver.
50
+ *
51
+ * Copyright (C) 2008 Nokia Corporation
52
+ * Written by Andrzej Zaborowski
53
+ *
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
43
+ */
56
+ */
44
+
57
+
45
+static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
58
+#ifndef HW_MISC_CBUS_H
46
+{
59
+#define HW_MISC_CBUS_H
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
49
+
60
+
50
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
61
+#include "hw/irq.h"
51
+ vec_full_reg_offset(s, a->rn),
52
+ status, vsz, vsz, 0, fn);
53
+ tcg_temp_free_ptr(status);
54
+}
55
+
62
+
56
+static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
63
+typedef struct {
57
+{
64
+ qemu_irq clk;
58
+ static gen_helper_gvec_2_ptr * const fns[3] = {
65
+ qemu_irq dat;
59
+ gen_helper_gvec_frecpe_h,
66
+ qemu_irq sel;
60
+ gen_helper_gvec_frecpe_s,
67
+} CBus;
61
+ gen_helper_gvec_frecpe_d,
62
+ };
63
+ if (a->esz == 0) {
64
+ return false;
65
+ }
66
+ if (sve_access_check(s)) {
67
+ do_zz_fp(s, a, fns[a->esz - 1]);
68
+ }
69
+ return true;
70
+}
71
+
68
+
72
+static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
69
+CBus *cbus_init(qemu_irq dat_out);
73
+{
70
+void cbus_attach(CBus *bus, void *slave_opaque);
74
+ static gen_helper_gvec_2_ptr * const fns[3] = {
75
+ gen_helper_gvec_frsqrte_h,
76
+ gen_helper_gvec_frsqrte_s,
77
+ gen_helper_gvec_frsqrte_d,
78
+ };
79
+ if (a->esz == 0) {
80
+ return false;
81
+ }
82
+ if (sve_access_check(s)) {
83
+ do_zz_fp(s, a, fns[a->esz - 1]);
84
+ }
85
+ return true;
86
+}
87
+
71
+
88
/*
72
+void *retu_init(qemu_irq irq, int vilma);
89
*** SVE Floating Point Accumulating Reduction Group
73
+void *tahvo_init(qemu_irq irq, int betty);
90
*/
74
+
91
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
92
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/vec_helper.c
80
--- a/hw/arm/nseries.c
94
+++ b/target/arm/vec_helper.c
81
+++ b/hw/arm/nseries.c
95
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
82
@@ -XXX,XX +XXX,XX @@
96
clear_tail(d, opr_sz, simd_maxsz(desc));
83
#include "hw/i2c/i2c.h"
97
}
84
#include "hw/devices.h"
98
85
#include "hw/display/blizzard.h"
99
+#define DO_2OP(NAME, FUNC, TYPE) \
86
+#include "hw/misc/cbus.h"
100
+void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \
87
#include "hw/misc/tmp105.h"
101
+{ \
88
#include "hw/block/flash.h"
102
+ intptr_t i, oprsz = simd_oprsz(desc); \
89
#include "hw/hw.h"
103
+ TYPE *d = vd, *n = vn; \
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
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
91
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/sve.decode
92
--- a/hw/misc/cbus.c
125
+++ b/target/arm/sve.decode
93
+++ b/hw/misc/cbus.c
126
@@ -XXX,XX +XXX,XX @@ FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn
94
@@ -XXX,XX +XXX,XX @@
127
FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn
95
#include "qemu/osdep.h"
128
FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
96
#include "hw/hw.h"
129
97
#include "hw/irq.h"
130
+## SVE Floating Point Unary Operations - Unpredicated Group
98
-#include "hw/devices.h"
131
+
99
+#include "hw/misc/cbus.h"
132
+FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
100
#include "sysemu/sysemu.h"
133
+FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
101
134
+
102
//#define DEBUG
135
### SVE FP Accumulating Reduction Group
103
diff --git a/MAINTAINERS b/MAINTAINERS
136
104
index XXXXXXX..XXXXXXX 100644
137
# SVE floating-point serial reduction (predicated)
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
112
113
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
138
--
115
--
139
2.17.1
116
2.20.1
140
117
141
118
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180627043328.11531-20-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 35 ++++++++++++++++++++++
8
include/hw/devices.h | 3 ---
9
target/arm/sve_helper.c | 61 ++++++++++++++++++++++++++++++++++++++
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
10
target/arm/translate-sve.c | 57 +++++++++++++++++++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
11
target/arm/sve.decode | 8 +++++
11
hw/input/stellaris_input.c | 2 +-
12
4 files changed, 161 insertions(+)
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
13
15
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
18
--- a/include/hw/devices.h
17
+++ b/target/arm/helper-sve.h
19
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
20
void, ptr, ptr, ptr, ptr, i32)
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
21
23
22
+DEF_HELPER_FLAGS_4(sve_faddv_h, TCG_CALL_NO_RWG,
24
-/* stellaris_input.c */
23
+ i64, ptr, ptr, ptr, i32)
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
+DEF_HELPER_FLAGS_4(sve_faddv_s, TCG_CALL_NO_RWG,
26
-
25
+ i64, ptr, ptr, ptr, i32)
27
#endif
26
+DEF_HELPER_FLAGS_4(sve_faddv_d, TCG_CALL_NO_RWG,
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
27
+ i64, ptr, ptr, ptr, i32)
29
new file mode 100644
28
+
30
index XXXXXXX..XXXXXXX
29
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_h, TCG_CALL_NO_RWG,
31
--- /dev/null
30
+ i64, ptr, ptr, ptr, i32)
32
+++ b/include/hw/input/gamepad.h
31
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_s, TCG_CALL_NO_RWG,
33
@@ -XXX,XX +XXX,XX @@
32
+ i64, ptr, ptr, ptr, i32)
34
+/*
33
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_d, TCG_CALL_NO_RWG,
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
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
+ *
36
+ *
71
+ * While it would be possible to write this without the DATA temporary,
37
+ * Copyright (c) 2007 CodeSourcery.
72
+ * it is much simpler to process the predicate register this way.
38
+ * Written by Paul Brook
73
+ * The recursion is bounded to depth 7 (128 fp16 elements), so there's
39
+ *
74
+ * little to gain with a more complex non-recursive form.
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
75
+ */
41
+ * See the COPYING file in the top-level directory.
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
+ */
42
+ */
143
+
43
+
144
+typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr,
44
+#ifndef HW_INPUT_GAMEPAD_H
145
+ TCGv_ptr, TCGv_i32);
45
+#define HW_INPUT_GAMEPAD_H
146
+
46
+
147
+static void do_reduce(DisasContext *s, arg_rpr_esz *a,
47
+#include "hw/irq.h"
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
+
48
+
156
+ temp = tcg_temp_new_i64();
49
+/* stellaris_input.c */
157
+ t_zn = tcg_temp_new_ptr();
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
158
+ t_pg = tcg_temp_new_ptr();
159
+
51
+
160
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, a->rn));
52
+#endif
161
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
162
+ status = get_fpstatus_ptr(a->esz == MO_16);
54
index XXXXXXX..XXXXXXX 100644
163
+
55
--- a/hw/arm/stellaris.c
164
+ fn(temp, t_zn, t_pg, status, t_desc);
56
+++ b/hw/arm/stellaris.c
165
+ tcg_temp_free_ptr(t_zn);
57
@@ -XXX,XX +XXX,XX @@
166
+ tcg_temp_free_ptr(t_pg);
58
#include "hw/sysbus.h"
167
+ tcg_temp_free_ptr(status);
59
#include "hw/ssi/ssi.h"
168
+ tcg_temp_free_i32(t_desc);
60
#include "hw/arm/arm.h"
169
+
61
-#include "hw/devices.h"
170
+ write_fp_dreg(s, a->rd, temp);
62
#include "qemu/timer.h"
171
+ tcg_temp_free_i64(temp);
63
#include "hw/i2c/i2c.h"
172
+}
64
#include "net/net.h"
173
+
65
@@ -XXX,XX +XXX,XX @@
174
+#define DO_VPZ(NAME, name) \
66
#include "sysemu/sysemu.h"
175
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
67
#include "hw/arm/armv7m.h"
176
+{ \
68
#include "hw/char/pl011.h"
177
+ static gen_helper_fp_reduce * const fns[3] = { \
69
+#include "hw/input/gamepad.h"
178
+ gen_helper_sve_##name##_h, \
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
179
+ gen_helper_sve_##name##_s, \
71
#include "hw/misc/unimp.h"
180
+ gen_helper_sve_##name##_d, \
72
#include "cpu.h"
181
+ }; \
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
182
+ if (a->esz == 0) { \
74
index XXXXXXX..XXXXXXX 100644
183
+ return false; \
75
--- a/hw/input/stellaris_input.c
184
+ } \
76
+++ b/hw/input/stellaris_input.c
185
+ if (sve_access_check(s)) { \
77
@@ -XXX,XX +XXX,XX @@
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
*/
78
*/
200
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
201
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
202
--- a/target/arm/sve.decode
88
--- a/MAINTAINERS
203
+++ b/target/arm/sve.decode
89
+++ b/MAINTAINERS
204
@@ -XXX,XX +XXX,XX @@ FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
205
FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
91
L: qemu-arm@nongnu.org
206
FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
92
S: Maintained
207
93
F: hw/*/stellaris*
208
+### SVE FP Fast Reduction Group
94
+F: include/hw/input/gamepad.h
209
+
95
210
+FADDV 01100101 .. 000 000 001 ... ..... ..... @rd_pg_rn
96
Versatile Express
211
+FMAXNMV 01100101 .. 000 100 001 ... ..... ..... @rd_pg_rn
97
M: Peter Maydell <peter.maydell@linaro.org>
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
--
98
--
220
2.17.1
99
2.20.1
221
100
222
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Since uWireSlave is only used in this new header, there is no
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
need to expose it via "qemu/typedefs.h".
5
Message-id: 20180627043328.11531-12-richard.henderson@linaro.org
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 41 +++++++++++++++++++++
11
include/hw/arm/omap.h | 6 +-----
9
target/arm/sve_helper.c | 61 +++++++++++++++++++++++++++++++
12
include/hw/devices.h | 15 ---------------
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 39 ++++++++++++++++++++
14
include/qemu/typedefs.h | 1 -
12
4 files changed, 216 insertions(+)
15
hw/arm/nseries.c | 2 +-
13
16
hw/arm/palm.c | 2 +-
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
hw/input/tsc2005.c | 2 +-
15
index XXXXXXX..XXXXXXX 100644
18
hw/input/tsc210x.c | 4 ++--
16
--- a/target/arm/helper-sve.h
19
MAINTAINERS | 2 ++
17
+++ b/target/arm/helper-sve.h
20
9 files changed, 44 insertions(+), 26 deletions(-)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
21
create mode 100644 include/hw/input/tsc2xxx.h
19
DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
20
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
index XXXXXXX..XXXXXXX 100644
22
+
25
--- a/include/hw/arm/omap.h
23
+DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
26
+++ b/include/hw/arm/omap.h
24
+ void, env, ptr, ptr, ptr, tl, i32)
27
@@ -XXX,XX +XXX,XX @@
25
+DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
28
#include "exec/memory.h"
26
+ void, env, ptr, ptr, ptr, tl, i32)
29
# define hw_omap_h        "omap.h"
27
+DEF_HELPER_FLAGS_6(sve_stss_zsu, TCG_CALL_NO_WG,
30
#include "hw/irq.h"
28
+ void, env, ptr, ptr, ptr, tl, i32)
31
+#include "hw/input/tsc2xxx.h"
29
+
32
#include "target/arm/cpu-qom.h"
30
+DEF_HELPER_FLAGS_6(sve_stbs_zss, TCG_CALL_NO_WG,
33
#include "qemu/log.h"
31
+ void, env, ptr, ptr, ptr, tl, i32)
34
32
+DEF_HELPER_FLAGS_6(sve_sths_zss, TCG_CALL_NO_WG,
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
33
+ void, env, ptr, ptr, ptr, tl, i32)
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
34
+DEF_HELPER_FLAGS_6(sve_stss_zss, TCG_CALL_NO_WG,
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
35
+ void, env, ptr, ptr, ptr, tl, i32)
38
36
+
39
-struct uWireSlave {
37
+DEF_HELPER_FLAGS_6(sve_stbd_zsu, TCG_CALL_NO_WG,
40
- uint16_t (*receive)(void *opaque);
38
+ void, env, ptr, ptr, ptr, tl, i32)
41
- void (*send)(void *opaque, uint16_t data);
39
+DEF_HELPER_FLAGS_6(sve_sthd_zsu, TCG_CALL_NO_WG,
42
- void *opaque;
40
+ void, env, ptr, ptr, ptr, tl, i32)
43
-};
41
+DEF_HELPER_FLAGS_6(sve_stsd_zsu, TCG_CALL_NO_WG,
44
struct omap_uwire_s;
42
+ void, env, ptr, ptr, ptr, tl, i32)
45
void omap_uwire_attach(struct omap_uwire_s *s,
43
+DEF_HELPER_FLAGS_6(sve_stdd_zsu, TCG_CALL_NO_WG,
46
uWireSlave *slave, int chipselect);
44
+ void, env, ptr, ptr, ptr, tl, i32)
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
45
+
48
index XXXXXXX..XXXXXXX 100644
46
+DEF_HELPER_FLAGS_6(sve_stbd_zss, TCG_CALL_NO_WG,
49
--- a/include/hw/devices.h
47
+ void, env, ptr, ptr, ptr, tl, i32)
50
+++ b/include/hw/devices.h
48
+DEF_HELPER_FLAGS_6(sve_sthd_zss, TCG_CALL_NO_WG,
51
@@ -XXX,XX +XXX,XX @@
49
+ void, env, ptr, ptr, ptr, tl, i32)
52
/* Devices that have nowhere better to go. */
50
+DEF_HELPER_FLAGS_6(sve_stsd_zss, TCG_CALL_NO_WG,
53
51
+ void, env, ptr, ptr, ptr, tl, i32)
54
#include "hw/hw.h"
52
+DEF_HELPER_FLAGS_6(sve_stdd_zss, TCG_CALL_NO_WG,
55
-#include "ui/console.h"
53
+ void, env, ptr, ptr, ptr, tl, i32)
56
54
+
57
/* smc91c111.c */
55
+DEF_HELPER_FLAGS_6(sve_stbd_zd, TCG_CALL_NO_WG,
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
56
+ void, env, ptr, ptr, ptr, tl, i32)
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
57
+DEF_HELPER_FLAGS_6(sve_sthd_zd, TCG_CALL_NO_WG,
60
/* lan9118.c */
58
+ void, env, ptr, ptr, ptr, tl, i32)
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
59
+DEF_HELPER_FLAGS_6(sve_stsd_zd, TCG_CALL_NO_WG,
62
60
+ void, env, ptr, ptr, ptr, tl, i32)
63
-/* tsc210x.c */
61
+DEF_HELPER_FLAGS_6(sve_stdd_zd, TCG_CALL_NO_WG,
64
-uWireSlave *tsc2102_init(qemu_irq pint);
62
+ void, env, ptr, ptr, ptr, tl, i32)
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
63
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
64
index XXXXXXX..XXXXXXX 100644
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
65
--- a/target/arm/sve_helper.c
68
-void tsc210x_set_transform(uWireSlave *chip,
66
+++ b/target/arm/sve_helper.c
69
- MouseTransformInfo *info);
67
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
68
addr += 4 * 8;
71
-
69
}
72
-/* tsc2005.c */
70
}
73
-void *tsc2005_init(qemu_irq pintdav);
71
+
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
72
+/* Stores with a vector index. */
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
73
+
76
-
74
+#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
77
#endif
75
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
76
+ target_ulong base, uint32_t desc) \
79
new file mode 100644
77
+{ \
80
index XXXXXXX..XXXXXXX
78
+ intptr_t i, oprsz = simd_oprsz(desc); \
81
--- /dev/null
79
+ unsigned scale = simd_data(desc); \
82
+++ b/include/hw/input/tsc2xxx.h
80
+ uintptr_t ra = GETPC(); \
83
@@ -XXX,XX +XXX,XX @@
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
+/*
84
+/*
151
+ *** SVE gather loads / scatter stores
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
152
+ */
92
+ */
153
+
93
+
154
+static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
94
+#ifndef HW_INPUT_TSC2XXX_H
155
+ TCGv_i64 scalar, gen_helper_gvec_mem_scatter *fn)
95
+#define HW_INPUT_TSC2XXX_H
156
+{
96
+
157
+ unsigned vsz = vec_full_reg_size(s);
97
+#include "hw/irq.h"
158
+ TCGv_i32 desc = tcg_const_i32(simd_desc(vsz, vsz, scale));
98
+#include "ui/console.h"
159
+ TCGv_ptr t_zm = tcg_temp_new_ptr();
99
+
160
+ TCGv_ptr t_pg = tcg_temp_new_ptr();
100
+typedef struct uWireSlave {
161
+ TCGv_ptr t_zt = tcg_temp_new_ptr();
101
+ uint16_t (*receive)(void *opaque);
162
+
102
+ void (*send)(void *opaque, uint16_t data);
163
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
103
+ void *opaque;
164
+ tcg_gen_addi_ptr(t_zm, cpu_env, vec_full_reg_offset(s, zm));
104
+} uWireSlave;
165
+ tcg_gen_addi_ptr(t_zt, cpu_env, vec_full_reg_offset(s, zt));
105
+
166
+ fn(cpu_env, t_zt, t_pg, t_zm, scalar, desc);
106
+/* tsc210x.c */
167
+
107
+uWireSlave *tsc2102_init(qemu_irq pint);
168
+ tcg_temp_free_ptr(t_zt);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
169
+ tcg_temp_free_ptr(t_zm);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
170
+ tcg_temp_free_ptr(t_pg);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
171
+ tcg_temp_free_i32(desc);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
172
+}
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
173
+
113
+
174
+static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
114
+/* tsc2005.c */
175
+{
115
+void *tsc2005_init(qemu_irq pintdav);
176
+ /* Indexed by [xs][msz]. */
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
177
+ static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
178
+ { gen_helper_sve_stbs_zsu,
118
+
179
+ gen_helper_sve_sths_zsu,
119
+#endif
180
+ gen_helper_sve_stss_zsu, },
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
181
+ { gen_helper_sve_stbs_zss,
121
index XXXXXXX..XXXXXXX 100644
182
+ gen_helper_sve_sths_zss,
122
--- a/include/qemu/typedefs.h
183
+ gen_helper_sve_stss_zss, },
123
+++ b/include/qemu/typedefs.h
184
+ };
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
185
+ /* Note that we overload xs=2 to indicate 64-bit offset. */
125
typedef struct Range Range;
186
+ static gen_helper_gvec_mem_scatter * const fn64[3][4] = {
126
typedef struct SHPCDevice SHPCDevice;
187
+ { gen_helper_sve_stbd_zsu,
127
typedef struct SSIBus SSIBus;
188
+ gen_helper_sve_sthd_zsu,
128
-typedef struct uWireSlave uWireSlave;
189
+ gen_helper_sve_stsd_zsu,
129
typedef struct VirtIODevice VirtIODevice;
190
+ gen_helper_sve_stdd_zsu, },
130
typedef struct Visitor Visitor;
191
+ { gen_helper_sve_stbd_zss,
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
192
+ gen_helper_sve_sthd_zss,
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
193
+ gen_helper_sve_stsd_zss,
133
index XXXXXXX..XXXXXXX 100644
194
+ gen_helper_sve_stdd_zss, },
134
--- a/hw/arm/nseries.c
195
+ { gen_helper_sve_stbd_zd,
135
+++ b/hw/arm/nseries.c
196
+ gen_helper_sve_sthd_zd,
136
@@ -XXX,XX +XXX,XX @@
197
+ gen_helper_sve_stsd_zd,
137
#include "ui/console.h"
198
+ gen_helper_sve_stdd_zd, },
138
#include "hw/boards.h"
199
+ };
139
#include "hw/i2c/i2c.h"
200
+ gen_helper_gvec_mem_scatter *fn;
140
-#include "hw/devices.h"
201
+
141
#include "hw/display/blizzard.h"
202
+ if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
142
+#include "hw/input/tsc2xxx.h"
203
+ return false;
143
#include "hw/misc/cbus.h"
204
+ }
144
#include "hw/misc/tmp105.h"
205
+ if (!sve_access_check(s)) {
145
#include "hw/block/flash.h"
206
+ return true;
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
207
+ }
147
index XXXXXXX..XXXXXXX 100644
208
+ switch (a->esz) {
148
--- a/hw/arm/palm.c
209
+ case MO_32:
149
+++ b/hw/arm/palm.c
210
+ fn = fn32[a->xs][a->msz];
150
@@ -XXX,XX +XXX,XX @@
211
+ break;
151
#include "hw/arm/omap.h"
212
+ case MO_64:
152
#include "hw/boards.h"
213
+ fn = fn64[a->xs][a->msz];
153
#include "hw/arm/arm.h"
214
+ break;
154
-#include "hw/devices.h"
215
+ default:
155
+#include "hw/input/tsc2xxx.h"
216
+ g_assert_not_reached();
156
#include "hw/loader.h"
217
+ }
157
#include "exec/address-spaces.h"
218
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
158
#include "cpu.h"
219
+ cpu_reg_sp(s, a->rn), fn);
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
220
+ return true;
160
index XXXXXXX..XXXXXXX 100644
221
+}
161
--- a/hw/input/tsc2005.c
222
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
162
+++ b/hw/input/tsc2005.c
223
index XXXXXXX..XXXXXXX 100644
163
@@ -XXX,XX +XXX,XX @@
224
--- a/target/arm/sve.decode
164
#include "hw/hw.h"
225
+++ b/target/arm/sve.decode
165
#include "qemu/timer.h"
226
@@ -XXX,XX +XXX,XX @@
166
#include "ui/console.h"
227
&rpri_load rd pg rn imm dtype nreg
167
-#include "hw/devices.h"
228
&rprr_store rd pg rn rm msz esz nreg
168
+#include "hw/input/tsc2xxx.h"
229
&rpri_store rd pg rn imm msz esz nreg
169
#include "trace.h"
230
+&rprr_scatter_store rd pg rn rm esz msz xs scale
170
231
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
232
###########################################################################
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
233
# Named instruction formats. These are generally used to
173
index XXXXXXX..XXXXXXX 100644
234
@@ -XXX,XX +XXX,XX @@
174
--- a/hw/input/tsc210x.c
235
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
175
+++ b/hw/input/tsc210x.c
236
@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
176
@@ -XXX,XX +XXX,XX @@
237
&rprr_store nreg=0
177
#include "audio/audio.h"
238
+@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
178
#include "qemu/timer.h"
239
+ &rprr_scatter_store
179
#include "ui/console.h"
240
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
241
###########################################################################
181
-#include "hw/devices.h"
242
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
182
+#include "hw/arm/omap.h" /* For I2SCodec */
243
@@ -XXX,XX +XXX,XX @@ ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
183
+#include "hw/input/tsc2xxx.h"
244
# SVE store multiple structures (scalar plus scalar) (nreg != 0)
184
245
ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
185
#define TSC_DATA_REGISTERS_PAGE        0x0
246
@rprr_store esz=%size_23
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
247
+
187
diff --git a/MAINTAINERS b/MAINTAINERS
248
+# SVE 32-bit scatter store (scalar plus 32-bit scaled offsets)
188
index XXXXXXX..XXXXXXX 100644
249
+# Require msz > 0 && msz <= esz.
189
--- a/MAINTAINERS
250
+ST1_zprz 1110010 .. 11 ..... 100 ... ..... ..... \
190
+++ b/MAINTAINERS
251
+ @rprr_scatter_store xs=0 esz=2 scale=1
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
252
+ST1_zprz 1110010 .. 11 ..... 110 ... ..... ..... \
192
F: hw/misc/cbus.c
253
+ @rprr_scatter_store xs=1 esz=2 scale=1
193
F: hw/timer/twl92230.c
254
+
194
F: include/hw/display/blizzard.h
255
+# SVE 32-bit scatter store (scalar plus 32-bit unscaled offsets)
195
+F: include/hw/input/tsc2xxx.h
256
+# Require msz <= esz.
196
F: include/hw/misc/cbus.h
257
+ST1_zprz 1110010 .. 10 ..... 100 ... ..... ..... \
197
258
+ @rprr_scatter_store xs=0 esz=2 scale=0
198
Palm
259
+ST1_zprz 1110010 .. 10 ..... 110 ... ..... ..... \
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
260
+ @rprr_scatter_store xs=1 esz=2 scale=0
200
S: Odd Fixes
261
+
201
F: hw/arm/palm.c
262
+# SVE 64-bit scatter store (scalar plus 64-bit scaled offset)
202
F: hw/input/tsc210x.c
263
+# Require msz > 0
203
+F: include/hw/input/tsc2xxx.h
264
+ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
204
265
+ @rprr_scatter_store xs=2 esz=3 scale=1
205
Raspberry Pi
266
+
206
M: Peter Maydell <peter.maydell@linaro.org>
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
--
207
--
284
2.17.1
208
2.20.1
285
209
286
210
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180627043328.11531-19-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper.h | 14 +++++++++++
8
include/hw/devices.h | 3 ---
9
target/arm/translate-sve.c | 50 ++++++++++++++++++++++++++++++++++++++
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
10
target/arm/vec_helper.c | 48 ++++++++++++++++++++++++++++++++++++
10
hw/arm/kzm.c | 2 +-
11
target/arm/sve.decode | 19 +++++++++++++++
11
hw/arm/mps2.c | 2 +-
12
4 files changed, 131 insertions(+)
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
13
17
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
20
--- a/include/hw/devices.h
17
+++ b/target/arm/helper.h
21
+++ b/include/hw/devices.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
22
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(gvec_ftsmul_d, TCG_CALL_NO_RWG,
23
/* smc91c111.c */
20
void, ptr, ptr, ptr, ptr, i32)
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
21
25
22
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_h, TCG_CALL_NO_RWG,
26
-/* lan9118.c */
23
+ void, ptr, ptr, ptr, ptr, i32)
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
24
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_s, TCG_CALL_NO_RWG,
28
-
25
+ void, ptr, ptr, ptr, ptr, i32)
29
#endif
26
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_d, TCG_CALL_NO_RWG,
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
27
+ void, ptr, ptr, ptr, ptr, i32)
31
new file mode 100644
28
+
32
index XXXXXXX..XXXXXXX
29
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_h, TCG_CALL_NO_RWG,
33
--- /dev/null
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
34
+++ b/include/hw/net/lan9118.h
31
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
35
@@ -XXX,XX +XXX,XX @@
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
#ifdef TARGET_AARCH64
37
#include "helper-a64.h"
38
#include "helper-sve.h"
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-sve.c
42
+++ b/target/arm/translate-sve.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
44
45
#undef DO_ZZI
46
47
+/*
36
+/*
48
+ *** SVE Floating Point Multiply-Add Indexed Group
37
+ * SMSC LAN9118 Ethernet interface emulation
38
+ *
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
40
+ * Written by Paul Brook
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
49
+ */
44
+ */
50
+
45
+
51
+static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a, uint32_t insn)
46
+#ifndef HW_NET_LAN9118_H
52
+{
47
+#define HW_NET_LAN9118_H
53
+ static gen_helper_gvec_4_ptr * const fns[3] = {
54
+ gen_helper_gvec_fmla_idx_h,
55
+ gen_helper_gvec_fmla_idx_s,
56
+ gen_helper_gvec_fmla_idx_d,
57
+ };
58
+
48
+
59
+ if (sve_access_check(s)) {
49
+#include "hw/irq.h"
60
+ unsigned vsz = vec_full_reg_size(s);
50
+#include "net/net.h"
61
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
62
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
63
+ vec_full_reg_offset(s, a->rn),
64
+ vec_full_reg_offset(s, a->rm),
65
+ vec_full_reg_offset(s, a->ra),
66
+ status, vsz, vsz, (a->index << 1) | a->sub,
67
+ fns[a->esz - 1]);
68
+ tcg_temp_free_ptr(status);
69
+ }
70
+ return true;
71
+}
72
+
51
+
73
+/*
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
74
+ *** SVE Floating Point Multiply Indexed Group
75
+ */
76
+
53
+
77
+static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
54
+#endif
78
+{
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
79
+ static gen_helper_gvec_3_ptr * const fns[3] = {
80
+ gen_helper_gvec_fmul_idx_h,
81
+ gen_helper_gvec_fmul_idx_s,
82
+ gen_helper_gvec_fmul_idx_d,
83
+ };
84
+
85
+ if (sve_access_check(s)) {
86
+ unsigned vsz = vec_full_reg_size(s);
87
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
88
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
89
+ vec_full_reg_offset(s, a->rn),
90
+ vec_full_reg_offset(s, a->rm),
91
+ status, vsz, vsz, a->index, fns[a->esz - 1]);
92
+ tcg_temp_free_ptr(status);
93
+ }
94
+ return true;
95
+}
96
+
97
/*
98
*** SVE Floating Point Accumulating Reduction Group
99
*/
100
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
101
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/vec_helper.c
57
--- a/hw/arm/kzm.c
103
+++ b/target/arm/vec_helper.c
58
+++ b/hw/arm/kzm.c
104
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
59
@@ -XXX,XX +XXX,XX @@
105
60
#include "qemu/error-report.h"
106
#endif
61
#include "exec/address-spaces.h"
107
#undef DO_3OP
62
#include "net/net.h"
108
+
63
-#include "hw/devices.h"
109
+/* For the indexed ops, SVE applies the index per 128-bit vector segment.
64
+#include "hw/net/lan9118.h"
110
+ * For AdvSIMD, there is of course only one such vector segment.
65
#include "hw/char/serial.h"
111
+ */
66
#include "sysemu/qtest.h"
112
+
67
113
+#define DO_MUL_IDX(NAME, TYPE, H) \
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
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
69
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/sve.decode
70
--- a/hw/arm/mps2.c
159
+++ b/target/arm/sve.decode
71
+++ b/hw/arm/mps2.c
160
@@ -XXX,XX +XXX,XX @@
72
@@ -XXX,XX +XXX,XX @@
161
%imm9_16_10 16:s6 10:3
73
#include "hw/timer/cmsdk-apb-timer.h"
162
%size_23 23:2
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
163
%dtype_23_13 23:2 13:2
75
#include "hw/misc/mps2-scc.h"
164
+%index3_22_19 22:1 19:2
76
-#include "hw/devices.h"
165
77
+#include "hw/net/lan9118.h"
166
# A combination of tsz:imm3 -- extract esize.
78
#include "net/net.h"
167
%tszimm_esz 22:2 5:5 !function=tszimm_esz
79
168
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
80
typedef enum MPS2FPGAType {
169
# SVE integer multiply immediate (unpredicated)
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
170
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
82
index XXXXXXX..XXXXXXX 100644
171
83
--- a/hw/arm/realview.c
172
+### SVE FP Multiply-Add Indexed Group
84
+++ b/hw/arm/realview.c
173
+
85
@@ -XXX,XX +XXX,XX @@
174
+# SVE floating-point multiply-add (indexed)
86
#include "hw/arm/arm.h"
175
+FMLA_zzxz 01100100 0.1 .. rm:3 00000 sub:1 rn:5 rd:5 \
87
#include "hw/arm/primecell.h"
176
+ ra=%reg_movprfx index=%index3_22_19 esz=1
88
#include "hw/devices.h"
177
+FMLA_zzxz 01100100 101 index:2 rm:3 00000 sub:1 rn:5 rd:5 \
89
+#include "hw/net/lan9118.h"
178
+ ra=%reg_movprfx esz=2
90
#include "hw/pci/pci.h"
179
+FMLA_zzxz 01100100 111 index:1 rm:4 00000 sub:1 rn:5 rd:5 \
91
#include "net/net.h"
180
+ ra=%reg_movprfx esz=3
92
#include "sysemu/sysemu.h"
181
+
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
182
+### SVE FP Multiply Indexed Group
94
index XXXXXXX..XXXXXXX 100644
183
+
95
--- a/hw/arm/vexpress.c
184
+# SVE floating-point multiply (indexed)
96
+++ b/hw/arm/vexpress.c
185
+FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
97
@@ -XXX,XX +XXX,XX @@
186
+ index=%index3_22_19 esz=1
98
#include "hw/sysbus.h"
187
+FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
99
#include "hw/arm/arm.h"
188
+FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
100
#include "hw/arm/primecell.h"
189
+
101
-#include "hw/devices.h"
190
### SVE FP Accumulating Reduction Group
102
+#include "hw/net/lan9118.h"
191
103
#include "hw/i2c/i2c.h"
192
# SVE floating-point serial reduction (predicated)
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
193
--
119
--
194
2.17.1
120
2.20.1
195
121
196
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Message-id: 20180627043328.11531-13-richard.henderson@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/translate-sve.c | 21 +++++++++++++++++++++
9
include/hw/net/ne2000-isa.h | 6 ++++++
9
target/arm/sve.decode | 23 +++++++++++++++++++++++
10
1 file changed, 6 insertions(+)
10
2 files changed, 44 insertions(+)
11
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
14
--- a/include/hw/net/ne2000-isa.h
15
+++ b/target/arm/translate-sve.c
15
+++ b/include/hw/net/ne2000-isa.h
16
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@
17
cpu_reg_sp(s, a->rn), fn);
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
18
return true;
18
* See the COPYING file in the top-level directory.
19
*/
20
+
21
+#ifndef HW_NET_NE2K_ISA_H
22
+#define HW_NET_NE2K_ISA_H
23
+
24
#include "hw/hw.h"
25
#include "hw/qdev.h"
26
#include "hw/isa/isa.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
29
return d;
19
}
30
}
20
+
31
+
21
+/*
32
+#endif
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
--
33
--
76
2.17.1
34
2.20.1
77
35
78
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180627043328.11531-15-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++++++
8
include/hw/net/lan9118.h | 2 ++
9
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
9
hw/arm/exynos4_boards.c | 3 ++-
10
target/arm/translate-sve.c | 40 ++++++++++++++++-
10
hw/arm/mps2-tz.c | 3 ++-
11
3 files changed, 193 insertions(+), 2 deletions(-)
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
12
13
13
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-sve.h
16
--- a/include/hw/net/lan9118.h
16
+++ b/target/arm/helper-sve.h
17
+++ b/include/hw/net/lan9118.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
18
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
19
#include "hw/irq.h"
19
void, env, ptr, ptr, ptr, tl, i32)
20
#include "net/net.h"
20
21
21
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zsu, TCG_CALL_NO_WG,
22
+#define TYPE_LAN9118 "lan9118"
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
+
23
+
32
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zss, TCG_CALL_NO_WG,
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
33
+ void, env, ptr, ptr, ptr, tl, i32)
25
34
+DEF_HELPER_FLAGS_6(sve_ldffhsu_zss, TCG_CALL_NO_WG,
26
#endif
35
+ void, env, ptr, ptr, ptr, tl, i32)
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
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
28
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/sve_helper.c
29
--- a/hw/arm/exynos4_boards.c
94
+++ b/target/arm/sve_helper.c
30
+++ b/hw/arm/exynos4_boards.c
95
@@ -XXX,XX +XXX,XX @@ DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
31
@@ -XXX,XX +XXX,XX @@
96
DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
32
#include "hw/arm/arm.h"
97
DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
33
#include "exec/address-spaces.h"
98
34
#include "hw/arm/exynos4210.h"
99
+/* First fault loads with a vector index. */
35
+#include "hw/net/lan9118.h"
100
+
36
#include "hw/boards.h"
101
+#ifdef CONFIG_USER_ONLY
37
102
+
38
#undef DEBUG
103
+#define DO_LDFF1_ZPZ(NAME, TYPEE, TYPEI, TYPEM, FN, H) \
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
40
/* This should be a 9215 but the 9118 is close enough */
105
+ target_ulong base, uint32_t desc) \
41
if (nd_table[0].used) {
106
+{ \
42
qemu_check_nic_model(&nd_table[0], "lan9118");
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
43
- dev = qdev_create(NULL, "lan9118");
108
+ unsigned scale = simd_data(desc); \
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
109
+ uintptr_t ra = GETPC(); \
45
qdev_set_nic_properties(dev, &nd_table[0]);
110
+ bool first = true; \
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
111
+ mmap_lock(); \
47
qdev_init_nofail(dev);
112
+ for (i = 0; i < oprsz; i++) { \
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
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
49
index XXXXXXX..XXXXXXX 100644
192
--- a/target/arm/translate-sve.c
50
--- a/hw/arm/mps2-tz.c
193
+++ b/target/arm/translate-sve.c
51
+++ b/hw/arm/mps2-tz.c
194
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
52
@@ -XXX,XX +XXX,XX @@
195
{ gen_helper_sve_ldbsu_zss,
53
#include "hw/arm/armsse.h"
196
gen_helper_sve_ldhsu_zss,
54
#include "hw/dma/pl080.h"
197
gen_helper_sve_ldssu_zss, } } },
55
#include "hw/ssi/pl022.h"
198
- /* TODO fill in first-fault handlers */
56
+#include "hw/net/lan9118.h"
199
+
57
#include "net/net.h"
200
+ { { { gen_helper_sve_ldffbss_zsu,
58
#include "hw/core/split-irq.h"
201
+ gen_helper_sve_ldffhss_zsu,
59
202
+ NULL, },
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
203
+ { gen_helper_sve_ldffbsu_zsu,
61
* except that it doesn't support the checksum-offload feature.
204
+ gen_helper_sve_ldffhsu_zsu,
62
*/
205
+ gen_helper_sve_ldffssu_zsu, } },
63
qemu_check_nic_model(nd, "lan9118");
206
+ { { gen_helper_sve_ldffbss_zss,
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
207
+ gen_helper_sve_ldffhss_zss,
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
208
+ NULL, },
66
qdev_set_nic_properties(mms->lan9118, nd);
209
+ { gen_helper_sve_ldffbsu_zss,
67
qdev_init_nofail(mms->lan9118);
210
+ gen_helper_sve_ldffhsu_zss,
68
211
+ gen_helper_sve_ldffssu_zss, } } }
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
72
+++ b/hw/net/lan9118.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
74
}
212
};
75
};
213
76
214
/* Note that we overload xs=2 to indicate 64-bit offset. */
77
-#define TYPE_LAN9118 "lan9118"
215
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn64[2][3][2][4] = {
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
216
gen_helper_sve_ldhdu_zd,
79
217
gen_helper_sve_ldsdu_zd,
80
typedef struct {
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
--
81
--
249
2.17.1
82
2.20.1
250
83
251
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
This commit finally deletes "hw/devices.h".
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Message-id: 20180627043328.11531-3-richard.henderson@linaro.org
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
---
9
target/arm/helper-sve.h | 40 ++++++++++
10
include/hw/devices.h | 11 -----------
10
target/arm/sve_helper.c | 157 +++++++++++++++++++++++++++++++++++++
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
11
target/arm/translate-sve.c | 69 ++++++++++++++++
12
hw/arm/gumstix.c | 2 +-
12
target/arm/sve.decode | 6 ++
13
hw/arm/integratorcp.c | 2 +-
13
4 files changed, 272 insertions(+)
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
14
21
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
16
index XXXXXXX..XXXXXXX 100644
23
deleted file mode 100644
17
--- a/target/arm/helper-sve.h
24
index XXXXXXX..XXXXXXX
18
+++ b/target/arm/helper-sve.h
25
--- a/include/hw/devices.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+++ /dev/null
20
27
@@ -XXX,XX +XXX,XX @@
21
DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
-#ifndef QEMU_DEVICES_H
22
DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
-#define QEMU_DEVICES_H
23
+
30
-
24
+DEF_HELPER_FLAGS_4(sve_ldff1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
-/* Devices that have nowhere better to go. */
25
+DEF_HELPER_FLAGS_4(sve_ldff1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
-
26
+DEF_HELPER_FLAGS_4(sve_ldff1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
-#include "hw/hw.h"
27
+DEF_HELPER_FLAGS_4(sve_ldff1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
-
28
+DEF_HELPER_FLAGS_4(sve_ldff1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
-/* smc91c111.c */
29
+DEF_HELPER_FLAGS_4(sve_ldff1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
30
+DEF_HELPER_FLAGS_4(sve_ldff1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
-
31
+
38
-#endif
32
+DEF_HELPER_FLAGS_4(sve_ldff1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
33
+DEF_HELPER_FLAGS_4(sve_ldff1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
new file mode 100644
34
+DEF_HELPER_FLAGS_4(sve_ldff1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
index XXXXXXX..XXXXXXX
35
+DEF_HELPER_FLAGS_4(sve_ldff1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
--- /dev/null
36
+DEF_HELPER_FLAGS_4(sve_ldff1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+++ b/include/hw/net/smc91c111.h
37
+
44
@@ -XXX,XX +XXX,XX @@
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
+/*
45
+/*
73
+ * Load contiguous data, first-fault and no-fault.
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
74
+ */
53
+ */
75
+
54
+
76
+#ifdef CONFIG_USER_ONLY
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
77
+
57
+
78
+/* Fault on byte I. All bits in FFR from I are cleared. The vector
58
+#include "hw/irq.h"
79
+ * result from I is CONSTRAINED UNPREDICTABLE; we choose the MERGE
59
+#include "net/net.h"
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
+
60
+
86
+ if (i & 63) {
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
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
+
62
+
183
+#endif
63
+#endif
184
+
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
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
65
index XXXXXXX..XXXXXXX 100644
230
--- a/target/arm/translate-sve.c
66
--- a/hw/arm/gumstix.c
231
+++ b/target/arm/translate-sve.c
67
+++ b/hw/arm/gumstix.c
232
@@ -XXX,XX +XXX,XX @@ static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
68
@@ -XXX,XX +XXX,XX @@
233
}
69
#include "hw/arm/pxa.h"
234
return true;
70
#include "net/net.h"
235
}
71
#include "hw/block/flash.h"
236
+
72
-#include "hw/devices.h"
237
+static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
73
+#include "hw/net/smc91c111.h"
238
+{
74
#include "hw/boards.h"
239
+ static gen_helper_gvec_mem * const fns[16] = {
75
#include "exec/address-spaces.h"
240
+ gen_helper_sve_ldff1bb_r,
76
#include "sysemu/qtest.h"
241
+ gen_helper_sve_ldff1bhu_r,
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
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
78
index XXXXXXX..XXXXXXX 100644
307
--- a/target/arm/sve.decode
79
--- a/hw/arm/integratorcp.c
308
+++ b/target/arm/sve.decode
80
+++ b/hw/arm/integratorcp.c
309
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
81
@@ -XXX,XX +XXX,XX @@
310
# SVE contiguous load (scalar plus scalar)
82
#include "qemu-common.h"
311
LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
83
#include "cpu.h"
312
84
#include "hw/sysbus.h"
313
+# SVE contiguous first-fault load (scalar plus scalar)
85
-#include "hw/devices.h"
314
+LDFF1_zprr 1010010 .... ..... 011 ... ..... ..... @rprr_load_dt nreg=0
86
#include "hw/boards.h"
315
+
87
#include "hw/arm/arm.h"
316
# SVE contiguous load (scalar plus immediate)
88
#include "hw/misc/arm_integrator_debug.h"
317
LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
89
+#include "hw/net/smc91c111.h"
318
90
#include "net/net.h"
319
+# SVE contiguous non-fault load (scalar plus immediate)
91
#include "exec/address-spaces.h"
320
+LDNF1_zpri 1010010 .... 1.... 101 ... ..... ..... @rpri_load_dt nreg=0
92
#include "sysemu/sysemu.h"
321
+
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
322
# SVE contiguous non-temporal load (scalar plus scalar)
94
index XXXXXXX..XXXXXXX 100644
323
# LDNT1B, LDNT1H, LDNT1W, LDNT1D
95
--- a/hw/arm/mainstone.c
324
# SVE load multiple structures (scalar plus scalar)
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
325
--
146
--
326
2.17.1
147
2.20.1
327
148
328
149
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 29 +++++
9
target/arm/sve_helper.c | 211 +++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 65 ++++++++++++
11
target/arm/sve.decode | 38 +++++++
12
4 files changed, 343 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
+
23
+DEF_HELPER_FLAGS_4(sve_st1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
+DEF_HELPER_FLAGS_4(sve_st2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_st3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_st4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+
28
+DEF_HELPER_FLAGS_4(sve_st1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(sve_st2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_st3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(sve_st4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+
33
+DEF_HELPER_FLAGS_4(sve_st1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_4(sve_st2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_st3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_st4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve_st1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_4(sve_st2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_st3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_st4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+
43
+DEF_HELPER_FLAGS_4(sve_st1bh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
44
+DEF_HELPER_FLAGS_4(sve_st1bs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_st1bd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+
47
+DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+
50
+DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve_helper.c
54
+++ b/target/arm/sve_helper.c
55
@@ -XXX,XX +XXX,XX @@ DO_LDNF1(sds_r)
56
DO_LDNF1(dd_r)
57
58
#undef DO_LDNF1
59
+
60
+/*
61
+ * Store contiguous data, protected by a governing predicate.
62
+ */
63
+#define DO_ST1(NAME, FN, TYPEE, TYPEM, H) \
64
+void HELPER(NAME)(CPUARMState *env, void *vg, \
65
+ target_ulong addr, uint32_t desc) \
66
+{ \
67
+ intptr_t i, oprsz = simd_oprsz(desc); \
68
+ intptr_t ra = GETPC(); \
69
+ unsigned rd = simd_data(desc); \
70
+ void *vd = &env->vfp.zregs[rd]; \
71
+ for (i = 0; i < oprsz; ) { \
72
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
73
+ do { \
74
+ if (pg & 1) { \
75
+ TYPEM m = *(TYPEE *)(vd + H(i)); \
76
+ FN(env, addr, m, ra); \
77
+ } \
78
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
79
+ addr += sizeof(TYPEM); \
80
+ } while (i & 15); \
81
+ } \
82
+}
83
+
84
+#define DO_ST1_D(NAME, FN, TYPEM) \
85
+void HELPER(NAME)(CPUARMState *env, void *vg, \
86
+ target_ulong addr, uint32_t desc) \
87
+{ \
88
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
89
+ intptr_t ra = GETPC(); \
90
+ unsigned rd = simd_data(desc); \
91
+ uint64_t *d = &env->vfp.zregs[rd].d[0]; \
92
+ uint8_t *pg = vg; \
93
+ for (i = 0; i < oprsz; i += 1) { \
94
+ if (pg[H1(i)] & 1) { \
95
+ FN(env, addr, d[i], ra); \
96
+ } \
97
+ addr += sizeof(TYPEM); \
98
+ } \
99
+}
100
+
101
+#define DO_ST2(NAME, FN, TYPEE, TYPEM, H) \
102
+void HELPER(NAME)(CPUARMState *env, void *vg, \
103
+ target_ulong addr, uint32_t desc) \
104
+{ \
105
+ intptr_t i, oprsz = simd_oprsz(desc); \
106
+ intptr_t ra = GETPC(); \
107
+ unsigned rd = simd_data(desc); \
108
+ void *d1 = &env->vfp.zregs[rd]; \
109
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
110
+ for (i = 0; i < oprsz; ) { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ if (pg & 1) { \
114
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
115
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
116
+ FN(env, addr, m1, ra); \
117
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
118
+ } \
119
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
120
+ addr += 2 * sizeof(TYPEM); \
121
+ } while (i & 15); \
122
+ } \
123
+}
124
+
125
+#define DO_ST3(NAME, FN, TYPEE, TYPEM, H) \
126
+void HELPER(NAME)(CPUARMState *env, void *vg, \
127
+ target_ulong addr, uint32_t desc) \
128
+{ \
129
+ intptr_t i, oprsz = simd_oprsz(desc); \
130
+ intptr_t ra = GETPC(); \
131
+ unsigned rd = simd_data(desc); \
132
+ void *d1 = &env->vfp.zregs[rd]; \
133
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
134
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
135
+ for (i = 0; i < oprsz; ) { \
136
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
137
+ do { \
138
+ if (pg & 1) { \
139
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
140
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
141
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
142
+ FN(env, addr, m1, ra); \
143
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
144
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
145
+ } \
146
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
147
+ addr += 3 * sizeof(TYPEM); \
148
+ } while (i & 15); \
149
+ } \
150
+}
151
+
152
+#define DO_ST4(NAME, FN, TYPEE, TYPEM, H) \
153
+void HELPER(NAME)(CPUARMState *env, void *vg, \
154
+ target_ulong addr, uint32_t desc) \
155
+{ \
156
+ intptr_t i, oprsz = simd_oprsz(desc); \
157
+ intptr_t ra = GETPC(); \
158
+ unsigned rd = simd_data(desc); \
159
+ void *d1 = &env->vfp.zregs[rd]; \
160
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
161
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
162
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
163
+ for (i = 0; i < oprsz; ) { \
164
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
165
+ do { \
166
+ if (pg & 1) { \
167
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
168
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
169
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
170
+ TYPEM m4 = *(TYPEE *)(d4 + H(i)); \
171
+ FN(env, addr, m1, ra); \
172
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
173
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
174
+ FN(env, addr + 3 * sizeof(TYPEM), m4, ra); \
175
+ } \
176
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
177
+ addr += 4 * sizeof(TYPEM); \
178
+ } while (i & 15); \
179
+ } \
180
+}
181
+
182
+DO_ST1(sve_st1bh_r, cpu_stb_data_ra, uint16_t, uint8_t, H1_2)
183
+DO_ST1(sve_st1bs_r, cpu_stb_data_ra, uint32_t, uint8_t, H1_4)
184
+DO_ST1_D(sve_st1bd_r, cpu_stb_data_ra, uint8_t)
185
+
186
+DO_ST1(sve_st1hs_r, cpu_stw_data_ra, uint32_t, uint16_t, H1_4)
187
+DO_ST1_D(sve_st1hd_r, cpu_stw_data_ra, uint16_t)
188
+
189
+DO_ST1_D(sve_st1sd_r, cpu_stl_data_ra, uint32_t)
190
+
191
+DO_ST1(sve_st1bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
192
+DO_ST2(sve_st2bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
193
+DO_ST3(sve_st3bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
194
+DO_ST4(sve_st4bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
195
+
196
+DO_ST1(sve_st1hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
197
+DO_ST2(sve_st2hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
198
+DO_ST3(sve_st3hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
199
+DO_ST4(sve_st4hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
200
+
201
+DO_ST1(sve_st1ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
202
+DO_ST2(sve_st2ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
203
+DO_ST3(sve_st3ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
204
+DO_ST4(sve_st4ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
205
+
206
+DO_ST1_D(sve_st1dd_r, cpu_stq_data_ra, uint64_t)
207
+
208
+void HELPER(sve_st2dd_r)(CPUARMState *env, void *vg,
209
+ target_ulong addr, uint32_t desc)
210
+{
211
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
212
+ intptr_t ra = GETPC();
213
+ unsigned rd = simd_data(desc);
214
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
215
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
216
+ uint8_t *pg = vg;
217
+
218
+ for (i = 0; i < oprsz; i += 1) {
219
+ if (pg[H1(i)] & 1) {
220
+ cpu_stq_data_ra(env, addr, d1[i], ra);
221
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
222
+ }
223
+ addr += 2 * 8;
224
+ }
225
+}
226
+
227
+void HELPER(sve_st3dd_r)(CPUARMState *env, void *vg,
228
+ target_ulong addr, uint32_t desc)
229
+{
230
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
231
+ intptr_t ra = GETPC();
232
+ unsigned rd = simd_data(desc);
233
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
234
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
235
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
236
+ uint8_t *pg = vg;
237
+
238
+ for (i = 0; i < oprsz; i += 1) {
239
+ if (pg[H1(i)] & 1) {
240
+ cpu_stq_data_ra(env, addr, d1[i], ra);
241
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
242
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
243
+ }
244
+ addr += 3 * 8;
245
+ }
246
+}
247
+
248
+void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
249
+ target_ulong addr, uint32_t desc)
250
+{
251
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
252
+ intptr_t ra = GETPC();
253
+ unsigned rd = simd_data(desc);
254
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
255
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
256
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
257
+ uint64_t *d4 = &env->vfp.zregs[(rd + 3) & 31].d[0];
258
+ uint8_t *pg = vg;
259
+
260
+ for (i = 0; i < oprsz; i += 1) {
261
+ if (pg[H1(i)] & 1) {
262
+ cpu_stq_data_ra(env, addr, d1[i], ra);
263
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
264
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
265
+ cpu_stq_data_ra(env, addr + 24, d4[i], ra);
266
+ }
267
+ addr += 4 * 8;
268
+ }
269
+}
270
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/target/arm/translate-sve.c
273
+++ b/target/arm/translate-sve.c
274
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
275
}
276
return true;
277
}
278
+
279
+static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
280
+ int msz, int esz, int nreg)
281
+{
282
+ static gen_helper_gvec_mem * const fn_single[4][4] = {
283
+ { gen_helper_sve_st1bb_r, gen_helper_sve_st1bh_r,
284
+ gen_helper_sve_st1bs_r, gen_helper_sve_st1bd_r },
285
+ { NULL, gen_helper_sve_st1hh_r,
286
+ gen_helper_sve_st1hs_r, gen_helper_sve_st1hd_r },
287
+ { NULL, NULL,
288
+ gen_helper_sve_st1ss_r, gen_helper_sve_st1sd_r },
289
+ { NULL, NULL, NULL, gen_helper_sve_st1dd_r },
290
+ };
291
+ static gen_helper_gvec_mem * const fn_multiple[3][4] = {
292
+ { gen_helper_sve_st2bb_r, gen_helper_sve_st2hh_r,
293
+ gen_helper_sve_st2ss_r, gen_helper_sve_st2dd_r },
294
+ { gen_helper_sve_st3bb_r, gen_helper_sve_st3hh_r,
295
+ gen_helper_sve_st3ss_r, gen_helper_sve_st3dd_r },
296
+ { gen_helper_sve_st4bb_r, gen_helper_sve_st4hh_r,
297
+ gen_helper_sve_st4ss_r, gen_helper_sve_st4dd_r },
298
+ };
299
+ gen_helper_gvec_mem *fn;
300
+
301
+ if (nreg == 0) {
302
+ /* ST1 */
303
+ fn = fn_single[msz][esz];
304
+ } else {
305
+ /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
306
+ assert(msz == esz);
307
+ fn = fn_multiple[nreg - 1][msz];
308
+ }
309
+ assert(fn != NULL);
310
+ do_mem_zpa(s, zt, pg, addr, fn);
311
+}
312
+
313
+static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a, uint32_t insn)
314
+{
315
+ if (a->rm == 31 || a->msz > a->esz) {
316
+ return false;
317
+ }
318
+ if (sve_access_check(s)) {
319
+ TCGv_i64 addr = new_tmp_a64(s);
320
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
321
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
322
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
323
+ }
324
+ return true;
325
+}
326
+
327
+static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a, uint32_t insn)
328
+{
329
+ if (a->msz > a->esz) {
330
+ return false;
331
+ }
332
+ if (sve_access_check(s)) {
333
+ int vsz = vec_full_reg_size(s);
334
+ int elements = vsz >> a->esz;
335
+ TCGv_i64 addr = new_tmp_a64(s);
336
+
337
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
338
+ (a->imm * elements * (a->nreg + 1)) << a->msz);
339
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
340
+ }
341
+ return true;
342
+}
343
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/arm/sve.decode
346
+++ b/target/arm/sve.decode
347
@@ -XXX,XX +XXX,XX @@
348
%imm7_22_16 22:2 16:5
349
%imm8_16_10 16:5 10:3
350
%imm9_16_10 16:s6 10:3
351
+%size_23 23:2
352
353
# A combination of tsz:imm3 -- extract esize.
354
%tszimm_esz 22:2 5:5 !function=tszimm_esz
355
@@ -XXX,XX +XXX,XX @@
356
&incdec2_pred rd rn pg esz d u
357
&rprr_load rd pg rn rm dtype nreg
358
&rpri_load rd pg rn imm dtype nreg
359
+&rprr_store rd pg rn rm msz esz nreg
360
+&rpri_store rd pg rn imm msz esz nreg
361
362
###########################################################################
363
# Named instruction formats. These are generally used to
364
@@ -XXX,XX +XXX,XX @@
365
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
366
&rpri_load dtype=%msz_dtype
367
368
+# Stores; user must fill in ESZ, MSZ, NREG as needed.
369
+@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
370
+@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
371
+@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
372
+ &rprr_store nreg=0
373
+
374
###########################################################################
375
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
376
377
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
378
# SVE load multiple structures (scalar plus immediate)
379
# LD2B, LD2H, LD2W, LD2D; etc.
380
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
381
+
382
+### SVE Memory Store Group
383
+
384
+# SVE contiguous store (scalar plus immediate)
385
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
386
+ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
387
+ @rpri_store_msz nreg=0
388
+
389
+# SVE contiguous store (scalar plus scalar)
390
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
391
+# Enumerate msz lest we conflict with STR_zri.
392
+ST_zprr 1110010 00 .. ..... 010 ... ..... ..... \
393
+ @rprr_store_esz_n0 msz=0
394
+ST_zprr 1110010 01 .. ..... 010 ... ..... ..... \
395
+ @rprr_store_esz_n0 msz=1
396
+ST_zprr 1110010 10 .. ..... 010 ... ..... ..... \
397
+ @rprr_store_esz_n0 msz=2
398
+ST_zprr 1110010 11 11 ..... 010 ... ..... ..... \
399
+ @rprr_store msz=3 esz=3 nreg=0
400
+
401
+# SVE contiguous non-temporal store (scalar plus immediate) (nreg == 0)
402
+# SVE store multiple structures (scalar plus immediate) (nreg != 0)
403
+ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
404
+ @rpri_store_msz esz=%size_23
405
+
406
+# SVE contiguous non-temporal store (scalar plus scalar) (nreg == 0)
407
+# SVE store multiple structures (scalar plus scalar) (nreg != 0)
408
+ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
409
+ @rprr_store esz=%size_23
410
--
411
2.17.1
412
413
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-sve.c | 52 ++++++++++++++++++++++++++++++++++++++
9
target/arm/sve.decode | 9 +++++++
10
2 files changed, 61 insertions(+)
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
17
return true;
18
}
19
20
+static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int msz)
21
+{
22
+ static gen_helper_gvec_mem * const fns[4] = {
23
+ gen_helper_sve_ld1bb_r, gen_helper_sve_ld1hh_r,
24
+ gen_helper_sve_ld1ss_r, gen_helper_sve_ld1dd_r,
25
+ };
26
+ unsigned vsz = vec_full_reg_size(s);
27
+ TCGv_ptr t_pg;
28
+ TCGv_i32 desc;
29
+
30
+ /* Load the first quadword using the normal predicated load helpers. */
31
+ desc = tcg_const_i32(simd_desc(16, 16, zt));
32
+ t_pg = tcg_temp_new_ptr();
33
+
34
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
35
+ fns[msz](cpu_env, t_pg, addr, desc);
36
+
37
+ tcg_temp_free_ptr(t_pg);
38
+ tcg_temp_free_i32(desc);
39
+
40
+ /* Replicate that first quadword. */
41
+ if (vsz > 16) {
42
+ unsigned dofs = vec_full_reg_offset(s, zt);
43
+ tcg_gen_gvec_dup_mem(4, dofs + 16, dofs, vsz - 16, vsz - 16);
44
+ }
45
+}
46
+
47
+static bool trans_LD1RQ_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
48
+{
49
+ if (a->rm == 31) {
50
+ return false;
51
+ }
52
+ if (sve_access_check(s)) {
53
+ int msz = dtype_msz(a->dtype);
54
+ TCGv_i64 addr = new_tmp_a64(s);
55
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), msz);
56
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
57
+ do_ldrq(s, a->rd, a->pg, addr, msz);
58
+ }
59
+ return true;
60
+}
61
+
62
+static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
63
+{
64
+ if (sve_access_check(s)) {
65
+ TCGv_i64 addr = new_tmp_a64(s);
66
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 16);
67
+ do_ldrq(s, a->rd, a->pg, addr, dtype_msz(a->dtype));
68
+ }
69
+ return true;
70
+}
71
+
72
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
73
int msz, int esz, int nreg)
74
{
75
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/sve.decode
78
+++ b/target/arm/sve.decode
79
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
80
# LD2B, LD2H, LD2W, LD2D; etc.
81
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
82
83
+# SVE load and broadcast quadword (scalar plus scalar)
84
+LD1RQ_zprr 1010010 .. 00 ..... 000 ... ..... ..... \
85
+ @rprr_load_msz nreg=0
86
+
87
+# SVE load and broadcast quadword (scalar plus immediate)
88
+# LD1RQB, LD1RQH, LD1RQS, LD1RQD
89
+LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
90
+ @rpri_load_msz nreg=0
91
+
92
### SVE Memory Store Group
93
94
# SVE contiguous store (scalar plus immediate)
95
--
96
2.17.1
97
98
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
[PMM: fixed typo]
6
Message-id: 20180627043328.11531-6-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 30 +++++++++++++
10
target/arm/sve_helper.c | 38 ++++++++++++++++
11
target/arm/translate-sve.c | 90 ++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 22 ++++++++++
13
4 files changed, 180 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve_scvt_dh, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve_scvt_ss, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_scvt_sd, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_scvt_ds, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve_scvt_dd, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_5(sve_ucvt_hh, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve_ucvt_sh, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve_ucvt_dh, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve_ucvt_ss, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve_ucvt_sd, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
49
+ void, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
+
53
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
56
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve_helper.c
59
+++ b/target/arm/sve_helper.c
60
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
61
return predtest_ones(d, oprsz, esz_mask);
62
}
63
64
+/* Fully general two-operand expander, controlled by a predicate,
65
+ * With the extra float_status parameter.
66
+ */
67
+#define DO_ZPZ_FP(NAME, TYPE, H, OP) \
68
+void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
69
+{ \
70
+ intptr_t i = simd_oprsz(desc); \
71
+ uint64_t *g = vg; \
72
+ do { \
73
+ uint64_t pg = g[(i - 1) >> 6]; \
74
+ do { \
75
+ i -= sizeof(TYPE); \
76
+ if (likely((pg >> (i & 63)) & 1)) { \
77
+ TYPE nn = *(TYPE *)(vn + H(i)); \
78
+ *(TYPE *)(vd + H(i)) = OP(nn, status); \
79
+ } \
80
+ } while (i & 63); \
81
+ } while (i != 0); \
82
+}
83
+
84
+DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
85
+DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
86
+DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
87
+DO_ZPZ_FP(sve_scvt_sd, uint64_t, , int32_to_float64)
88
+DO_ZPZ_FP(sve_scvt_dh, uint64_t, , int64_to_float16)
89
+DO_ZPZ_FP(sve_scvt_ds, uint64_t, , int64_to_float32)
90
+DO_ZPZ_FP(sve_scvt_dd, uint64_t, , int64_to_float64)
91
+
92
+DO_ZPZ_FP(sve_ucvt_hh, uint16_t, H1_2, uint16_to_float16)
93
+DO_ZPZ_FP(sve_ucvt_sh, uint32_t, H1_4, uint32_to_float16)
94
+DO_ZPZ_FP(sve_ucvt_ss, uint32_t, H1_4, uint32_to_float32)
95
+DO_ZPZ_FP(sve_ucvt_sd, uint64_t, , uint32_to_float64)
96
+DO_ZPZ_FP(sve_ucvt_dh, uint64_t, , uint64_to_float16)
97
+DO_ZPZ_FP(sve_ucvt_ds, uint64_t, , uint64_to_float32)
98
+DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
99
+
100
+#undef DO_ZPZ_FP
101
+
102
/*
103
* Load contiguous data, protected by a governing predicate.
104
*/
105
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate-sve.c
108
+++ b/target/arm/translate-sve.c
109
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
110
111
#undef DO_FP3
112
113
+
114
+/*
115
+ *** SVE Floating Point Unary Operations Predicated Group
116
+ */
117
+
118
+static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
119
+ bool is_fp16, gen_helper_gvec_3_ptr *fn)
120
+{
121
+ if (sve_access_check(s)) {
122
+ unsigned vsz = vec_full_reg_size(s);
123
+ TCGv_ptr status = get_fpstatus_ptr(is_fp16);
124
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
125
+ vec_full_reg_offset(s, rn),
126
+ pred_full_reg_offset(s, pg),
127
+ status, vsz, vsz, 0, fn);
128
+ tcg_temp_free_ptr(status);
129
+ }
130
+ return true;
131
+}
132
+
133
+static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
134
+{
135
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
136
+}
137
+
138
+static bool trans_SCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
139
+{
140
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_sh);
141
+}
142
+
143
+static bool trans_SCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
144
+{
145
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_dh);
146
+}
147
+
148
+static bool trans_SCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
149
+{
150
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ss);
151
+}
152
+
153
+static bool trans_SCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
154
+{
155
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ds);
156
+}
157
+
158
+static bool trans_SCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
159
+{
160
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_sd);
161
+}
162
+
163
+static bool trans_SCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
164
+{
165
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_dd);
166
+}
167
+
168
+static bool trans_UCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
169
+{
170
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_hh);
171
+}
172
+
173
+static bool trans_UCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
174
+{
175
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_sh);
176
+}
177
+
178
+static bool trans_UCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
179
+{
180
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_dh);
181
+}
182
+
183
+static bool trans_UCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
184
+{
185
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ss);
186
+}
187
+
188
+static bool trans_UCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
189
+{
190
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ds);
191
+}
192
+
193
+static bool trans_UCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
194
+{
195
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_sd);
196
+}
197
+
198
+static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
199
+{
200
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_dd);
201
+}
202
+
203
/*
204
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
205
*/
206
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/sve.decode
209
+++ b/target/arm/sve.decode
210
@@ -XXX,XX +XXX,XX @@
211
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
212
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
213
214
+# One register operand, with governing predicate, no vector element size
215
+@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
216
+
217
# Two register operands with a 6-bit signed immediate.
218
@rd_rn_i6 ........ ... rn:5 ..... imm:s6 rd:5 &rri
219
220
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
221
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
222
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
223
224
+### SVE FP Unary Operations Predicated Group
225
+
226
+# SVE integer convert to floating-point
227
+SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
228
+SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
229
+SCVTF_dh 01100101 01 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
230
+SCVTF_ss 01100101 10 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
231
+SCVTF_sd 01100101 11 010 00 0 101 ... ..... ..... @rd_pg_rn_e0
232
+SCVTF_ds 01100101 11 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
233
+SCVTF_dd 01100101 11 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
234
+
235
+UCVTF_hh 01100101 01 010 01 1 101 ... ..... ..... @rd_pg_rn_e0
236
+UCVTF_sh 01100101 01 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
237
+UCVTF_dh 01100101 01 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
238
+UCVTF_ss 01100101 10 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
239
+UCVTF_sd 01100101 11 010 00 1 101 ... ..... ..... @rd_pg_rn_e0
240
+UCVTF_ds 01100101 11 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
241
+UCVTF_dd 01100101 11 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
242
+
243
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
244
245
# SVE load predicate register
246
--
247
2.17.1
248
249
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 77 +++++++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 89 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 46 ++++++++++++++++++++
11
target/arm/sve.decode | 17 ++++++++
12
4 files changed, 229 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fadd_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fsub_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fsub_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fsub_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fmul_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fmul_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fmul_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fdiv_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fdiv_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fdiv_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fmin_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fmin_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fmin_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_fmax_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_fmax_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_fmax_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_fminnum_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_fminnum_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, ptr, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_fminnum_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, ptr, ptr, i32)
70
+
71
+DEF_HELPER_FLAGS_6(sve_fmaxnum_h, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, ptr, ptr, i32)
73
+DEF_HELPER_FLAGS_6(sve_fmaxnum_s, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, ptr, ptr, i32)
75
+DEF_HELPER_FLAGS_6(sve_fmaxnum_d, TCG_CALL_NO_RWG,
76
+ void, ptr, ptr, ptr, ptr, ptr, i32)
77
+
78
+DEF_HELPER_FLAGS_6(sve_fabd_h, TCG_CALL_NO_RWG,
79
+ void, ptr, ptr, ptr, ptr, ptr, i32)
80
+DEF_HELPER_FLAGS_6(sve_fabd_s, TCG_CALL_NO_RWG,
81
+ void, ptr, ptr, ptr, ptr, ptr, i32)
82
+DEF_HELPER_FLAGS_6(sve_fabd_d, TCG_CALL_NO_RWG,
83
+ void, ptr, ptr, ptr, ptr, ptr, i32)
84
+
85
+DEF_HELPER_FLAGS_6(sve_fscalbn_h, TCG_CALL_NO_RWG,
86
+ void, ptr, ptr, ptr, ptr, ptr, i32)
87
+DEF_HELPER_FLAGS_6(sve_fscalbn_s, TCG_CALL_NO_RWG,
88
+ void, ptr, ptr, ptr, ptr, ptr, i32)
89
+DEF_HELPER_FLAGS_6(sve_fscalbn_d, TCG_CALL_NO_RWG,
90
+ void, ptr, ptr, ptr, ptr, ptr, i32)
91
+
92
+DEF_HELPER_FLAGS_6(sve_fmulx_h, TCG_CALL_NO_RWG,
93
+ void, ptr, ptr, ptr, ptr, ptr, i32)
94
+DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG,
95
+ void, ptr, ptr, ptr, ptr, ptr, i32)
96
+DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG,
97
+ void, ptr, ptr, ptr, ptr, ptr, i32)
98
+
99
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
100
void, ptr, ptr, ptr, ptr, i32)
101
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
102
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/sve_helper.c
105
+++ b/target/arm/sve_helper.c
106
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
107
return predtest_ones(d, oprsz, esz_mask);
108
}
109
110
+/* Fully general three-operand expander, controlled by a predicate,
111
+ * With the extra float_status parameter.
112
+ */
113
+#define DO_ZPZZ_FP(NAME, TYPE, H, OP) \
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
115
+ void *status, uint32_t desc) \
116
+{ \
117
+ intptr_t i = simd_oprsz(desc); \
118
+ uint64_t *g = vg; \
119
+ do { \
120
+ uint64_t pg = g[(i - 1) >> 6]; \
121
+ do { \
122
+ i -= sizeof(TYPE); \
123
+ if (likely((pg >> (i & 63)) & 1)) { \
124
+ TYPE nn = *(TYPE *)(vn + H(i)); \
125
+ TYPE mm = *(TYPE *)(vm + H(i)); \
126
+ *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \
127
+ } \
128
+ } while (i & 63); \
129
+ } while (i != 0); \
130
+}
131
+
132
+DO_ZPZZ_FP(sve_fadd_h, uint16_t, H1_2, float16_add)
133
+DO_ZPZZ_FP(sve_fadd_s, uint32_t, H1_4, float32_add)
134
+DO_ZPZZ_FP(sve_fadd_d, uint64_t, , float64_add)
135
+
136
+DO_ZPZZ_FP(sve_fsub_h, uint16_t, H1_2, float16_sub)
137
+DO_ZPZZ_FP(sve_fsub_s, uint32_t, H1_4, float32_sub)
138
+DO_ZPZZ_FP(sve_fsub_d, uint64_t, , float64_sub)
139
+
140
+DO_ZPZZ_FP(sve_fmul_h, uint16_t, H1_2, float16_mul)
141
+DO_ZPZZ_FP(sve_fmul_s, uint32_t, H1_4, float32_mul)
142
+DO_ZPZZ_FP(sve_fmul_d, uint64_t, , float64_mul)
143
+
144
+DO_ZPZZ_FP(sve_fdiv_h, uint16_t, H1_2, float16_div)
145
+DO_ZPZZ_FP(sve_fdiv_s, uint32_t, H1_4, float32_div)
146
+DO_ZPZZ_FP(sve_fdiv_d, uint64_t, , float64_div)
147
+
148
+DO_ZPZZ_FP(sve_fmin_h, uint16_t, H1_2, float16_min)
149
+DO_ZPZZ_FP(sve_fmin_s, uint32_t, H1_4, float32_min)
150
+DO_ZPZZ_FP(sve_fmin_d, uint64_t, , float64_min)
151
+
152
+DO_ZPZZ_FP(sve_fmax_h, uint16_t, H1_2, float16_max)
153
+DO_ZPZZ_FP(sve_fmax_s, uint32_t, H1_4, float32_max)
154
+DO_ZPZZ_FP(sve_fmax_d, uint64_t, , float64_max)
155
+
156
+DO_ZPZZ_FP(sve_fminnum_h, uint16_t, H1_2, float16_minnum)
157
+DO_ZPZZ_FP(sve_fminnum_s, uint32_t, H1_4, float32_minnum)
158
+DO_ZPZZ_FP(sve_fminnum_d, uint64_t, , float64_minnum)
159
+
160
+DO_ZPZZ_FP(sve_fmaxnum_h, uint16_t, H1_2, float16_maxnum)
161
+DO_ZPZZ_FP(sve_fmaxnum_s, uint32_t, H1_4, float32_maxnum)
162
+DO_ZPZZ_FP(sve_fmaxnum_d, uint64_t, , float64_maxnum)
163
+
164
+static inline float16 abd_h(float16 a, float16 b, float_status *s)
165
+{
166
+ return float16_abs(float16_sub(a, b, s));
167
+}
168
+
169
+static inline float32 abd_s(float32 a, float32 b, float_status *s)
170
+{
171
+ return float32_abs(float32_sub(a, b, s));
172
+}
173
+
174
+static inline float64 abd_d(float64 a, float64 b, float_status *s)
175
+{
176
+ return float64_abs(float64_sub(a, b, s));
177
+}
178
+
179
+DO_ZPZZ_FP(sve_fabd_h, uint16_t, H1_2, abd_h)
180
+DO_ZPZZ_FP(sve_fabd_s, uint32_t, H1_4, abd_s)
181
+DO_ZPZZ_FP(sve_fabd_d, uint64_t, , abd_d)
182
+
183
+static inline float64 scalbn_d(float64 a, int64_t b, float_status *s)
184
+{
185
+ int b_int = MIN(MAX(b, INT_MIN), INT_MAX);
186
+ return float64_scalbn(a, b_int, s);
187
+}
188
+
189
+DO_ZPZZ_FP(sve_fscalbn_h, int16_t, H1_2, float16_scalbn)
190
+DO_ZPZZ_FP(sve_fscalbn_s, int32_t, H1_4, float32_scalbn)
191
+DO_ZPZZ_FP(sve_fscalbn_d, int64_t, , scalbn_d)
192
+
193
+DO_ZPZZ_FP(sve_fmulx_h, uint16_t, H1_2, helper_advsimd_mulxh)
194
+DO_ZPZZ_FP(sve_fmulx_s, uint32_t, H1_4, helper_vfp_mulxs)
195
+DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd)
196
+
197
+#undef DO_ZPZZ_FP
198
+
199
/* Fully general two-operand expander, controlled by a predicate,
200
* With the extra float_status parameter.
201
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/target/arm/translate-sve.c
205
+++ b/target/arm/translate-sve.c
206
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
207
208
#undef DO_FP3
209
210
+/*
211
+ *** SVE Floating Point Arithmetic - Predicated Group
212
+ */
213
+
214
+static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
215
+ gen_helper_gvec_4_ptr *fn)
216
+{
217
+ if (fn == NULL) {
218
+ return false;
219
+ }
220
+ if (sve_access_check(s)) {
221
+ unsigned vsz = vec_full_reg_size(s);
222
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
223
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
224
+ vec_full_reg_offset(s, a->rn),
225
+ vec_full_reg_offset(s, a->rm),
226
+ pred_full_reg_offset(s, a->pg),
227
+ status, vsz, vsz, 0, fn);
228
+ tcg_temp_free_ptr(status);
229
+ }
230
+ return true;
231
+}
232
+
233
+#define DO_FP3(NAME, name) \
234
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a, uint32_t insn) \
235
+{ \
236
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
237
+ NULL, gen_helper_sve_##name##_h, \
238
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
239
+ }; \
240
+ return do_zpzz_fp(s, a, fns[a->esz]); \
241
+}
242
+
243
+DO_FP3(FADD_zpzz, fadd)
244
+DO_FP3(FSUB_zpzz, fsub)
245
+DO_FP3(FMUL_zpzz, fmul)
246
+DO_FP3(FMIN_zpzz, fmin)
247
+DO_FP3(FMAX_zpzz, fmax)
248
+DO_FP3(FMINNM_zpzz, fminnum)
249
+DO_FP3(FMAXNM_zpzz, fmaxnum)
250
+DO_FP3(FABD, fabd)
251
+DO_FP3(FSCALE, fscalbn)
252
+DO_FP3(FDIV, fdiv)
253
+DO_FP3(FMULX, fmulx)
254
+
255
+#undef DO_FP3
256
257
/*
258
*** SVE Floating Point Unary Operations Predicated Group
259
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/arm/sve.decode
262
+++ b/target/arm/sve.decode
263
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
264
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
265
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
266
267
+### SVE FP Arithmetic Predicated Group
268
+
269
+# SVE floating-point arithmetic (predicated)
270
+FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
271
+FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
272
+FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
273
+FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR
274
+FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
275
+FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
276
+FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
277
+FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
278
+FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm
279
+FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm
280
+FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
281
+FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
282
+FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
283
+
284
### SVE FP Unary Operations Predicated Group
285
286
# SVE integer convert to floating-point
287
--
288
2.17.1
289
290
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
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-24-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 13 +++++++++
9
target/arm/sve_helper.c | 55 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 30 +++++++++++++++++++++
11
target/arm/sve.decode | 8 ++++++
12
4 files changed, 106 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, i64, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_fcvt_sh, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_fcvt_dh, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve_fcvt_hs, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve_fcvt_ds, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+
35
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
38
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/sve_helper.c
41
+++ b/target/arm/sve_helper.c
42
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
43
} while (i != 0); \
44
}
45
46
+/* SVE fp16 conversions always use IEEE mode. Like AdvSIMD, they ignore
47
+ * FZ16. When converting from fp16, this affects flushing input denormals;
48
+ * when converting to fp16, this affects flushing output denormals.
49
+ */
50
+static inline float32 sve_f16_to_f32(float16 f, float_status *fpst)
51
+{
52
+ flag save = get_flush_inputs_to_zero(fpst);
53
+ float32 ret;
54
+
55
+ set_flush_inputs_to_zero(false, fpst);
56
+ ret = float16_to_float32(f, true, fpst);
57
+ set_flush_inputs_to_zero(save, fpst);
58
+ return ret;
59
+}
60
+
61
+static inline float64 sve_f16_to_f64(float16 f, float_status *fpst)
62
+{
63
+ flag save = get_flush_inputs_to_zero(fpst);
64
+ float64 ret;
65
+
66
+ set_flush_inputs_to_zero(false, fpst);
67
+ ret = float16_to_float64(f, true, fpst);
68
+ set_flush_inputs_to_zero(save, fpst);
69
+ return ret;
70
+}
71
+
72
+static inline float16 sve_f32_to_f16(float32 f, float_status *fpst)
73
+{
74
+ flag save = get_flush_to_zero(fpst);
75
+ float16 ret;
76
+
77
+ set_flush_to_zero(false, fpst);
78
+ ret = float32_to_float16(f, true, fpst);
79
+ set_flush_to_zero(save, fpst);
80
+ return ret;
81
+}
82
+
83
+static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
84
+{
85
+ flag save = get_flush_to_zero(fpst);
86
+ float16 ret;
87
+
88
+ set_flush_to_zero(false, fpst);
89
+ ret = float64_to_float16(f, true, fpst);
90
+ set_flush_to_zero(save, fpst);
91
+ return ret;
92
+}
93
+
94
+DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
+DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
97
+DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
98
+DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
99
+DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
100
+
101
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
102
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
103
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
104
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-sve.c
107
+++ b/target/arm/translate-sve.c
108
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
109
return true;
110
}
111
112
+static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
113
+{
114
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
115
+}
116
+
117
+static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
118
+{
119
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
120
+}
121
+
122
+static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
123
+{
124
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
125
+}
126
+
127
+static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
128
+{
129
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hd);
130
+}
131
+
132
+static bool trans_FCVT_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
133
+{
134
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_ds);
135
+}
136
+
137
+static bool trans_FCVT_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
138
+{
139
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sd);
140
+}
141
+
142
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
143
{
144
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
145
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/sve.decode
148
+++ b/target/arm/sve.decode
149
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
150
151
### SVE FP Unary Operations Predicated Group
152
153
+# SVE floating-point convert precision
154
+FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
155
+FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
156
+FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
157
+FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
158
+FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
159
+FCVT_sd 01100101 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
160
+
161
# SVE integer convert to floating-point
162
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
163
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
164
--
165
2.17.1
166
167
diff view generated by jsdifflib
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