1
The following changes since commit adf2e451f357e993f173ba9b4176dbf3e65fee7e:
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-02-26 19:04:47 +0000)
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190228-1
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
8
8
9
for you to fetch changes up to 1c9af3a9e05c1607a36df4943f8f5393d7621a91:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
10
10
11
linux-user: Enable HWCAP_ASIMDFHM, HWCAP_JSCVT (2019-02-28 11:03:05 +0000)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* add MHU and dual-core support to Musca boards
15
* more MVE instructions
16
* refactor some VFP insns to be gated by ID registers
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
17
* Revert "arm: Allow system registers for KVM guests to be changed by QEMU code"
17
* target/arm: Check NaN mode before silencing NaN
18
* Implement ARMv8.2-FHM extension
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
19
* Advertise JSCVT via HWCAP for linux-user
19
* hw/arm: Add basic power management to raspi.
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
20
21
21
----------------------------------------------------------------
22
----------------------------------------------------------------
22
Peter Maydell (11):
23
Joe Komlodi (1):
23
hw/misc/armsse-mhu.c: Model the SSE-200 Message Handling Unit
24
target/arm: Check NaN mode before silencing NaN
24
hw/arm/armsse: Wire up the MHUs
25
target/arm/cpu: Allow init-svtor property to be set after realize
26
target/arm/arm-powerctl: Add new arm_set_cpu_on_and_reset()
27
hw/misc/iotkit-sysctl: Correct typo in INITSVTOR0 register name
28
hw/arm/iotkit-sysctl: Add SSE-200 registers
29
hw/arm/iotkit-sysctl: Implement CPUWAIT and INITSVTOR*
30
hw/arm/armsse: Unify init-svtor and cpuwait handling
31
target/arm: Use MVFR1 feature bits to gate A32/T32 FP16 instructions
32
target/arm: Gate "miscellaneous FP" insns by ID register field
33
Revert "arm: Allow system registers for KVM guests to be changed by QEMU code"
34
25
35
Richard Henderson (5):
26
Maxim Uvarov (1):
36
target/arm: Add helpers for FMLAL
27
hw/gpio/gpio_pwr: use shutdown function for reboot
37
target/arm: Implement FMLAL and FMLSL for aarch64
38
target/arm: Implement VFMAL and VFMSL for aarch32
39
target/arm: Enable ARMv8.2-FHM for -cpu max
40
linux-user: Enable HWCAP_ASIMDFHM, HWCAP_JSCVT
41
28
42
hw/misc/Makefile.objs | 1 +
29
Nolan Leake (1):
43
include/hw/arm/armsse.h | 3 +-
30
hw/arm: Add basic power management to raspi.
44
include/hw/misc/armsse-mhu.h | 44 ++++++
45
include/hw/misc/iotkit-sysctl.h | 25 +++-
46
target/arm/arm-powerctl.h | 16 +++
47
target/arm/cpu.h | 76 +++++++++--
48
target/arm/helper.h | 9 ++
49
hw/arm/armsse.c | 91 +++++++++----
50
hw/misc/armsse-mhu.c | 198 +++++++++++++++++++++++++++
51
hw/misc/iotkit-sysctl.c | 294 ++++++++++++++++++++++++++++++++++++++--
52
linux-user/elfload.c | 2 +
53
target/arm/arm-powerctl.c | 56 ++++++++
54
target/arm/cpu.c | 32 ++++-
55
target/arm/cpu64.c | 2 +
56
target/arm/helper.c | 27 +---
57
target/arm/kvm32.c | 23 +++-
58
target/arm/kvm64.c | 2 -
59
target/arm/machine.c | 2 +-
60
target/arm/translate-a64.c | 49 ++++++-
61
target/arm/translate.c | 180 ++++++++++++++++--------
62
target/arm/vec_helper.c | 148 ++++++++++++++++++++
63
MAINTAINERS | 2 +
64
default-configs/arm-softmmu.mak | 1 +
65
hw/misc/trace-events | 4 +
66
24 files changed, 1139 insertions(+), 148 deletions(-)
67
create mode 100644 include/hw/misc/armsse-mhu.h
68
create mode 100644 hw/misc/armsse-mhu.c
69
31
32
Patrick Venture (2):
33
docs/system/arm: Add quanta-q7l1-bmc reference
34
docs/system/arm: Add quanta-gbs-bmc reference
35
36
Peter Maydell (18):
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
55
56
Philippe Mathieu-Daudé (1):
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
58
59
docs/system/arm/aspeed.rst | 1 +
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
82
diff view generated by jsdifflib
New patch
1
From: Patrick Venture <venture@google.com>
1
2
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
entry.
5
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ etc.
19
AST2400 SoC based machines :
20
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
23
24
AST2500 SoC based machines :
25
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
New patch
1
From: Patrick Venture <venture@google.com>
1
2
3
Add line item reference to quanta-gbs-bmc machine.
4
5
Signed-off-by: Patrick Venture <venture@google.com>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
8
[PMM: fixed underline Sphinx warning]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/nuvoton.rst | 5 +++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
13
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/nuvoton.rst
17
+++ b/docs/system/arm/nuvoton.rst
18
@@ -XXX,XX +XXX,XX @@
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
20
-=====================================================
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
22
+================================================================
23
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
25
designed to be used as Baseboard Management Controllers (BMCs) in various
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
28
Hyperscale applications. The following machines are based on this chip :
29
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
31
- ``quanta-gsj`` Quanta GSJ server BMC
32
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
1
Implement a model of the Message Handling Unit (MHU) found in
1
From: Nolan Leake <nolan@sigbus.net>
2
the Arm SSE-200. This is a simple device which just contains
2
3
some registers which allow the two cores of the SSE-200
3
This is just enough to make reboot and poweroff work. Works for
4
to raise interrupts on each other.
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
do what linux does for reset.
7
8
The watchdog timer functionality is not yet implemented.
9
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190219125808.25174-2-peter.maydell@linaro.org
9
---
18
---
10
hw/misc/Makefile.objs | 1 +
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
11
include/hw/misc/armsse-mhu.h | 44 +++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
12
hw/misc/armsse-mhu.c | 198 ++++++++++++++++++++++++++++++++
21
hw/arm/bcm2835_peripherals.c | 13 ++-
13
MAINTAINERS | 2 +
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
14
default-configs/arm-softmmu.mak | 1 +
23
hw/misc/meson.build | 1 +
15
hw/misc/trace-events | 4 +
24
5 files changed, 204 insertions(+), 2 deletions(-)
16
6 files changed, 250 insertions(+)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
17
create mode 100644 include/hw/misc/armsse-mhu.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
18
create mode 100644 hw/misc/armsse-mhu.c
27
19
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/Makefile.objs
30
--- a/include/hw/arm/bcm2835_peripherals.h
23
+++ b/hw/misc/Makefile.objs
31
+++ b/include/hw/arm/bcm2835_peripherals.h
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
32
@@ -XXX,XX +XXX,XX @@
25
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
33
#include "hw/misc/bcm2835_mphi.h"
26
obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
34
#include "hw/misc/bcm2835_thermal.h"
27
obj-$(CONFIG_ARMSSE_CPUID) += armsse-cpuid.o
35
#include "hw/misc/bcm2835_cprman.h"
28
+obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
36
+#include "hw/misc/bcm2835_powermgt.h"
29
37
#include "hw/sd/sdhci.h"
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
38
#include "hw/sd/bcm2835_sdhost.h"
31
obj-$(CONFIG_AUX) += auxbus.o
39
#include "hw/gpio/bcm2835_gpio.h"
32
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
33
new file mode 100644
50
new file mode 100644
34
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
35
--- /dev/null
52
--- /dev/null
36
+++ b/include/hw/misc/armsse-mhu.h
53
+++ b/include/hw/misc/bcm2835_powermgt.h
37
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
38
+/*
55
+/*
39
+ * ARM SSE-200 Message Handling Unit (MHU)
56
+ * BCM2835 Power Management emulation
40
+ *
57
+ *
41
+ * Copyright (c) 2019 Linaro Limited
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
42
+ * Written by Peter Maydell
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
43
+ *
60
+ *
44
+ * This program is free software; you can redistribute it and/or modify
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * it under the terms of the GNU General Public License version 2 or
62
+ * See the COPYING file in the top-level directory.
46
+ * (at your option) any later version.
47
+ */
63
+ */
48
+
64
+
49
+/*
65
+#ifndef BCM2835_POWERMGT_H
50
+ * This is a model of the Message Handling Unit (MHU) which is part of the
66
+#define BCM2835_POWERMGT_H
51
+ * Arm SSE-200 and documented in
52
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ *
54
+ * QEMU interface:
55
+ * + sysbus MMIO region 0: the system information register bank
56
+ * + sysbus IRQ 0: interrupt for CPU 0
57
+ * + sysbus IRQ 1: interrupt for CPU 1
58
+ */
59
+
60
+#ifndef HW_MISC_SSE_MHU_H
61
+#define HW_MISC_SSE_MHU_H
62
+
67
+
63
+#include "hw/sysbus.h"
68
+#include "hw/sysbus.h"
64
+
69
+#include "qom/object.h"
65
+#define TYPE_ARMSSE_MHU "armsse-mhu"
70
+
66
+#define ARMSSE_MHU(obj) OBJECT_CHECK(ARMSSEMHU, (obj), TYPE_ARMSSE_MHU)
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
67
+
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
68
+typedef struct ARMSSEMHU {
73
+
69
+ /*< private >*/
74
+struct BCM2835PowerMgtState {
70
+ SysBusDevice parent_obj;
75
+ SysBusDevice busdev;
71
+
72
+ /*< public >*/
73
+ MemoryRegion iomem;
76
+ MemoryRegion iomem;
74
+ qemu_irq cpu0irq;
77
+
75
+ qemu_irq cpu1irq;
78
+ uint32_t rstc;
76
+
79
+ uint32_t rsts;
77
+ uint32_t cpu0intr;
80
+ uint32_t wdog;
78
+ uint32_t cpu1intr;
81
+};
79
+} ARMSSEMHU;
80
+
82
+
81
+#endif
83
+#endif
82
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
87
+++ b/hw/arm/bcm2835_peripherals.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
96
}
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
83
new file mode 100644
118
new file mode 100644
84
index XXXXXXX..XXXXXXX
119
index XXXXXXX..XXXXXXX
85
--- /dev/null
120
--- /dev/null
86
+++ b/hw/misc/armsse-mhu.c
121
+++ b/hw/misc/bcm2835_powermgt.c
87
@@ -XXX,XX +XXX,XX @@
122
@@ -XXX,XX +XXX,XX @@
88
+/*
123
+/*
89
+ * ARM SSE-200 Message Handling Unit (MHU)
124
+ * BCM2835 Power Management emulation
90
+ *
125
+ *
91
+ * Copyright (c) 2019 Linaro Limited
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
92
+ * Written by Peter Maydell
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
93
+ *
128
+ *
94
+ * This program is free software; you can redistribute it and/or modify
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
95
+ * it under the terms of the GNU General Public License version 2 or
130
+ * See the COPYING file in the top-level directory.
96
+ * (at your option) any later version.
97
+ */
98
+
99
+/*
100
+ * This is a model of the Message Handling Unit (MHU) which is part of the
101
+ * Arm SSE-200 and documented in
102
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
103
+ */
131
+ */
104
+
132
+
105
+#include "qemu/osdep.h"
133
+#include "qemu/osdep.h"
106
+#include "qemu/log.h"
134
+#include "qemu/log.h"
107
+#include "trace.h"
135
+#include "qemu/module.h"
108
+#include "qapi/error.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
109
+#include "sysemu/sysemu.h"
137
+#include "migration/vmstate.h"
110
+#include "hw/sysbus.h"
138
+#include "sysemu/runstate.h"
111
+#include "hw/registerfields.h"
139
+
112
+#include "hw/misc/armsse-mhu.h"
140
+#define PASSWORD 0x5a000000
113
+
141
+#define PASSWORD_MASK 0xff000000
114
+REG32(CPU0INTR_STAT, 0x0)
142
+
115
+REG32(CPU0INTR_SET, 0x4)
143
+#define R_RSTC 0x1c
116
+REG32(CPU0INTR_CLR, 0x8)
144
+#define V_RSTC_RESET 0x20
117
+REG32(CPU1INTR_STAT, 0x10)
145
+#define R_RSTS 0x20
118
+REG32(CPU1INTR_SET, 0x14)
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
119
+REG32(CPU1INTR_CLR, 0x18)
147
+#define R_WDOG 0x24
120
+REG32(PID4, 0xfd0)
148
+
121
+REG32(PID5, 0xfd4)
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
122
+REG32(PID6, 0xfd8)
150
+ unsigned size)
123
+REG32(PID7, 0xfdc)
151
+{
124
+REG32(PID0, 0xfe0)
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
125
+REG32(PID1, 0xfe4)
153
+ uint32_t res = 0;
126
+REG32(PID2, 0xfe8)
127
+REG32(PID3, 0xfec)
128
+REG32(CID0, 0xff0)
129
+REG32(CID1, 0xff4)
130
+REG32(CID2, 0xff8)
131
+REG32(CID3, 0xffc)
132
+
133
+/* Valid bits in the interrupt registers. If any are set the IRQ is raised */
134
+#define INTR_MASK 0xf
135
+
136
+/* PID/CID values */
137
+static const int armsse_mhu_id[] = {
138
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
139
+ 0x56, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
140
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
141
+};
142
+
143
+static void armsse_mhu_update(ARMSSEMHU *s)
144
+{
145
+ qemu_set_irq(s->cpu0irq, s->cpu0intr != 0);
146
+ qemu_set_irq(s->cpu1irq, s->cpu1intr != 0);
147
+}
148
+
149
+static uint64_t armsse_mhu_read(void *opaque, hwaddr offset, unsigned size)
150
+{
151
+ ARMSSEMHU *s = ARMSSE_MHU(opaque);
152
+ uint64_t r;
153
+
154
+
154
+ switch (offset) {
155
+ switch (offset) {
155
+ case A_CPU0INTR_STAT:
156
+ case R_RSTC:
156
+ r = s->cpu0intr;
157
+ res = s->rstc;
157
+ break;
158
+ break;
158
+
159
+ case R_RSTS:
159
+ case A_CPU1INTR_STAT:
160
+ res = s->rsts;
160
+ r = s->cpu1intr;
161
+ break;
161
+ break;
162
+ case R_WDOG:
162
+
163
+ res = s->wdog;
163
+ case A_PID4 ... A_CID3:
164
+ break;
164
+ r = armsse_mhu_id[(offset - A_PID4) / 4];
165
+
165
+ break;
166
+ default:
166
+
167
+ qemu_log_mask(LOG_UNIMP,
167
+ case A_CPU0INTR_SET:
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
168
+ case A_CPU0INTR_CLR:
169
+ "\n", offset);
169
+ case A_CPU1INTR_SET:
170
+ res = 0;
170
+ case A_CPU1INTR_CLR:
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
171
+ qemu_log_mask(LOG_GUEST_ERROR,
183
+ qemu_log_mask(LOG_GUEST_ERROR,
172
+ "SSE MHU: read of write-only register at offset 0x%x\n",
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
173
+ (int)offset);
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
174
+ r = 0;
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
175
+ break;
212
+ break;
176
+
213
+
177
+ default:
214
+ default:
178
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ qemu_log_mask(LOG_UNIMP,
179
+ "SSE MHU read: bad offset 0x%x\n", (int)offset);
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
180
+ r = 0;
217
+ "\n", offset);
181
+ break;
218
+ break;
182
+ }
219
+ }
183
+ trace_armsse_mhu_read(offset, r, size);
220
+}
184
+ return r;
221
+
185
+}
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
186
+
223
+ .read = bcm2835_powermgt_read,
187
+static void armsse_mhu_write(void *opaque, hwaddr offset,
224
+ .write = bcm2835_powermgt_write,
188
+ uint64_t value, unsigned size)
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
189
+{
226
+ .impl.min_access_size = 4,
190
+ ARMSSEMHU *s = ARMSSE_MHU(opaque);
227
+ .impl.max_access_size = 4,
191
+
228
+};
192
+ trace_armsse_mhu_write(offset, value, size);
229
+
193
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
194
+ switch (offset) {
231
+ .name = TYPE_BCM2835_POWERMGT,
195
+ case A_CPU0INTR_SET:
196
+ s->cpu0intr |= (value & INTR_MASK);
197
+ break;
198
+ case A_CPU0INTR_CLR:
199
+ s->cpu0intr &= ~(value & INTR_MASK);
200
+ break;
201
+ case A_CPU1INTR_SET:
202
+ s->cpu1intr |= (value & INTR_MASK);
203
+ break;
204
+ case A_CPU1INTR_CLR:
205
+ s->cpu1intr &= ~(value & INTR_MASK);
206
+ break;
207
+
208
+ case A_CPU0INTR_STAT:
209
+ case A_CPU1INTR_STAT:
210
+ case A_PID4 ... A_CID3:
211
+ qemu_log_mask(LOG_GUEST_ERROR,
212
+ "SSE MHU: write to read-only register at offset 0x%x\n",
213
+ (int)offset);
214
+ break;
215
+
216
+ default:
217
+ qemu_log_mask(LOG_GUEST_ERROR,
218
+ "SSE MHU write: bad offset 0x%x\n", (int)offset);
219
+ break;
220
+ }
221
+
222
+ armsse_mhu_update(s);
223
+}
224
+
225
+static const MemoryRegionOps armsse_mhu_ops = {
226
+ .read = armsse_mhu_read,
227
+ .write = armsse_mhu_write,
228
+ .endianness = DEVICE_LITTLE_ENDIAN,
229
+ .valid.min_access_size = 4,
230
+ .valid.max_access_size = 4,
231
+};
232
+
233
+static void armsse_mhu_reset(DeviceState *dev)
234
+{
235
+ ARMSSEMHU *s = ARMSSE_MHU(dev);
236
+
237
+ s->cpu0intr = 0;
238
+ s->cpu1intr = 0;
239
+}
240
+
241
+static const VMStateDescription armsse_mhu_vmstate = {
242
+ .name = "armsse-mhu",
243
+ .version_id = 1,
232
+ .version_id = 1,
244
+ .minimum_version_id = 1,
233
+ .minimum_version_id = 1,
245
+ .fields = (VMStateField[]) {
234
+ .fields = (VMStateField[]) {
246
+ VMSTATE_UINT32(cpu0intr, ARMSSEMHU),
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
247
+ VMSTATE_UINT32(cpu1intr, ARMSSEMHU),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
248
+ VMSTATE_END_OF_LIST()
238
+ VMSTATE_END_OF_LIST()
249
+ },
239
+ }
250
+};
240
+};
251
+
241
+
252
+static void armsse_mhu_init(Object *obj)
242
+static void bcm2835_powermgt_init(Object *obj)
253
+{
243
+{
254
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
255
+ ARMSSEMHU *s = ARMSSE_MHU(obj);
245
+
256
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
257
+ memory_region_init_io(&s->iomem, obj, &armsse_mhu_ops,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
258
+ s, "armsse-mhu", 0x1000);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
259
+ sysbus_init_mmio(sbd, &s->iomem);
249
+}
260
+ sysbus_init_irq(sbd, &s->cpu0irq);
250
+
261
+ sysbus_init_irq(sbd, &s->cpu1irq);
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
262
+}
252
+{
263
+
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
264
+static void armsse_mhu_class_init(ObjectClass *klass, void *data)
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
265
+{
262
+{
266
+ DeviceClass *dc = DEVICE_CLASS(klass);
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
267
+
264
+
268
+ dc->reset = armsse_mhu_reset;
265
+ dc->reset = bcm2835_powermgt_reset;
269
+ dc->vmsd = &armsse_mhu_vmstate;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
270
+}
267
+}
271
+
268
+
272
+static const TypeInfo armsse_mhu_info = {
269
+static TypeInfo bcm2835_powermgt_info = {
273
+ .name = TYPE_ARMSSE_MHU,
270
+ .name = TYPE_BCM2835_POWERMGT,
274
+ .parent = TYPE_SYS_BUS_DEVICE,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
275
+ .instance_size = sizeof(ARMSSEMHU),
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
276
+ .instance_init = armsse_mhu_init,
273
+ .class_init = bcm2835_powermgt_class_init,
277
+ .class_init = armsse_mhu_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
278
+};
275
+};
279
+
276
+
280
+static void armsse_mhu_register_types(void)
277
+static void bcm2835_powermgt_register_types(void)
281
+{
278
+{
282
+ type_register_static(&armsse_mhu_info);
279
+ type_register_static(&bcm2835_powermgt_info);
283
+}
280
+}
284
+
281
+
285
+type_init(armsse_mhu_register_types);
282
+type_init(bcm2835_powermgt_register_types)
286
diff --git a/MAINTAINERS b/MAINTAINERS
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
287
index XXXXXXX..XXXXXXX 100644
284
index XXXXXXX..XXXXXXX 100644
288
--- a/MAINTAINERS
285
--- a/hw/misc/meson.build
289
+++ b/MAINTAINERS
286
+++ b/hw/misc/meson.build
290
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysinfo.c
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
291
F: include/hw/misc/iotkit-sysinfo.h
288
'bcm2835_rng.c',
292
F: hw/misc/armsse-cpuid.c
289
'bcm2835_thermal.c',
293
F: include/hw/misc/armsse-cpuid.h
290
'bcm2835_cprman.c',
294
+F: hw/misc/armsse-mhu.c
291
+ 'bcm2835_powermgt.c',
295
+F: include/hw/misc/armsse-mhu.h
292
))
296
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
297
Musca
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
298
M: Peter Maydell <peter.maydell@linaro.org>
299
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
300
index XXXXXXX..XXXXXXX 100644
301
--- a/default-configs/arm-softmmu.mak
302
+++ b/default-configs/arm-softmmu.mak
303
@@ -XXX,XX +XXX,XX @@ CONFIG_IOTKIT_SECCTL=y
304
CONFIG_IOTKIT_SYSCTL=y
305
CONFIG_IOTKIT_SYSINFO=y
306
CONFIG_ARMSSE_CPUID=y
307
+CONFIG_ARMSSE_MHU=y
308
309
CONFIG_VERSATILE=y
310
CONFIG_VERSATILE_PCI=y
311
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
312
index XXXXXXX..XXXXXXX 100644
313
--- a/hw/misc/trace-events
314
+++ b/hw/misc/trace-events
315
@@ -XXX,XX +XXX,XX @@ iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
316
# hw/misc/armsse-cpuid.c
317
armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
318
armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
319
+
320
+# hw/misc/armsse-mhu.c
321
+armsse_mhu_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
322
+armsse_mhu_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
323
--
295
--
324
2.20.1
296
2.20.1
325
297
326
298
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
5
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
44
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
51
1 file changed, 43 insertions(+)
52
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/acceptance/boot_linux_console.py
56
+++ b/tests/acceptance/boot_linux_console.py
57
@@ -XXX,XX +XXX,XX @@
58
from avocado import skip
59
from avocado import skipUnless
60
from avocado_qemu import Test
61
+from avocado_qemu import exec_command
62
from avocado_qemu import exec_command_and_wait_for_pattern
63
from avocado_qemu import interrupt_interactive_console_until_pattern
64
from avocado_qemu import wait_for_console_pattern
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
66
"""
67
self.do_test_arm_raspi2(0)
68
69
+ def test_arm_raspi2_initrd(self):
70
+ """
71
+ :avocado: tags=arch:arm
72
+ :avocado: tags=machine:raspi2
73
+ """
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
81
+
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
84
+ 'arm/rootfs-armv7a.cpio.gz')
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
89
+
90
+ self.vm.set_console()
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
93
+ 'panic=-1 noreboot ' +
94
+ 'dwc_otg.fiq_fsm_enable=0')
95
+ self.vm.add_args('-kernel', kernel_path,
96
+ '-dtb', dtb_path,
97
+ '-initrd', initrd_path,
98
+ '-append', kernel_command_line,
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
114
--
115
2.20.1
116
117
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
Message-id: 20190219222952.22183-6-richard.henderson@linaro.org
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
6
7
To avoid this, we check to see what NaN mode we're running in before we call
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
linux-user/elfload.c | 2 ++
16
target/arm/helper-a64.c | 12 +++++++++---
9
1 file changed, 2 insertions(+)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
10
19
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/linux-user/elfload.c
22
--- a/target/arm/helper-a64.c
14
+++ b/linux-user/elfload.c
23
+++ b/target/arm/helper-a64.c
15
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
25
float16 nan = a;
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
26
if (float16_is_signaling_nan(a, fpst)) {
18
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
27
float_raise(float_flag_invalid, fpst);
19
+ GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
28
- nan = float16_silence_nan(a, fpst);
20
+ GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
29
+ if (!fpst->default_nan_mode) {
21
30
+ nan = float16_silence_nan(a, fpst);
22
#undef GET_FEATURE_ID
31
+ }
23
32
}
33
if (fpst->default_nan_mode) {
34
nan = float16_default_nan(fpst);
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
24
--
127
--
25
2.20.1
128
2.20.1
26
129
27
130
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
5
Message-id: 20190219222952.22183-5-richard.henderson@linaro.org
10
[PMM: tweaked commit message]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/cpu.c | 1 +
13
hw/gpio/gpio_pwr.c | 2 +-
9
target/arm/cpu64.c | 2 ++
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
2 files changed, 3 insertions(+)
11
15
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
18
--- a/hw/gpio/gpio_pwr.c
15
+++ b/target/arm/cpu.c
19
+++ b/hw/gpio/gpio_pwr.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
17
t = cpu->isar.id_isar6;
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
18
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
22
{
19
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
23
if (level) {
20
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
21
cpu->isar.id_isar6 = t;
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
22
26
}
23
t = cpu->id_mmfr4;
27
}
24
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu64.c
27
+++ b/target/arm/cpu64.c
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
30
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
31
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
32
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
33
cpu->isar.id_aa64isar0 = t;
34
35
t = cpu->isar.id_aa64isar1;
36
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
37
u = cpu->isar.id_isar6;
38
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
39
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
40
+ u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
41
cpu->isar.id_isar6 = u;
42
43
/*
44
--
29
--
45
2.20.1
30
2.20.1
46
31
47
32
diff view generated by jsdifflib
1
This reverts commit 823e1b3818f9b10b824ddcd756983b6e2fa68730,
1
In do_ldst(), the calculation of the offset needs to be based on the
2
which introduces a regression running EDK2 guest firmware
2
size of the memory access, not the size of the elements in the
3
under KVM:
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
4
5
5
error: kvm run failed Function not implemented
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
PC=000000013f5a6208 X00=00000000404003c4 X01=000000000000003a
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
X02=0000000000000000 X03=00000000404003c4 X04=0000000000000000
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
8
X05=0000000096000046 X06=000000013d2ef270 X07=000000013e3d1710
9
---
9
X08=09010755ffaf8ba8 X09=ffaf8b9cfeeb5468 X10=feeb546409010756
10
target/arm/translate-mve.c | 17 +++++++++--------
10
X11=09010757ffaf8b90 X12=feeb50680903068b X13=090306a1ffaf8bc0
11
1 file changed, 9 insertions(+), 8 deletions(-)
11
X14=0000000000000000 X15=0000000000000000 X16=000000013f872da0
12
X17=00000000ffffa6ab X18=0000000000000000 X19=000000013f5a92d0
13
X20=000000013f5a7a78 X21=000000000000003a X22=000000013f5a7ab2
14
X23=000000013f5a92e8 X24=000000013f631090 X25=0000000000000010
15
X26=0000000000000100 X27=000000013f89501b X28=000000013e3d14e0
16
X29=000000013e3d12a0 X30=000000013f5a2518 SP=000000013b7be0b0
17
PSTATE=404003c4 -Z-- EL1t
18
12
19
with
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
20
[ 3507.926571] kvm [35042]: load/store instruction decoding not implemented
21
in the host dmesg.
22
23
Revert the change for the moment until we can investigate the
24
cause of the regression.
25
26
Reported-by: Eric Auger <eric.auger@redhat.com>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
29
target/arm/cpu.h | 9 +--------
30
target/arm/helper.c | 27 ++-------------------------
31
target/arm/kvm32.c | 20 ++++++++++++++++++--
32
target/arm/kvm64.c | 2 --
33
target/arm/machine.c | 2 +-
34
5 files changed, 22 insertions(+), 38 deletions(-)
35
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.h
15
--- a/target/arm/translate-mve.c
39
+++ b/target/arm/cpu.h
16
+++ b/target/arm/translate-mve.c
40
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu);
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
41
/**
18
}
42
* write_cpustate_to_list:
43
* @cpu: ARMCPU
44
- * @kvm_sync: true if this is for syncing back to KVM
45
*
46
* For each register listed in the ARMCPU cpreg_indexes list, write
47
* its value from the ARMCPUState structure into the cpreg_values list.
48
* This is used to copy info from TCG's working data structures into
49
* KVM or for outbound migration.
50
*
51
- * @kvm_sync is true if we are doing this in order to sync the
52
- * register state back to KVM. In this case we will only update
53
- * values in the list if the previous list->cpustate sync actually
54
- * successfully wrote the CPU state. Otherwise we will keep the value
55
- * that is in the list.
56
- *
57
* Returns: true if all register values were read correctly,
58
* false if some register was unknown or could not be read.
59
* Note that we do not stop early on failure -- we will attempt
60
* reading all registers in the list.
61
*/
62
-bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
63
+bool write_cpustate_to_list(ARMCPU *cpu);
64
65
#define ARM_CPUID_TI915T 0x54029152
66
#define ARM_CPUID_TI925T 0x54029252
67
diff --git a/target/arm/helper.c b/target/arm/helper.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/helper.c
70
+++ b/target/arm/helper.c
71
@@ -XXX,XX +XXX,XX @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
72
return true;
73
}
19
}
74
20
75
-bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
76
+bool write_cpustate_to_list(ARMCPU *cpu)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
23
+ unsigned msize)
77
{
24
{
78
/* Write the coprocessor state from cpu->env to the (index,value) list. */
25
TCGv_i32 addr;
79
int i;
26
uint32_t offset;
80
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
81
for (i = 0; i < cpu->cpreg_array_len; i++) {
28
return true;
82
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
83
const ARMCPRegInfo *ri;
84
- uint64_t newval;
85
86
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
87
if (!ri) {
88
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
89
if (ri->type & ARM_CP_NO_RAW) {
90
continue;
91
}
92
-
93
- newval = read_raw_cp_reg(&cpu->env, ri);
94
- if (kvm_sync) {
95
- /*
96
- * Only sync if the previous list->cpustate sync succeeded.
97
- * Rather than tracking the success/failure state for every
98
- * item in the list, we just recheck "does the raw write we must
99
- * have made in write_list_to_cpustate() read back OK" here.
100
- */
101
- uint64_t oldval = cpu->cpreg_values[i];
102
-
103
- if (oldval == newval) {
104
- continue;
105
- }
106
-
107
- write_raw_cp_reg(&cpu->env, ri, oldval);
108
- if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
109
- continue;
110
- }
111
-
112
- write_raw_cp_reg(&cpu->env, ri, newval);
113
- }
114
- cpu->cpreg_values[i] = newval;
115
+ cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
116
}
29
}
117
return ok;
30
31
- offset = a->imm << a->size;
32
+ offset = a->imm << msize;
33
if (!a->a) {
34
offset = -offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
38
{ NULL, NULL }
39
};
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
118
}
42
}
119
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
43
120
index XXXXXXX..XXXXXXX 100644
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
121
--- a/target/arm/kvm32.c
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
122
+++ b/target/arm/kvm32.c
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
123
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
47
{ \
124
return ret;
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
50
{ NULL, gen_helper_mve_##ULD }, \
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
125
}
54
}
126
55
127
- write_cpustate_to_list(cpu, true);
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
128
-
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
129
+ /* Note that we do not call write_cpustate_to_list()
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
130
+ * here, so we are only writing the tuple list back to
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
131
+ * KVM. This is safe because nothing can change the
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
132
+ * CPUARMState cp15 fields (in particular gdb accesses cannot)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
133
+ * and so there are no changes to sync. In fact syncing would
62
134
+ * be wrong at this point: for a constant register where TCG and
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
135
+ * KVM disagree about its value, the preceding write_list_to_cpustate()
64
{
136
+ * would not have had any effect on the CPUARMState value (since the
137
+ * register is read-only), and a write_cpustate_to_list() here would
138
+ * then try to write the TCG value back into KVM -- this would either
139
+ * fail or incorrectly change the value the guest sees.
140
+ *
141
+ * If we ever want to allow the user to modify cp15 registers via
142
+ * the gdb stub, we would need to be more clever here (for instance
143
+ * tracking the set of registers kvm_arch_get_registers() successfully
144
+ * managed to update the CPUARMState with, and only allowing those
145
+ * to be written back up into the kernel).
146
+ */
147
if (!write_list_to_kvmstate(cpu, level)) {
148
return EINVAL;
149
}
150
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/arm/kvm64.c
153
+++ b/target/arm/kvm64.c
154
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
155
return ret;
156
}
157
158
- write_cpustate_to_list(cpu, true);
159
-
160
if (!write_list_to_kvmstate(cpu, level)) {
161
return EINVAL;
162
}
163
diff --git a/target/arm/machine.c b/target/arm/machine.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/machine.c
166
+++ b/target/arm/machine.c
167
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
168
abort();
169
}
170
} else {
171
- if (!write_cpustate_to_list(cpu, false)) {
172
+ if (!write_cpustate_to_list(cpu)) {
173
/* This should never fail. */
174
abort();
175
}
176
--
65
--
177
2.20.1
66
2.20.1
178
67
179
68
diff view generated by jsdifflib
New patch
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
1
9
10
In particular, fixing the second of these allows us to recast
11
the implementation to avoid 128-bit arithmetic entirely.
12
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
20
---
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
22
1 file changed, 21 insertions(+), 17 deletions(-)
23
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/mve_helper.c
27
+++ b/target/arm/mve_helper.c
28
@@ -XXX,XX +XXX,XX @@
29
*/
30
31
#include "qemu/osdep.h"
32
-#include "qemu/int128.h"
33
#include "cpu.h"
34
#include "internals.h"
35
#include "vec_internal.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
38
39
/*
40
- * Rounding multiply add long dual accumulate high: we must keep
41
- * a 72-bit internal accumulator value and return the top 64 bits.
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
82
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
87
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
98
--
99
2.20.1
100
101
diff view generated by jsdifflib
New patch
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
20
return opc | s->be_data;
21
}
22
23
+/**
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
25
+ *
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
120
}
121
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
123
+{
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
181
{
182
--
183
2.20.1
184
185
diff view generated by jsdifflib
1
Create and connect the MHUs in the SSE-200.
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
2
5
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190219125808.25174-3-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
6
---
9
---
7
include/hw/arm/armsse.h | 3 ++-
10
target/arm/translate.h | 3 +-
8
hw/arm/armsse.c | 40 ++++++++++++++++++++++++++++++----------
11
target/arm/translate-a64.c | 86 ++++----------------------------------
9
2 files changed, 32 insertions(+), 11 deletions(-)
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
10
14
11
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/arm/armsse.h
17
--- a/target/arm/translate.h
14
+++ b/include/hw/arm/armsse.h
18
+++ b/target/arm/translate.h
15
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
16
#include "hw/misc/iotkit-sysctl.h"
20
* VMVN and VBIC (when cmode < 14 && op == 1).
17
#include "hw/misc/iotkit-sysinfo.h"
21
*
18
#include "hw/misc/armsse-cpuid.h"
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
19
+#include "hw/misc/armsse-mhu.h"
23
- * callers must catch this.
20
#include "hw/misc/unimp.h"
24
+ * callers must catch this; we return the 64-bit constant value defined
21
#include "hw/or-irq.h"
25
+ * for AArch64.
22
#include "hw/core/split-irq.h"
26
*
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
24
IoTKitSysCtl sysctl;
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
25
IoTKitSysCtl sysinfo;
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
26
27
- UnimplementedDeviceState mhu[2];
28
+ ARMSSEMHU mhu[2];
29
UnimplementedDeviceState ppu[NUM_PPUS];
30
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
31
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
32
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
33
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/armsse.c
31
--- a/target/arm/translate-a64.c
35
+++ b/hw/arm/armsse.c
32
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
37
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
34
{
38
if (info->has_mhus) {
35
int rd = extract32(insn, 0, 5);
39
sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
36
int cmode = extract32(insn, 12, 4);
40
- TYPE_UNIMPLEMENTED_DEVICE);
37
- int cmode_3_1 = extract32(cmode, 1, 3);
41
+ TYPE_ARMSSE_MHU);
38
- int cmode_0 = extract32(cmode, 0, 1);
42
sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
39
int o2 = extract32(insn, 11, 1);
43
- TYPE_UNIMPLEMENTED_DEVICE);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
44
+ TYPE_ARMSSE_MHU);
41
bool is_neg = extract32(insn, 29, 1);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
43
return;
45
}
44
}
46
if (info->has_ppus) {
45
47
for (i = 0; i < info->num_cpus; i++) {
46
- /* See AdvSIMDExpandImm() in ARM ARM */
48
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
49
}
130
}
50
131
51
if (info->has_mhus) {
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
52
- for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
53
- char *name;
134
index XXXXXXX..XXXXXXX 100644
54
- char *port;
135
--- a/target/arm/translate.c
55
+ /*
136
+++ b/target/arm/translate.c
56
+ * An SSE-200 with only one CPU should have only one MHU created,
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
57
+ * with the region where the second MHU usually is being RAZ/WI.
138
case 14:
58
+ * We don't implement that SSE-200 config; if we want to support
139
if (op) {
59
+ * it then this code needs to be enhanced to handle creating the
140
/*
60
+ * RAZ/WI region instead of the second MHU.
141
- * This is the only case where the top and bottom 32 bits
61
+ */
142
- * of the encoded constant differ.
62
+ assert(info->num_cpus == ARRAY_SIZE(s->mhu));
143
+ * This and cmode == 15 op == 1 are the only cases where
63
+
144
+ * the top and bottom 32 bits of the encoded constant differ.
64
+ for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
145
*/
65
+ char *port;
146
uint64_t imm64 = 0;
66
+ int cpunum;
147
int n;
67
+ SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
68
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
69
- name = g_strdup_printf("MHU%d", i);
150
break;
70
- qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
151
case 15:
71
- qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
152
+ if (op) {
72
object_property_set_bool(OBJECT(&s->mhu[i]), true,
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
73
"realized", &err);
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
74
- g_free(name);
155
+ if (imm & 0x80) {
75
if (err) {
156
+ imm64 |= 0x8000000000000000ULL;
76
error_propagate(errp, err);
77
return;
78
}
79
port = g_strdup_printf("port[%d]", i + 3);
80
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
81
+ mr = sysbus_mmio_get_region(mhu_sbd, 0);
82
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
83
port, &err);
84
g_free(port);
85
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
86
error_propagate(errp, err);
87
return;
88
}
89
+
90
+ /*
91
+ * Each MHU has an irq line for each CPU:
92
+ * MHU 0 irq line 0 -> CPU 0 IRQ 6
93
+ * MHU 0 irq line 1 -> CPU 1 IRQ 6
94
+ * MHU 1 irq line 0 -> CPU 0 IRQ 7
95
+ * MHU 1 irq line 1 -> CPU 1 IRQ 7
96
+ */
97
+ for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
98
+ DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
99
+
100
+ sysbus_connect_irq(mhu_sbd, cpunum,
101
+ qdev_get_gpio_in(cpudev, 6 + i));
102
+ }
157
+ }
103
}
158
+ if (imm & 0x40) {
104
}
159
+ imm64 |= 0x3fc0000000000000ULL;
105
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
106
--
168
--
107
2.20.1
169
2.20.1
108
170
109
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
(We can't replace the other use of bitfield_replicate() in this file,
4
Message-id: 20190219222952.22183-3-richard.henderson@linaro.org
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
and 4 bit elements, which dup_const() cannot.)
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
7
---
11
---
8
target/arm/cpu.h | 5 ++++
12
target/arm/translate-a64.c | 2 +-
9
target/arm/translate-a64.c | 49 +++++++++++++++++++++++++++++++++++++-
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
2 files changed, 53 insertions(+), 1 deletion(-)
11
14
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
17
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
18
}
19
20
+static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
21
+{
22
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
23
+}
24
+
25
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
26
{
27
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
33
if (!fp_access_check(s)) {
20
/* FMOV (vector, immediate) - half-precision */
34
return;
21
imm = vfp_expand_imm(MO_16, abcdefgh);
35
}
22
/* now duplicate across the lanes */
36
-
23
- imm = bitfield_replicate(imm, 16);
37
handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
24
+ imm = dup_const(MO_16, imm);
38
return;
25
} else {
39
+
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
40
+ case 0x1d: /* FMLAL */
41
+ case 0x3d: /* FMLSL */
42
+ case 0x59: /* FMLAL2 */
43
+ case 0x79: /* FMLSL2 */
44
+ if (size & 1 || !dc_isar_feature(aa64_fhm, s)) {
45
+ unallocated_encoding(s);
46
+ return;
47
+ }
48
+ if (fp_access_check(s)) {
49
+ int is_s = extract32(insn, 23, 1);
50
+ int is_2 = extract32(insn, 29, 1);
51
+ int data = (is_2 << 1) | is_s;
52
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
53
+ vec_full_reg_offset(s, rn),
54
+ vec_full_reg_offset(s, rm), cpu_env,
55
+ is_q ? 16 : 8, vec_full_reg_size(s),
56
+ data, gen_helper_gvec_fmlal_a64);
57
+ }
58
+ return;
59
+
60
default:
61
unallocated_encoding(s);
62
return;
63
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
64
}
65
is_fp = 2;
66
break;
67
+ case 0x00: /* FMLAL */
68
+ case 0x04: /* FMLSL */
69
+ case 0x18: /* FMLAL2 */
70
+ case 0x1c: /* FMLSL2 */
71
+ if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_fhm, s)) {
72
+ unallocated_encoding(s);
73
+ return;
74
+ }
75
+ size = MO_16;
76
+ /* is_fp, but we pass cpu_env not fp_status. */
77
+ break;
78
default:
79
unallocated_encoding(s);
80
return;
81
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
82
tcg_temp_free_ptr(fpst);
83
}
84
return;
85
+
86
+ case 0x00: /* FMLAL */
87
+ case 0x04: /* FMLSL */
88
+ case 0x18: /* FMLAL2 */
89
+ case 0x1c: /* FMLSL2 */
90
+ {
91
+ int is_s = extract32(opcode, 2, 1);
92
+ int is_2 = u;
93
+ int data = (index << 2) | (is_2 << 1) | is_s;
94
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
95
+ vec_full_reg_offset(s, rn),
96
+ vec_full_reg_offset(s, rm), cpu_env,
97
+ is_q ? 16 : 8, vec_full_reg_size(s),
98
+ data, gen_helper_gvec_fmlal_idx_a64);
99
+ }
100
+ return;
101
}
27
}
102
103
if (size == 3) {
104
--
28
--
105
2.20.1
29
2.20.1
106
30
107
31
diff view generated by jsdifflib
New patch
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 4 +++
11
target/arm/mve.decode | 17 +++++++++++++
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
15
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
31
+++ b/target/arm/mve.decode
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
94
+
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
121
}
122
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
124
+{
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
127
+
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
171
--
172
2.20.1
173
174
diff view generated by jsdifflib
New patch
1
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
and VQSHLU.
3
4
The size-and-immediate encoding here is the same as Neon, and we
5
handle it the same way neon-dp.decode does.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
10
---
11
target/arm/helper-mve.h | 16 +++++++++++
12
target/arm/mve.decode | 23 +++++++++++++++
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
4 files changed, 147 insertions(+)
16
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
+
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
177
+{
178
+ TCGv_ptr qd, qm;
179
+ int shift = a->shift;
180
+
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
189
+
190
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
192
+ * which permits a negative shift count to indicate a right-shift,
193
+ * we must negate the shift count.
194
+ */
195
+ if (negateshift) {
196
+ shift = -shift;
197
+ }
198
+
199
+ qd = mve_qreg_ptr(a->qd);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
206
+}
207
+
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
210
+ { \
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
212
+ gen_helper_mve_##FN##b, \
213
+ gen_helper_mve_##FN##h, \
214
+ gen_helper_mve_##FN##w, \
215
+ NULL, \
216
+ }; \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
218
+ }
219
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
224
--
225
2.20.1
226
227
diff view generated by jsdifflib
1
There is a set of VFP instructions which we implement in
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
disas_vfp_v8_insn() and gate on the ARM_FEATURE_V8 bit.
2
VRSHRI. As with Neon, we implement these by using helper functions
3
These were all first introduced in v8 for A-profile, but in
3
which perform left shifts but allow negative shift counts to indicate
4
M-profile they appeared in v7M. Gate them on the MVFR2
4
right shifts.
5
FPMisc field instead, and rename the function appropriately.
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190222170936.13268-3-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
10
---
9
---
11
target/arm/cpu.h | 20 ++++++++++++++++++++
10
target/arm/helper-mve.h | 12 ++++++++++++
12
target/arm/translate.c | 25 +++++++++++++------------
11
target/arm/translate.h | 20 ++++++++++++++++++++
13
2 files changed, 33 insertions(+), 12 deletions(-)
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
14
17
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
20
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/cpu.h
21
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
20
return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
50
return x * 2 + 1;
21
}
51
}
22
52
23
+static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
53
+static inline int rsub_64(DisasContext *s, int x)
24
+{
54
+{
25
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
55
+ return 64 - x;
26
+}
56
+}
27
+
57
+
28
+static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
58
+static inline int rsub_32(DisasContext *s, int x)
29
+{
59
+{
30
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
60
+ return 32 - x;
31
+}
61
+}
32
+
62
+
33
+static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
63
+static inline int rsub_16(DisasContext *s, int x)
34
+{
64
+{
35
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
65
+ return 16 - x;
36
+}
66
+}
37
+
67
+
38
+static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
68
+static inline int rsub_8(DisasContext *s, int x)
39
+{
69
+{
40
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
70
+ return 8 - x;
41
+}
71
+}
42
+
72
+
43
/*
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
44
* 64-bit feature tests via id registers.
74
{
45
*/
75
return (dc->features & (1ULL << feature)) != 0;
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
47
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.c
78
--- a/target/arm/mve.decode
49
+++ b/target/arm/translate.c
79
+++ b/target/arm/mve.decode
50
@@ -XXX,XX +XXX,XX @@ static const uint8_t fp_decode_rm[] = {
80
@@ -XXX,XX +XXX,XX @@
51
FPROUNDING_NEGINF,
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
52
};
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
53
83
54
-static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
55
+static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
88
+
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
90
+ size=0 shift=%rshift_i3
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
92
+ size=1 shift=%rshift_i4
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
94
+ size=2 shift=%rshift_i5
95
+
96
# Vector loads and stores
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
163
}
164
165
-static inline int rsub_64(DisasContext *s, int x)
166
-{
167
- return 64 - x;
168
-}
169
-
170
-static inline int rsub_32(DisasContext *s, int x)
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
56
{
184
{
57
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
58
59
- if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
60
- return 1;
61
- }
62
-
63
if (dp) {
64
VFP_DREG_D(rd, insn);
65
VFP_DREG_N(rn, insn);
66
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
67
rm = VFP_SREG_M(insn);
68
}
69
70
- if ((insn & 0x0f800e50) == 0x0e000a00) {
71
+ if ((insn & 0x0f800e50) == 0x0e000a00 && dc_isar_feature(aa32_vsel, s)) {
72
return handle_vsel(insn, rd, rn, rm, dp);
73
- } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
74
+ } else if ((insn & 0x0fb00e10) == 0x0e800a00 &&
75
+ dc_isar_feature(aa32_vminmaxnm, s)) {
76
return handle_vminmaxnm(insn, rd, rn, rm, dp);
77
- } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
78
+ } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40 &&
79
+ dc_isar_feature(aa32_vrint, s)) {
80
/* VRINTA, VRINTN, VRINTP, VRINTM */
81
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
82
return handle_vrint(insn, rd, rm, dp, rounding);
83
- } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
84
+ } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
85
+ dc_isar_feature(aa32_vcvt_dr, s)) {
86
/* VCVTA, VCVTN, VCVTP, VCVTM */
87
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
88
return handle_vcvt(insn, rd, rm, dp, rounding);
89
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
90
}
91
92
if (extract32(insn, 28, 4) == 0xf) {
93
- /* Encodings with T=1 (Thumb) or unconditional (ARM):
94
- * only used in v8 and above.
95
+ /*
96
+ * Encodings with T=1 (Thumb) or unconditional (ARM):
97
+ * only used for the "miscellaneous VFP features" added in v8A
98
+ * and v7M (and gated on the MVFR2.FPMisc field).
99
*/
100
- return disas_vfp_v8_insn(s, insn);
101
+ return disas_vfp_misc_insn(s, insn);
102
}
103
104
dp = ((insn & 0xf00) == 0xb00);
105
--
186
--
106
2.20.1
187
2.20.1
107
188
108
189
diff view generated by jsdifflib
1
Make the M-profile "init-svtor" property be settable after realize.
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
This matches the hardware, where this is a config signal which
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
is sampled on CPU reset and can thus be changed between one
3
and the T2 encoding is a special case where the shift count is always
4
reset and another. To do this we have to change the API we
4
equal to the element size.
5
use to add the property.
6
7
(We will need this capability for the SSE-200.)
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190219125808.25174-4-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
12
---
9
---
13
target/arm/cpu.c | 29 ++++++++++++++++++++++++-----
10
target/arm/helper-mve.h | 9 +++++++
14
1 file changed, 24 insertions(+), 5 deletions(-)
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
15
15
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.c
18
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/cpu.c
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
20
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
21
#include "target/arm/idau.h"
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
22
#include "qemu/error-report.h"
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
23
#include "qapi/error.h"
40
24
+#include "qapi/visitor.h"
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
25
#include "cpu.h"
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
26
#include "internals.h"
43
+# VSHLL encoding T2 where shift == esize
27
#include "qemu-common.h"
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
28
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pmsav7_dregion_property =
45
+ qd=%qd qm=%qm size=0 shift=8
29
pmsav7_dregion,
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
30
qdev_prop_uint32, uint32_t);
47
+ qd=%qd qm=%qm size=1 shift=16
31
48
+
32
-/* M profile: initial value of the Secure VTOR */
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
33
-static Property arm_cpu_initsvtor_property =
50
%rshift_i5 16:5 !function=rsub_32
34
- DEFINE_PROP_UINT32("init-svtor", ARMCPU, init_svtor, 0);
51
%rshift_i4 16:4 !function=rsub_16
35
+static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name,
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
36
+ void *opaque, Error **errp)
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
37
+{
60
+{
38
+ ARMCPU *cpu = ARM_CPU(obj);
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
39
+
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
40
+ visit_type_uint32(v, name, &cpu->init_svtor, errp);
63
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
41
+}
67
+}
42
+
68
+
43
+static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
44
+ void *opaque, Error **errp)
45
+{
69
+{
46
+ ARMCPU *cpu = ARM_CPU(obj);
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
47
+
72
+
48
+ visit_type_uint32(v, name, &cpu->init_svtor, errp);
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
49
+}
74
+}
50
75
+
51
void arm_cpu_post_init(Object *obj)
76
+{
52
{
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
54
qdev_prop_allow_set_link_before_realize,
79
+
55
OBJ_PROP_LINK_STRONG,
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
56
&error_abort);
81
+}
57
- qdev_property_add_static(DEVICE(obj), &arm_cpu_initsvtor_property,
82
+
58
- &error_abort);
83
+{
59
+ /*
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
60
+ * M profile: initial value of the Secure VTOR. We can't just use
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
61
+ * a simple DEFINE_PROP_UINT32 for this because we want to permit
86
+
62
+ * the property to be set after realize.
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
63
+ */
88
+}
64
+ object_property_add(obj, "init-svtor", "uint32",
89
65
+ arm_get_init_svtor, arm_set_init_svtor,
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
66
+ NULL, NULL, &error_abort);
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
67
}
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
68
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
69
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
139
+ }
140
+
141
+#define DO_VSHLL_ALL(OP, TOP) \
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
146
+
147
+DO_VSHLL_ALL(vshllb, false)
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
+
158
+#define DO_VSHLL(INSN, FN) \
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
166
+ }
167
+
168
+DO_VSHLL(VSHLL_BS, vshllbs)
169
+DO_VSHLL(VSHLL_BU, vshllbu)
170
+DO_VSHLL(VSHLL_TS, vshllts)
171
+DO_VSHLL(VSHLL_TU, vshlltu)
70
--
172
--
71
2.20.1
173
2.20.1
72
174
73
175
diff view generated by jsdifflib
New patch
1
Implement the MVE VSRI and VSLI insns, which perform a
2
shift-and-insert operation.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 8 ++++++++
9
target/arm/mve.decode | 9 ++++++++
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
13
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
33
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
35
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
38
+
39
+# Shift-and-insert
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
114
--
115
2.20.1
116
117
diff view generated by jsdifflib
1
The CPUWAIT register acts as a sort of power-control: if a bit
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
in it is 1 then the CPU will have been forced into waiting
3
when the system was reset (which in QEMU we model as the
4
CPU starting powered off). Writing a 0 to the register will
5
allow the CPU to boot (for QEMU, we model this as powering
6
it on). Note that writing 0 to the register does not power
7
off a CPU.
8
2
9
For this to work correctly we need to also honour the
3
do_urshr() is borrowed from sve_helper.c.
10
INITSVTOR* registers, which let the guest control where the
11
CPU will load its SP and PC from when it comes out of reset.
12
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190219125808.25174-8-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
16
---
8
---
17
hw/misc/iotkit-sysctl.c | 41 +++++++++++++++++++++++++++++++++++++----
9
target/arm/helper-mve.h | 10 ++++++++++
18
1 file changed, 37 insertions(+), 4 deletions(-)
10
target/arm/mve.decode | 11 +++++++++++
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
19
14
20
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/iotkit-sysctl.c
17
--- a/target/arm/helper-mve.h
23
+++ b/hw/misc/iotkit-sysctl.c
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
#include "hw/sysbus.h"
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
#include "hw/registerfields.h"
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
#include "hw/misc/iotkit-sysctl.h"
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+#include "target/arm/arm-powerctl.h"
23
+
29
+#include "target/arm/cpu.h"
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
REG32(SECDBGSTAT, 0x0)
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
REG32(SECDBGSET, 0x4)
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ static const int sysctl_id[] = {
28
+
34
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
};
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
41
+
42
+# Narrowing shifts (which only support b and h sizes)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/mve_helper.c
55
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
57
58
DO_VSHLL_ALL(vshllb, false)
59
DO_VSHLL_ALL(vshllt, true)
60
+
37
+/*
61
+/*
38
+ * Set the initial secure vector table offset address for the core.
62
+ * Narrowing right shifts, taking a double sized input, shifting it
39
+ * This will take effect when the CPU next resets.
63
+ * and putting the result in either the top or bottom half of the output.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
40
+ */
65
+ */
41
+static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
68
+ void *vm, uint32_t shift) \
69
+ { \
70
+ LTYPE *m = vm; \
71
+ TYPE *d = vd; \
72
+ uint16_t mask = mve_element_mask(env); \
73
+ unsigned le; \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
77
+ } \
78
+ mve_advance_vpt(env); \
79
+ }
80
+
81
+#define DO_VSHRN_ALL(OP, FN) \
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
86
+
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
42
+{
88
+{
43
+ Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
89
+ if (likely(sh < 64)) {
44
+
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
45
+ if (cpuobj) {
91
+ } else if (sh == 64) {
46
+ if (object_property_find(cpuobj, "init-svtor", NULL)) {
92
+ return x >> 63;
47
+ object_property_set_uint(cpuobj, vtor, "init-svtor", &error_abort);
93
+ } else {
48
+ }
94
+ return 0;
49
+ }
95
+ }
50
+}
96
+}
51
+
97
+
52
static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
53
unsigned size)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
54
{
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
55
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
101
index XXXXXXX..XXXXXXX 100644
56
s->gretreg = value;
102
--- a/target/arm/translate-mve.c
57
break;
103
+++ b/target/arm/translate-mve.c
58
case A_INITSVTOR0:
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
59
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR0 unimplemented\n");
105
DO_VSHLL(VSHLL_BU, vshllbu)
60
s->initsvtor0 = value;
106
DO_VSHLL(VSHLL_TS, vshllts)
61
+ set_init_vtor(0, s->initsvtor0);
107
DO_VSHLL(VSHLL_TU, vshlltu)
62
break;
108
+
63
case A_CPUWAIT:
109
+#define DO_2SHIFT_N(INSN, FN) \
64
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
65
+ if ((s->cpuwait & 1) && !(value & 1)) {
111
+ { \
66
+ /* Powering up CPU 0 */
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
67
+ arm_set_cpu_on_and_reset(0);
113
+ gen_helper_mve_##FN##b, \
68
+ }
114
+ gen_helper_mve_##FN##h, \
69
+ if ((s->cpuwait & 2) && !(value & 2)) {
115
+ }; \
70
+ /* Powering up CPU 1 */
116
+ return do_2shift(s, a, fns[a->size], false); \
71
+ arm_set_cpu_on_and_reset(1);
72
+ }
73
s->cpuwait = value;
74
break;
75
case A_WICCTRL:
76
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
77
if (!s->is_sse200) {
78
goto bad_offset;
79
}
80
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR1 unimplemented\n");
81
s->initsvtor1 = value;
82
+ set_init_vtor(1, s->initsvtor1);
83
break;
84
case A_EWCTRL:
85
if (!s->is_sse200) {
86
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
87
s->gretreg = 0;
88
s->initsvtor0 = 0x10000000;
89
s->initsvtor1 = 0x10000000;
90
- s->cpuwait = 0;
91
+ if (s->is_sse200) {
92
+ /*
93
+ * CPU 0 starts on, CPU 1 starts off. In real hardware this is
94
+ * configurable by the SoC integrator as a verilog parameter.
95
+ */
96
+ s->cpuwait = 2;
97
+ } else {
98
+ /* CPU 0 starts on */
99
+ s->cpuwait = 0;
100
+ }
117
+ }
101
s->wicctrl = 0;
118
+
102
s->scsecctrl = 0;
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
103
s->fclk_div = 0;
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
104
--
123
--
105
2.20.1
124
2.20.1
106
125
107
126
diff view generated by jsdifflib
1
The SYSCTL block in the SSE-200 has some extra registers that
1
Implement the MVE saturating shift-right-and-narrow insns
2
are not present in the IoTKit version. Add these registers
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
(as reads-as-written stubs), enabled by a new QOM property.
3
4
do_srshr() is borrowed from sve_helper.c.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190219125808.25174-7-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
8
---
9
---
9
include/hw/misc/iotkit-sysctl.h | 20 +++
10
target/arm/helper-mve.h | 30 +++++++++++
10
hw/arm/armsse.c | 2 +
11
target/arm/mve.decode | 28 ++++++++++
11
hw/misc/iotkit-sysctl.c | 245 +++++++++++++++++++++++++++++++-
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
12
3 files changed, 262 insertions(+), 5 deletions(-)
13
target/arm/translate-mve.c | 12 +++++
13
14
4 files changed, 174 insertions(+)
14
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
15
15
index XXXXXXX..XXXXXXX 100644
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
--- a/include/hw/misc/iotkit-sysctl.h
17
index XXXXXXX..XXXXXXX 100644
17
+++ b/include/hw/misc/iotkit-sysctl.h
18
--- a/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@
19
+++ b/target/arm/helper-mve.h
19
* "system control register" blocks.
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
*
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
* QEMU interface:
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+ * + QOM property "SYS_VERSION": value of the SYS_VERSION register of the
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ * system information block of the SSE
24
+
24
+ * (used to identify whether to provide SSE-200-only registers)
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
* + sysbus MMIO region 0: the system information register bank
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
* + sysbus MMIO region 1: the system control register bank
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
*/
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
29
+
29
uint32_t initsvtor0;
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
uint32_t cpuwait;
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
uint32_t wicctrl;
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ uint32_t scsecctrl;
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ uint32_t fclk_div;
34
+
34
+ uint32_t sysclk_div;
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ uint32_t clock_force;
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+ uint32_t initsvtor1;
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+ uint32_t nmi_enable;
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+ uint32_t ewctrl;
39
+
39
+ uint32_t pdcm_pd_sys_sense;
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+ uint32_t pdcm_pd_sram0_sense;
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+ uint32_t pdcm_pd_sram1_sense;
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+ uint32_t pdcm_pd_sram2_sense;
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+ uint32_t pdcm_pd_sram3_sense;
44
+
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
+ /* Properties */
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+ uint32_t sys_version;
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+ bool is_sse200;
49
+
49
} IoTKitSysCtl;
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
#endif
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
index XXXXXXX..XXXXXXX 100644
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
54
--- a/hw/arm/armsse.c
55
index XXXXXXX..XXXXXXX 100644
55
+++ b/hw/arm/armsse.c
56
--- a/target/arm/mve.decode
56
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
57
+++ b/target/arm/mve.decode
57
/* System information registers */
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
58
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
59
/* System control registers */
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
60
+ object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
61
+ "SYS_VERSION", &err);
62
+
62
object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
63
if (err) {
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
64
error_propagate(errp, err);
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
65
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
66
index XXXXXXX..XXXXXXX 100644
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
67
--- a/hw/misc/iotkit-sysctl.c
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
68
+++ b/hw/misc/iotkit-sysctl.c
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
69
@@ -XXX,XX +XXX,XX @@
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
70
*/
71
+
71
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
72
#include "qemu/osdep.h"
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
73
+#include "qemu/bitops.h"
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
74
#include "qemu/log.h"
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
75
#include "trace.h"
76
+
76
#include "qapi/error.h"
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
77
@@ -XXX,XX +XXX,XX @@
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
78
REG32(SECDBGSTAT, 0x0)
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
79
REG32(SECDBGSET, 0x4)
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
80
REG32(SECDBGCLR, 0x8)
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
81
+REG32(SCSECCTRL, 0xc)
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
82
+REG32(FCLK_DIV, 0x10)
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
83
+REG32(SYSCLK_DIV, 0x14)
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
84
+REG32(CLOCK_FORCE, 0x18)
85
+
85
REG32(RESET_SYNDROME, 0x100)
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
86
REG32(RESET_MASK, 0x104)
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
87
REG32(SWRESET, 0x108)
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
88
FIELD(SWRESET, SWRESETREQ, 9, 1)
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
89
REG32(GRETREG, 0x10c)
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
90
REG32(INITSVTOR0, 0x110)
91
index XXXXXXX..XXXXXXX 100644
91
+REG32(INITSVTOR1, 0x114)
92
--- a/target/arm/mve_helper.c
92
REG32(CPUWAIT, 0x118)
93
+++ b/target/arm/mve_helper.c
93
-REG32(BUSWAIT, 0x11c)
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
94
+REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
95
}
95
REG32(WICCTRL, 0x120)
96
+REG32(EWCTRL, 0x124)
97
+REG32(PDCM_PD_SYS_SENSE, 0x200)
98
+REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
99
+REG32(PDCM_PD_SRAM1_SENSE, 0x210)
100
+REG32(PDCM_PD_SRAM2_SENSE, 0x214)
101
+REG32(PDCM_PD_SRAM3_SENSE, 0x218)
102
REG32(PID4, 0xfd0)
103
REG32(PID5, 0xfd4)
104
REG32(PID6, 0xfd8)
105
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
106
case A_SECDBGSTAT:
107
r = s->secure_debug;
108
break;
109
+ case A_SCSECCTRL:
110
+ if (!s->is_sse200) {
111
+ goto bad_offset;
112
+ }
113
+ r = s->scsecctrl;
114
+ break;
115
+ case A_FCLK_DIV:
116
+ if (!s->is_sse200) {
117
+ goto bad_offset;
118
+ }
119
+ r = s->fclk_div;
120
+ break;
121
+ case A_SYSCLK_DIV:
122
+ if (!s->is_sse200) {
123
+ goto bad_offset;
124
+ }
125
+ r = s->sysclk_div;
126
+ break;
127
+ case A_CLOCK_FORCE:
128
+ if (!s->is_sse200) {
129
+ goto bad_offset;
130
+ }
131
+ r = s->clock_force;
132
+ break;
133
case A_RESET_SYNDROME:
134
r = s->reset_syndrome;
135
break;
136
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
137
case A_INITSVTOR0:
138
r = s->initsvtor0;
139
break;
140
+ case A_INITSVTOR1:
141
+ if (!s->is_sse200) {
142
+ goto bad_offset;
143
+ }
144
+ r = s->initsvtor1;
145
+ break;
146
case A_CPUWAIT:
147
r = s->cpuwait;
148
break;
149
- case A_BUSWAIT:
150
- /* In IoTKit BUSWAIT is reserved, R/O, zero */
151
- r = 0;
152
+ case A_NMI_ENABLE:
153
+ /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
154
+ if (!s->is_sse200) {
155
+ r = 0;
156
+ break;
157
+ }
158
+ r = s->nmi_enable;
159
break;
160
case A_WICCTRL:
161
r = s->wicctrl;
162
break;
163
+ case A_EWCTRL:
164
+ if (!s->is_sse200) {
165
+ goto bad_offset;
166
+ }
167
+ r = s->ewctrl;
168
+ break;
169
+ case A_PDCM_PD_SYS_SENSE:
170
+ if (!s->is_sse200) {
171
+ goto bad_offset;
172
+ }
173
+ r = s->pdcm_pd_sys_sense;
174
+ break;
175
+ case A_PDCM_PD_SRAM0_SENSE:
176
+ if (!s->is_sse200) {
177
+ goto bad_offset;
178
+ }
179
+ r = s->pdcm_pd_sram0_sense;
180
+ break;
181
+ case A_PDCM_PD_SRAM1_SENSE:
182
+ if (!s->is_sse200) {
183
+ goto bad_offset;
184
+ }
185
+ r = s->pdcm_pd_sram1_sense;
186
+ break;
187
+ case A_PDCM_PD_SRAM2_SENSE:
188
+ if (!s->is_sse200) {
189
+ goto bad_offset;
190
+ }
191
+ r = s->pdcm_pd_sram2_sense;
192
+ break;
193
+ case A_PDCM_PD_SRAM3_SENSE:
194
+ if (!s->is_sse200) {
195
+ goto bad_offset;
196
+ }
197
+ r = s->pdcm_pd_sram3_sense;
198
+ break;
199
case A_PID4 ... A_CID3:
200
r = sysctl_id[(offset - A_PID4) / 4];
201
break;
202
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
203
r = 0;
204
break;
205
default:
206
+ bad_offset:
207
qemu_log_mask(LOG_GUEST_ERROR,
208
"IoTKit SysCtl read: bad offset %x\n", (int)offset);
209
r = 0;
210
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
211
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
212
}
213
break;
214
- case A_BUSWAIT: /* In IoTKit BUSWAIT is reserved, R/O, zero */
215
+ case A_SCSECCTRL:
216
+ if (!s->is_sse200) {
217
+ goto bad_offset;
218
+ }
219
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
220
+ s->scsecctrl = value;
221
+ break;
222
+ case A_FCLK_DIV:
223
+ if (!s->is_sse200) {
224
+ goto bad_offset;
225
+ }
226
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
227
+ s->fclk_div = value;
228
+ break;
229
+ case A_SYSCLK_DIV:
230
+ if (!s->is_sse200) {
231
+ goto bad_offset;
232
+ }
233
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
234
+ s->sysclk_div = value;
235
+ break;
236
+ case A_CLOCK_FORCE:
237
+ if (!s->is_sse200) {
238
+ goto bad_offset;
239
+ }
240
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
241
+ s->clock_force = value;
242
+ break;
243
+ case A_INITSVTOR1:
244
+ if (!s->is_sse200) {
245
+ goto bad_offset;
246
+ }
247
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR1 unimplemented\n");
248
+ s->initsvtor1 = value;
249
+ break;
250
+ case A_EWCTRL:
251
+ if (!s->is_sse200) {
252
+ goto bad_offset;
253
+ }
254
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
255
+ s->ewctrl = value;
256
+ break;
257
+ case A_PDCM_PD_SYS_SENSE:
258
+ if (!s->is_sse200) {
259
+ goto bad_offset;
260
+ }
261
+ qemu_log_mask(LOG_UNIMP,
262
+ "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
263
+ s->pdcm_pd_sys_sense = value;
264
+ break;
265
+ case A_PDCM_PD_SRAM0_SENSE:
266
+ if (!s->is_sse200) {
267
+ goto bad_offset;
268
+ }
269
+ qemu_log_mask(LOG_UNIMP,
270
+ "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
271
+ s->pdcm_pd_sram0_sense = value;
272
+ break;
273
+ case A_PDCM_PD_SRAM1_SENSE:
274
+ if (!s->is_sse200) {
275
+ goto bad_offset;
276
+ }
277
+ qemu_log_mask(LOG_UNIMP,
278
+ "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
279
+ s->pdcm_pd_sram1_sense = value;
280
+ break;
281
+ case A_PDCM_PD_SRAM2_SENSE:
282
+ if (!s->is_sse200) {
283
+ goto bad_offset;
284
+ }
285
+ qemu_log_mask(LOG_UNIMP,
286
+ "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
287
+ s->pdcm_pd_sram2_sense = value;
288
+ break;
289
+ case A_PDCM_PD_SRAM3_SENSE:
290
+ if (!s->is_sse200) {
291
+ goto bad_offset;
292
+ }
293
+ qemu_log_mask(LOG_UNIMP,
294
+ "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
295
+ s->pdcm_pd_sram3_sense = value;
296
+ break;
297
+ case A_NMI_ENABLE:
298
+ /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
299
+ if (!s->is_sse200) {
300
+ goto ro_offset;
301
+ }
302
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
303
+ s->nmi_enable = value;
304
+ break;
305
case A_SECDBGSTAT:
306
case A_PID4 ... A_CID3:
307
+ ro_offset:
308
qemu_log_mask(LOG_GUEST_ERROR,
309
"IoTKit SysCtl write: write of RO offset %x\n",
310
(int)offset);
311
break;
312
default:
313
+ bad_offset:
314
qemu_log_mask(LOG_GUEST_ERROR,
315
"IoTKit SysCtl write: bad offset %x\n", (int)offset);
316
break;
317
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
318
s->reset_mask = 0;
319
s->gretreg = 0;
320
s->initsvtor0 = 0x10000000;
321
+ s->initsvtor1 = 0x10000000;
322
s->cpuwait = 0;
323
s->wicctrl = 0;
324
+ s->scsecctrl = 0;
325
+ s->fclk_div = 0;
326
+ s->sysclk_div = 0;
327
+ s->clock_force = 0;
328
+ s->nmi_enable = 0;
329
+ s->ewctrl = 0;
330
+ s->pdcm_pd_sys_sense = 0x7f;
331
+ s->pdcm_pd_sram0_sense = 0;
332
+ s->pdcm_pd_sram1_sense = 0;
333
+ s->pdcm_pd_sram2_sense = 0;
334
+ s->pdcm_pd_sram3_sense = 0;
335
}
96
}
336
97
337
static void iotkit_sysctl_init(Object *obj)
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
338
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_init(Object *obj)
339
sysbus_init_mmio(sbd, &s->iomem);
340
}
341
342
+static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
343
+{
99
+{
344
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
100
+ if (likely(sh < 64)) {
345
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
346
+ /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
102
+ } else {
347
+ if (extract32(s->sys_version, 28, 4) == 2) {
103
+ /* Rounding the sign bit always produces 0. */
348
+ s->is_sse200 = true;
104
+ return 0;
349
+ }
105
+ }
350
+}
106
+}
351
+
107
+
352
+static bool sse200_needed(void *opaque)
108
DO_VSHRN_ALL(vshrn, DO_SHR)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
353
+{
113
+{
354
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
114
+ if (val > max) {
355
+
115
+ *satp = true;
356
+ return s->is_sse200;
116
+ return max;
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
122
+ }
357
+}
123
+}
358
+
124
+
359
+static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
125
+/* Saturating narrowing right shifts */
360
+ .name = "iotkit-sysctl/sse-200",
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
361
+ .version_id = 1,
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
362
+ .minimum_version_id = 1,
128
+ void *vm, uint32_t shift) \
363
+ .needed = sse200_needed,
129
+ { \
364
+ .fields = (VMStateField[]) {
130
+ LTYPE *m = vm; \
365
+ VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
131
+ TYPE *d = vd; \
366
+ VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
132
+ uint16_t mask = mve_element_mask(env); \
367
+ VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
133
+ bool qc = false; \
368
+ VMSTATE_UINT32(clock_force, IoTKitSysCtl),
134
+ unsigned le; \
369
+ VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
370
+ VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
136
+ bool sat = false; \
371
+ VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
372
+ VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
373
+ VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
374
+ VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
140
+ } \
375
+ VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
141
+ if (qc) { \
376
+ VMSTATE_END_OF_LIST()
142
+ env->vfp.qc[0] = qc; \
143
+ } \
144
+ mve_advance_vpt(env); \
377
+ }
145
+ }
378
+};
146
+
379
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
380
static const VMStateDescription iotkit_sysctl_vmstate = {
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
381
.name = "iotkit-sysctl",
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
382
.version_id = 1,
150
+
383
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
384
VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
385
VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
386
VMSTATE_END_OF_LIST()
154
+
387
+ },
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
388
+ .subsections = (const VMStateDescription*[]) {
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
389
+ &iotkit_sysctl_sse200_vmstate,
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
390
+ NULL
158
+
391
}
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
392
};
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
393
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
394
+static Property iotkit_sysctl_props[] = {
162
+
395
+ DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
163
+#define DO_SHRN_SB(N, M, SATP) \
396
+ DEFINE_PROP_END_OF_LIST()
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
397
+};
165
+#define DO_SHRN_UB(N, M, SATP) \
398
+
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
399
static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
167
+#define DO_SHRUN_B(N, M, SATP) \
400
{
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
401
DeviceClass *dc = DEVICE_CLASS(klass);
169
+
402
170
+#define DO_SHRN_SH(N, M, SATP) \
403
dc->vmsd = &iotkit_sysctl_vmstate;
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
404
dc->reset = iotkit_sysctl_reset;
172
+#define DO_SHRN_UH(N, M, SATP) \
405
+ dc->props = iotkit_sysctl_props;
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
406
+ dc->realize = iotkit_sysctl_realize;
174
+#define DO_SHRUN_H(N, M, SATP) \
407
}
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
408
176
+
409
static const TypeInfo iotkit_sysctl_info = {
177
+#define DO_RSHRN_SB(N, M, SATP) \
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
179
+#define DO_RSHRN_UB(N, M, SATP) \
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
181
+#define DO_RSHRUN_B(N, M, SATP) \
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
183
+
184
+#define DO_RSHRN_SH(N, M, SATP) \
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
186
+#define DO_RSHRN_UH(N, M, SATP) \
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
188
+#define DO_RSHRUN_H(N, M, SATP) \
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
190
+
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
197
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/translate-mve.c
207
+++ b/target/arm/translate-mve.c
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
410
--
224
--
411
2.20.1
225
2.20.1
412
226
413
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
2
4
3
Note that float16_to_float32 rightly squashes SNaN to QNaN.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
But of course pickNaNMulAdd, for ARM, selects SNaNs first.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
So we have to preserve SNaN long enough for the correct NaN
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
6
to be selected. Thus float16_to_float32_by_bits.
8
---
9
target/arm/helper-mve.h | 2 ++
10
target/arm/mve.decode | 2 ++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
7
14
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
9
Message-id: 20190219222952.22183-2-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper.h | 9 +++
14
target/arm/vec_helper.c | 148 ++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 157 insertions(+)
16
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
17
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/helper.h
18
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_sqsub_s, TCG_CALL_NO_RWG,
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_5(gvec_sqsub_d, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(gvec_fmlal_a32, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(gvec_fmlal_a64, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+
23
+
34
#ifdef TARGET_AARCH64
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
35
#include "helper-a64.h"
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
36
#include "helper-sve.h"
37
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
38
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/vec_helper.c
27
--- a/target/arm/mve.decode
40
+++ b/target/arm/vec_helper.c
28
+++ b/target/arm/mve.decode
41
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sqsub_d)(void *vd, void *vq, void *vn,
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
42
}
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
43
clear_tail(d, oprsz, simd_maxsz(desc));
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
44
}
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
45
+
33
+
46
+/*
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
47
+ * Convert float16 to float32, raising no exceptions and
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
+ * preserving exceptional values, including SNaN.
36
index XXXXXXX..XXXXXXX 100644
49
+ * This is effectively an unpack+repack operation.
37
--- a/target/arm/mve_helper.c
50
+ */
38
+++ b/target/arm/mve_helper.c
51
+static float32 float16_to_float32_by_bits(uint32_t f16, bool fz16)
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
52
+{
46
+{
53
+ const int f16_bias = 15;
47
+ uint32_t *d = vd;
54
+ const int f32_bias = 127;
48
+ uint16_t mask = mve_element_mask(env);
55
+ uint32_t sign = extract32(f16, 15, 1);
49
+ unsigned e;
56
+ uint32_t exp = extract32(f16, 10, 5);
50
+ uint32_t r;
57
+ uint32_t frac = extract32(f16, 0, 10);
58
+
51
+
59
+ if (exp == 0x1f) {
52
+ /*
60
+ /* Inf or NaN */
53
+ * For each 32-bit element, we shift it left, bringing in the
61
+ exp = 0xff;
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
62
+ } else if (exp == 0) {
55
+ * the top become the new rdm, if the predicate mask permits.
63
+ /* Zero or denormal. */
56
+ * The final rdm value is returned to update the register.
64
+ if (frac != 0) {
57
+ * shift == 0 here means "shift by 32 bits".
65
+ if (fz16) {
58
+ */
66
+ frac = 0;
59
+ if (shift == 0) {
67
+ } else {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
68
+ /*
61
+ r = rdm;
69
+ * Denormal; these are all normal float32.
62
+ if (mask & 1) {
70
+ * Shift the fraction so that the msb is at bit 11,
63
+ rdm = d[H4(e)];
71
+ * then remove bit 11 as the implicit bit of the
72
+ * normalized float32. Note that we still go through
73
+ * the shift for normal numbers below, to put the
74
+ * float32 fraction at the right place.
75
+ */
76
+ int shift = clz32(frac) - 21;
77
+ frac = (frac << shift) & 0x3ff;
78
+ exp = f32_bias - f16_bias - shift + 1;
79
+ }
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
80
+ }
66
+ }
81
+ } else {
67
+ } else {
82
+ /* Normal number; adjust the bias. */
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
83
+ exp += f32_bias - f16_bias;
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
84
+ }
77
+ }
85
+ sign <<= 31;
78
+ mve_advance_vpt(env);
86
+ exp <<= 23;
79
+ return rdm;
87
+ frac <<= 23 - 10;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
88
+
89
+
89
+ return sign | exp | frac;
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
90
+}
91
+
92
+static uint64_t load4_f16(uint64_t *ptr, int is_q, int is_2)
93
+{
91
+{
94
+ /*
92
+ /*
95
+ * Branchless load of u32[0], u64[0], u32[1], or u64[1].
93
+ * Whole Vector Left Shift with Carry. The carry is taken
96
+ * Load the 2nd qword iff is_q & is_2.
94
+ * from a general purpose register and written back there.
97
+ * Shift to the 2nd dword iff !is_q & is_2.
95
+ * An imm of 0 means "shift by 32".
98
+ * For !is_q & !is_2, the upper bits of the result are garbage.
99
+ */
96
+ */
100
+ return ptr[is_q & is_2] >> ((is_2 & ~is_q) << 5);
97
+ TCGv_ptr qd;
101
+}
98
+ TCGv_i32 rdm;
102
+
99
+
103
+/*
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
104
+ * Note that FMLAL requires oprsz == 8 or oprsz == 16,
101
+ return false;
105
+ * as there is not yet SVE versions that might use blocking.
102
+ }
106
+ */
103
+ if (a->rdm == 13 || a->rdm == 15) {
107
+
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
108
+static void do_fmlal(float32 *d, void *vn, void *vm, float_status *fpst,
105
+ return false;
109
+ uint32_t desc, bool fz16)
106
+ }
110
+{
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
111
+ intptr_t i, oprsz = simd_oprsz(desc);
108
+ return true;
112
+ int is_s = extract32(desc, SIMD_DATA_SHIFT, 1);
113
+ int is_2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
114
+ int is_q = oprsz == 16;
115
+ uint64_t n_4, m_4;
116
+
117
+ /* Pre-load all of the f16 data, avoiding overlap issues. */
118
+ n_4 = load4_f16(vn, is_q, is_2);
119
+ m_4 = load4_f16(vm, is_q, is_2);
120
+
121
+ /* Negate all inputs for FMLSL at once. */
122
+ if (is_s) {
123
+ n_4 ^= 0x8000800080008000ull;
124
+ }
109
+ }
125
+
110
+
126
+ for (i = 0; i < oprsz / 4; i++) {
111
+ qd = mve_qreg_ptr(a->qd);
127
+ float32 n_1 = float16_to_float32_by_bits(n_4 >> (i * 16), fz16);
112
+ rdm = load_reg(s, a->rdm);
128
+ float32 m_1 = float16_to_float32_by_bits(m_4 >> (i * 16), fz16);
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
129
+ d[H4(i)] = float32_muladd(n_1, m_1, d[H4(i)], 0, fpst);
114
+ store_reg(s, a->rdm, rdm);
130
+ }
115
+ tcg_temp_free_ptr(qd);
131
+ clear_tail(d, oprsz, simd_maxsz(desc));
116
+ mve_update_eci(s);
132
+}
117
+ return true;
133
+
134
+void HELPER(gvec_fmlal_a32)(void *vd, void *vn, void *vm,
135
+ void *venv, uint32_t desc)
136
+{
137
+ CPUARMState *env = venv;
138
+ do_fmlal(vd, vn, vm, &env->vfp.standard_fp_status, desc,
139
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
140
+}
141
+
142
+void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm,
143
+ void *venv, uint32_t desc)
144
+{
145
+ CPUARMState *env = venv;
146
+ do_fmlal(vd, vn, vm, &env->vfp.fp_status, desc,
147
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
148
+}
149
+
150
+static void do_fmlal_idx(float32 *d, void *vn, void *vm, float_status *fpst,
151
+ uint32_t desc, bool fz16)
152
+{
153
+ intptr_t i, oprsz = simd_oprsz(desc);
154
+ int is_s = extract32(desc, SIMD_DATA_SHIFT, 1);
155
+ int is_2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
156
+ int index = extract32(desc, SIMD_DATA_SHIFT + 2, 3);
157
+ int is_q = oprsz == 16;
158
+ uint64_t n_4;
159
+ float32 m_1;
160
+
161
+ /* Pre-load all of the f16 data, avoiding overlap issues. */
162
+ n_4 = load4_f16(vn, is_q, is_2);
163
+
164
+ /* Negate all inputs for FMLSL at once. */
165
+ if (is_s) {
166
+ n_4 ^= 0x8000800080008000ull;
167
+ }
168
+
169
+ m_1 = float16_to_float32_by_bits(((float16 *)vm)[H2(index)], fz16);
170
+
171
+ for (i = 0; i < oprsz / 4; i++) {
172
+ float32 n_1 = float16_to_float32_by_bits(n_4 >> (i * 16), fz16);
173
+ d[H4(i)] = float32_muladd(n_1, m_1, d[H4(i)], 0, fpst);
174
+ }
175
+ clear_tail(d, oprsz, simd_maxsz(desc));
176
+}
177
+
178
+void HELPER(gvec_fmlal_idx_a32)(void *vd, void *vn, void *vm,
179
+ void *venv, uint32_t desc)
180
+{
181
+ CPUARMState *env = venv;
182
+ do_fmlal_idx(vd, vn, vm, &env->vfp.standard_fp_status, desc,
183
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
184
+}
185
+
186
+void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
187
+ void *venv, uint32_t desc)
188
+{
189
+ CPUARMState *env = venv;
190
+ do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc,
191
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
192
+}
118
+}
193
--
119
--
194
2.20.1
120
2.20.1
195
121
196
122
diff view generated by jsdifflib
1
Currently the Arm arm-powerctl.h APIs allow:
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
* arm_set_cpu_on(), which powers on a CPU and sets its
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
initial PC and other startup state
3
stored in a pair of general-purpose registers.
4
* arm_reset_cpu(), which resets a CPU which is already on
5
(and fails if the CPU is powered off)
6
7
but there is no way to say "power on a CPU as if it had
8
just come out of reset and don't do anything else to it".
9
10
Add a new function arm_set_cpu_on_and_reset(), which does this.
11
4
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190219125808.25174-5-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
15
---
8
---
16
target/arm/arm-powerctl.h | 16 +++++++++++
9
target/arm/helper-mve.h | 3 ++
17
target/arm/arm-powerctl.c | 56 +++++++++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 6 +++-
18
2 files changed, 72 insertions(+)
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
19
14
20
diff --git a/target/arm/arm-powerctl.h b/target/arm/arm-powerctl.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/arm-powerctl.h
17
--- a/target/arm/helper-mve.h
23
+++ b/target/arm/arm-powerctl.h
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ int arm_set_cpu_off(uint64_t cpuid);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
25
*/
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
int arm_reset_cpu(uint64_t cpuid);
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
22
28
+/*
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
29
+ * arm_set_cpu_on_and_reset:
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
30
+ * @cpuid: the id of the CPU we want to star
31
+ *
32
+ * Start the cpu designated by @cpuid and put it through its normal
33
+ * CPU reset process. The CPU will start in the way it is architected
34
+ * to start after a power-on reset.
35
+ *
36
+ * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
37
+ * QEMU_ARM_POWERCTL_INVALID_PARAM if there is no CPU with that ID.
38
+ * QEMU_ARM_POWERCTL_ALREADY_ON if the CPU is already on.
39
+ * QEMU_ARM_POWERCTL_ON_PENDING if the CPU is already partway through
40
+ * powering on.
41
+ */
42
+int arm_set_cpu_on_and_reset(uint64_t cpuid);
43
+
25
+
44
#endif
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
45
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
46
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/arm-powerctl.c
31
--- a/target/arm/mve.decode
48
+++ b/target/arm/arm-powerctl.c
32
+++ b/target/arm/mve.decode
49
@@ -XXX,XX +XXX,XX @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
50
return QEMU_ARM_POWERCTL_RET_SUCCESS;
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
51
}
82
}
52
83
53
+static void arm_set_cpu_on_and_reset_async_work(CPUState *target_cpu_state,
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
54
+ run_on_cpu_data data)
55
+{
85
+{
56
+ ARMCPU *target_cpu = ARM_CPU(target_cpu_state);
86
+ /*
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
88
+ * elements of the vector into a 64-bit result stored in
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
57
+
95
+
58
+ /* Initialize the cpu we are turning on */
96
+ if (!dc_isar_feature(aa32_mve, s)) {
59
+ cpu_reset(target_cpu_state);
97
+ return false;
60
+ target_cpu_state->halted = 0;
61
+
62
+ /* Finally set the power status */
63
+ assert(qemu_mutex_iothread_locked());
64
+ target_cpu->power_state = PSCI_ON;
65
+}
66
+
67
+int arm_set_cpu_on_and_reset(uint64_t cpuid)
68
+{
69
+ CPUState *target_cpu_state;
70
+ ARMCPU *target_cpu;
71
+
72
+ assert(qemu_mutex_iothread_locked());
73
+
74
+ /* Retrieve the cpu we are powering up */
75
+ target_cpu_state = arm_get_cpu_by_id(cpuid);
76
+ if (!target_cpu_state) {
77
+ /* The cpu was not found */
78
+ return QEMU_ARM_POWERCTL_INVALID_PARAM;
79
+ }
98
+ }
80
+
99
+ /*
81
+ target_cpu = ARM_CPU(target_cpu_state);
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
82
+ if (target_cpu->power_state == PSCI_ON) {
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
83
+ qemu_log_mask(LOG_GUEST_ERROR,
102
+ */
84
+ "[ARM]%s: CPU %" PRId64 " is already on\n",
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
85
+ __func__, cpuid);
104
+ return false;
86
+ return QEMU_ARM_POWERCTL_ALREADY_ON;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
107
+ return true;
87
+ }
108
+ }
88
+
109
+
89
+ /*
110
+ /*
90
+ * If another CPU has powered the target on we are in the state
111
+ * This insn is subject to beat-wise execution. Partial execution
91
+ * ON_PENDING and additional attempts to power on the CPU should
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
92
+ * fail (see 6.6 Implementation CPU_ON/CPU_OFF races in the PSCI
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
93
+ * spec)
94
+ */
114
+ */
95
+ if (target_cpu->power_state == PSCI_ON_PENDING) {
115
+ if (a->a || mve_skip_first_beat(s)) {
96
+ qemu_log_mask(LOG_GUEST_ERROR,
116
+ /* Accumulate input from RdaHi:RdaLo */
97
+ "[ARM]%s: CPU %" PRId64 " is already powering on\n",
117
+ rda = tcg_temp_new_i64();
98
+ __func__, cpuid);
118
+ rdalo = load_reg(s, a->rdalo);
99
+ return QEMU_ARM_POWERCTL_ON_PENDING;
119
+ rdahi = load_reg(s, a->rdahi);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
100
+ }
126
+ }
101
+
127
+
102
+ async_run_on_cpu(target_cpu_state, arm_set_cpu_on_and_reset_async_work,
128
+ qm = mve_qreg_ptr(a->qm);
103
+ RUN_ON_CPU_NULL);
129
+ if (a->u) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
104
+
135
+
105
+ /* We are good to go */
136
+ rdalo = tcg_temp_new_i32();
106
+ return QEMU_ARM_POWERCTL_RET_SUCCESS;
137
+ rdahi = tcg_temp_new_i32();
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
140
+ store_reg(s, a->rdalo, rdalo);
141
+ store_reg(s, a->rdahi, rdahi);
142
+ tcg_temp_free_i64(rda);
143
+ mve_update_eci(s);
144
+ return true;
107
+}
145
+}
108
+
146
+
109
static void arm_set_cpu_off_async_work(CPUState *target_cpu_state,
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
110
run_on_cpu_data data)
111
{
148
{
149
TCGv_ptr qd;
112
--
150
--
113
2.20.1
151
2.20.1
114
152
115
153
diff view generated by jsdifflib
1
Instead of gating the A32/T32 FP16 conversion instructions on
1
The MVE extension to v8.1M includes some new shift instructions which
2
the ARM_FEATURE_VFP_FP16 flag, switch to our new approach of
2
sit entirely within the non-coprocessor part of the encoding space
3
looking at ID register bits. In this case MVFR1 fields FPHP
3
and which operate only on general-purpose registers. They take up
4
and SIMDHP indicate the presence of these insns.
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
5
with Rm == 13 or 15.
6
This change doesn't alter behaviour for any of our CPUs.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
7
23
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190222170936.13268-2-peter.maydell@linaro.org
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
11
---
27
---
12
target/arm/cpu.h | 37 ++++++++++++++++++++++++++++++++++++-
28
target/arm/helper-mve.h | 3 ++
13
target/arm/cpu.c | 2 --
29
target/arm/translate.h | 1 +
14
target/arm/kvm32.c | 3 ---
30
target/arm/t32.decode | 28 +++++++++++++
15
target/arm/translate.c | 26 ++++++++++++++++++--------
31
target/arm/mve_helper.c | 10 +++++
16
4 files changed, 54 insertions(+), 14 deletions(-)
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
17
33
5 files changed, 132 insertions(+)
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
34
19
index XXXXXXX..XXXXXXX 100644
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
--- a/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
21
+++ b/target/arm/cpu.h
37
--- a/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
38
+++ b/target/arm/helper-mve.h
23
FIELD(ID_DFR0, PERFMON, 24, 4)
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
FIELD(ID_DFR0, TRACEFILT, 28, 4)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
41
26
+FIELD(MVFR0, SIMDREG, 0, 4)
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
27
+FIELD(MVFR0, FPSP, 4, 4)
43
+
28
+FIELD(MVFR0, FPDP, 8, 4)
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
+FIELD(MVFR0, FPTRAP, 12, 4)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
+FIELD(MVFR0, FPDIVIDE, 16, 4)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
+FIELD(MVFR0, FPSQRT, 20, 4)
47
index XXXXXXX..XXXXXXX 100644
32
+FIELD(MVFR0, FPSHVEC, 24, 4)
48
--- a/target/arm/translate.h
33
+FIELD(MVFR0, FPROUND, 28, 4)
49
+++ b/target/arm/translate.h
34
+
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+FIELD(MVFR1, FPFTZ, 0, 4)
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+FIELD(MVFR1, FPDNAN, 4, 4)
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+FIELD(MVFR1, SIMDLS, 8, 4)
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+FIELD(MVFR1, SIMDINT, 12, 4)
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
39
+FIELD(MVFR1, SIMDSP, 16, 4)
55
40
+FIELD(MVFR1, SIMDHP, 20, 4)
56
/**
41
+FIELD(MVFR1, FPHP, 24, 4)
57
* arm_tbflags_from_tb:
42
+FIELD(MVFR1, SIMDFMAC, 28, 4)
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
43
+
59
index XXXXXXX..XXXXXXX 100644
44
+FIELD(MVFR2, SIMDMISC, 0, 4)
60
--- a/target/arm/t32.decode
45
+FIELD(MVFR2, FPMISC, 4, 4)
61
+++ b/target/arm/t32.decode
46
+
62
@@ -XXX,XX +XXX,XX @@
47
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
63
&mcr !extern cp opc1 crn crm opc2 rt
48
64
&mcrr !extern cp opc1 crm rt rt2
49
/* If adding a feature bit which corresponds to a Linux ELF
65
50
@@ -XXX,XX +XXX,XX @@ enum arm_features {
66
+&mve_shl_ri rdalo rdahi shim
51
ARM_FEATURE_THUMB2,
67
+
52
ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
53
ARM_FEATURE_VFP3,
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
54
- ARM_FEATURE_VFP_FP16,
70
+%rdahi_9 9:3 !function=times_2_plus_1
55
ARM_FEATURE_NEON,
71
+%rdalo_17 17:3 !function=times_2
56
ARM_FEATURE_M, /* Microcontroller profile. */
72
+
57
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
73
# Data-processing (register)
58
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
74
59
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
75
%imm5_12_6 12:3 6:2
60
}
76
@@ -XXX,XX +XXX,XX @@
61
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
62
+/*
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
63
+ * We always set the FP and SIMD FP16 fields to indicate identical
79
64
+ * levels of support (assuming SIMD is implemented at all), so
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
65
+ * we only need one set of accessors.
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
66
+ */
82
+
67
+static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
83
{
68
+{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
69
+ return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 0;
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
70
+}
86
}
71
+
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
72
+static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
88
{
73
+{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
74
+ return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
75
+}
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
76
+
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
77
/*
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
78
* 64-bit feature tests via id registers.
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
79
*/
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
80
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
96
+ [
81
index XXXXXXX..XXXXXXX 100644
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
82
--- a/target/arm/cpu.c
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+++ b/target/arm/cpu.c
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
84
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
100
+
85
}
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
86
if (arm_feature(env, ARM_FEATURE_VFP4)) {
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
87
set_feature(env, ARM_FEATURE_VFP3);
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
- set_feature(env, ARM_FEATURE_VFP_FP16);
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
89
}
105
+ ]
90
if (arm_feature(env, ARM_FEATURE_VFP3)) {
106
+
91
set_feature(env, ARM_FEATURE_VFP);
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
92
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
93
cpu->dtb_compatible = "arm,cortex-a9";
109
}
94
set_feature(&cpu->env, ARM_FEATURE_V7);
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
95
set_feature(&cpu->env, ARM_FEATURE_VFP3);
111
index XXXXXXX..XXXXXXX 100644
96
- set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
112
--- a/target/arm/mve_helper.c
97
set_feature(&cpu->env, ARM_FEATURE_NEON);
113
+++ b/target/arm/mve_helper.c
98
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
99
set_feature(&cpu->env, ARM_FEATURE_EL3);
115
mve_advance_vpt(env);
100
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
116
return rdm;
101
index XXXXXXX..XXXXXXX 100644
117
}
102
--- a/target/arm/kvm32.c
118
+
103
+++ b/target/arm/kvm32.c
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
104
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
120
+{
105
if (extract32(id_pfr0, 12, 4) == 1) {
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
106
set_feature(&features, ARM_FEATURE_THUMB2EE);
122
+}
107
}
123
+
108
- if (extract32(ahcf->isar.mvfr1, 20, 4) == 1) {
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
109
- set_feature(&features, ARM_FEATURE_VFP_FP16);
125
+{
110
- }
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
111
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
127
+}
112
set_feature(&features, ARM_FEATURE_NEON);
113
}
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
119
* UNPREDICTABLE if bit 8 is set prior to ARMv8
133
return true;
120
* (we choose to UNDEF)
134
}
121
*/
135
122
- if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
136
+/*
123
- !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
137
+ * v8.1M MVE wide-shifts
124
- return 1;
138
+ */
125
+ if (dp) {
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
126
+ if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
140
+ WideShiftImmFn *fn)
127
+ return 1;
141
+{
128
+ }
142
+ TCGv_i64 rda;
129
+ } else {
143
+ TCGv_i32 rdalo, rdahi;
130
+ if (!dc_isar_feature(aa32_fp16_spconv, s)) {
144
+
131
+ return 1;
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
132
+ }
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
133
}
147
+ return false;
134
rm_is_dp = false;
148
+ }
135
break;
149
+ if (a->rdahi == 15) {
136
case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
137
case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
151
+ return false;
138
- if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
152
+ }
139
- !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
153
+ if (!dc_isar_feature(aa32_mve, s) ||
140
- return 1;
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
141
+ if (dp) {
155
+ a->rdahi == 13) {
142
+ if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
143
+ return 1;
157
+ unallocated_encoding(s);
144
+ }
158
+ return true;
145
+ } else {
159
+ }
146
+ if (!dc_isar_feature(aa32_fp16_spconv, s)) {
160
+
147
+ return 1;
161
+ if (a->shim == 0) {
148
+ }
162
+ a->shim = 32;
149
}
163
+ }
150
rd_is_dp = false;
164
+
151
break;
165
+ rda = tcg_temp_new_i64();
152
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
166
+ rdalo = load_reg(s, a->rdalo);
153
TCGv_ptr fpst;
167
+ rdahi = load_reg(s, a->rdahi);
154
TCGv_i32 ahp;
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
155
169
+
156
- if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
170
+ fn(rda, rda, a->shim);
157
+ if (!dc_isar_feature(aa32_fp16_spconv, s) ||
171
+
158
q || (rm & 1)) {
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
159
return 1;
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
160
}
174
+ store_reg(s, a->rdalo, rdalo);
161
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
175
+ store_reg(s, a->rdahi, rdahi);
162
{
176
+ tcg_temp_free_i64(rda);
163
TCGv_ptr fpst;
177
+
164
TCGv_i32 ahp;
178
+ return true;
165
- if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
179
+}
166
+ if (!dc_isar_feature(aa32_fp16_spconv, s) ||
180
+
167
q || (rd & 1)) {
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
168
return 1;
182
+{
169
}
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
170
--
229
--
171
2.20.1
230
2.20.1
172
231
173
232
diff view generated by jsdifflib
1
The iotkit-sysctl device has a register it names INITSVRTOR0.
1
Implement the MVE long shifts by register, which perform shifts on a
2
This is actually a typo present in the IoTKit documentation
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
and also in part of the SSE-200 documentation: it should be
3
the shift count in another general-purpose register, which might be
4
INITSVTOR0 because it is specifying the initial value of the
4
either positive or negative.
5
Secure VTOR register in the CPU. Correct the typo.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
6
11
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190219125808.25174-6-peter.maydell@linaro.org
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
10
---
15
---
11
include/hw/misc/iotkit-sysctl.h | 2 +-
16
target/arm/helper-mve.h | 6 +++
12
hw/misc/iotkit-sysctl.c | 16 ++++++++--------
17
target/arm/translate.h | 1 +
13
2 files changed, 9 insertions(+), 9 deletions(-)
18
target/arm/t32.decode | 16 +++++--
14
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
15
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
16
index XXXXXXX..XXXXXXX 100644
21
5 files changed, 182 insertions(+), 3 deletions(-)
17
--- a/include/hw/misc/iotkit-sysctl.h
22
18
+++ b/include/hw/misc/iotkit-sysctl.h
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
24
index XXXXXXX..XXXXXXX 100644
20
uint32_t reset_syndrome;
25
--- a/target/arm/helper-mve.h
21
uint32_t reset_mask;
26
+++ b/target/arm/helper-mve.h
22
uint32_t gretreg;
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
- uint32_t initsvrtor0;
28
24
+ uint32_t initsvtor0;
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
25
uint32_t cpuwait;
30
26
uint32_t wicctrl;
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
} IoTKitSysCtl;
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
index XXXXXXX..XXXXXXX 100644
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
--- a/hw/misc/iotkit-sysctl.c
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
+++ b/hw/misc/iotkit-sysctl.c
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
@@ -XXX,XX +XXX,XX @@ REG32(RESET_MASK, 0x104)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
REG32(SWRESET, 0x108)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
FIELD(SWRESET, SWRESETREQ, 9, 1)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
35
REG32(GRETREG, 0x10c)
40
index XXXXXXX..XXXXXXX 100644
36
-REG32(INITSVRTOR0, 0x110)
41
--- a/target/arm/translate.h
37
+REG32(INITSVTOR0, 0x110)
42
+++ b/target/arm/translate.h
38
REG32(CPUWAIT, 0x118)
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
39
REG32(BUSWAIT, 0x11c)
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
40
REG32(WICCTRL, 0x120)
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
41
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
42
case A_GRETREG:
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
43
r = s->gretreg;
48
44
break;
49
/**
45
- case A_INITSVRTOR0:
50
* arm_tbflags_from_tb:
46
- r = s->initsvrtor0;
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
47
+ case A_INITSVTOR0:
52
index XXXXXXX..XXXXXXX 100644
48
+ r = s->initsvtor0;
53
--- a/target/arm/t32.decode
49
break;
54
+++ b/target/arm/t32.decode
50
case A_CPUWAIT:
55
@@ -XXX,XX +XXX,XX @@
51
r = s->cpuwait;
56
&mcrr !extern cp opc1 crm rt rt2
52
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
57
53
*/
58
&mve_shl_ri rdalo rdahi shim
54
s->gretreg = value;
59
+&mve_shl_rr rdalo rdahi rm
55
break;
60
56
- case A_INITSVRTOR0:
61
# rdahi: bits [3:1] from insn, bit 0 is 1
57
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n");
62
# rdalo: bits [3:1] from insn, bit 0 is 0
58
- s->initsvrtor0 = value;
63
@@ -XXX,XX +XXX,XX @@
59
+ case A_INITSVTOR0:
64
60
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR0 unimplemented\n");
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
61
+ s->initsvtor0 = value;
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
62
break;
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
63
case A_CPUWAIT:
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
64
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
69
65
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
70
{
66
s->reset_syndrome = 1;
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
67
s->reset_mask = 0;
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
68
s->gretreg = 0;
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
69
- s->initsvrtor0 = 0x10000000;
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
70
+ s->initsvtor0 = 0x10000000;
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
71
s->cpuwait = 0;
76
+
72
s->wicctrl = 0;
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
73
}
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
74
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
75
VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
76
VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
77
VMSTATE_UINT32(gretreg, IoTKitSysCtl),
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
78
- VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl),
83
]
79
+ VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
84
80
VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
81
VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
82
VMSTATE_END_OF_LIST()
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
83
--
291
--
84
2.20.1
292
2.20.1
85
293
86
294
diff view generated by jsdifflib
1
At the moment the handling of init-svtor and cpuwait initial
1
Implement the MVE shifts by immediate, which perform shifts
2
values is split between armsse.c and iotkit-sysctl.c:
2
on a single general-purpose register.
3
the code in armsse.c sets the initial state of the CPU
3
4
object by setting the init-svtor and start-powered-off
4
These patterns overlap with the long-shift-by-immediates,
5
properties, but the iotkit-sysctl.c code has its own
5
so we have to rearrange the grouping a little here.
6
code setting the reset values of its registers (which are
7
then used when updating the CPU when the guest makes
8
runtime changes).
9
10
Clean this up by making the armsse.c code set properties on the
11
iotkit-sysctl object to define the initial values of the
12
registers, so they always match the initial CPU state,
13
and update the comments in armsse.c accordingly.
14
6
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190219125808.25174-9-peter.maydell@linaro.org
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
18
---
10
---
19
include/hw/misc/iotkit-sysctl.h | 3 ++
11
target/arm/helper-mve.h | 3 ++
20
hw/arm/armsse.c | 49 +++++++++++++++++++++------------
12
target/arm/translate.h | 1 +
21
hw/misc/iotkit-sysctl.c | 20 ++++++--------
13
target/arm/t32.decode | 31 ++++++++++++++-----
22
3 files changed, 42 insertions(+), 30 deletions(-)
14
target/arm/mve_helper.c | 10 ++++++
23
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
24
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
16
5 files changed, 104 insertions(+), 9 deletions(-)
25
index XXXXXXX..XXXXXXX 100644
17
26
--- a/include/hw/misc/iotkit-sysctl.h
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
27
+++ b/include/hw/misc/iotkit-sysctl.h
19
index XXXXXXX..XXXXXXX 100644
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
20
--- a/target/arm/helper-mve.h
29
21
+++ b/target/arm/helper-mve.h
30
/* Properties */
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
uint32_t sys_version;
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+ uint32_t cpuwait_rst;
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
+ uint32_t initsvtor0_rst;
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
+ uint32_t initsvtor1_rst;
26
+
35
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
36
bool is_sse200;
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
37
} IoTKitSysCtl;
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
38
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
30
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
40
--- a/hw/arm/armsse.c
32
+++ b/target/arm/translate.h
41
+++ b/hw/arm/armsse.c
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
42
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
43
46
44
#include "qemu/osdep.h"
47
&mve_shl_ri rdalo rdahi shim
45
#include "qemu/log.h"
48
&mve_shl_rr rdalo rdahi rm
46
+#include "qemu/bitops.h"
49
+&mve_sh_ri rda shim
47
#include "qapi/error.h"
50
48
#include "trace.h"
51
# rdahi: bits [3:1] from insn, bit 0 is 1
49
#include "hw/sysbus.h"
52
# rdalo: bits [3:1] from insn, bit 0 is 0
50
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
53
@@ -XXX,XX +XXX,XX @@
51
int sram_banks;
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
52
int num_cpus;
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
53
uint32_t sys_version;
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
54
+ uint32_t cpuwait_rst;
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
55
SysConfigFormat sys_config_format;
58
+ &mve_sh_ri shim=%imm5_12_6
56
bool has_mhus;
59
57
bool has_ppus;
60
{
58
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
59
.sram_banks = 1,
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
60
.num_cpus = 1,
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
61
.sys_version = 0x41743,
64
# handling them as r13 and r15 accesses with the same semantics as A32).
62
+ .cpuwait_rst = 0,
65
[
63
.sys_config_format = IoTKitFormat,
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
64
.has_mhus = false,
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
65
.has_ppus = false,
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
69
+ {
67
.sram_banks = 4,
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
68
.num_cpus = 2,
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
69
.sys_version = 0x22041743,
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
70
+ .cpuwait_rst = 2,
73
+ }
71
.sys_config_format = SSE200Format,
74
72
.has_mhus = true,
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
.has_ppus = true,
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
79
+ {
77
/*
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
78
- * In real hardware the initial Secure VTOR is set from the INITSVTOR0
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
79
- * register in the IoT Kit System Control Register block, and the
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
80
- * initial value of that is in turn specifiable by the FPGA that
83
+ }
81
- * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
84
+
82
- * and simply set the CPU's init-svtor to the IoT Kit default value.
85
+ {
83
- * In SSE-200 the situation is similar, except that the default value
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
84
- * is a reset-time signal input. Typically a board using the SSE-200
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
85
- * will have a system control processor whose boot firmware initializes
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
86
- * the INITSVTOR* registers before powering up the CPUs in any case,
89
+ }
87
- * so the hardware's default value doesn't matter. QEMU doesn't emulate
90
+
88
+ * In real hardware the initial Secure VTOR is set from the INITSVTOR*
91
+ {
89
+ * registers in the IoT Kit System Control Register block. In QEMU
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
90
+ * we set the initial value here, and also the reset value of the
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
91
+ * sysctl register, from this object's QOM init-svtor property.
94
+ }
92
+ * If the guest changes the INITSVTOR* registers at runtime then the
95
93
+ * code in iotkit-sysctl.c will update the CPU init-svtor property
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
94
+ * (which will then take effect on the next CPU warm-reset).
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
95
+ *
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
96
+ * Note that typically a board using the SSE-200 will have a system
99
index XXXXXXX..XXXXXXX 100644
97
+ * control processor whose boot firmware initializes the INITSVTOR*
100
--- a/target/arm/mve_helper.c
98
+ * registers before powering up the CPUs. QEMU doesn't emulate
101
+++ b/target/arm/mve_helper.c
99
* the control processor, so instead we behave in the way that the
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
100
- * firmware does. The initial value is configurable by the board code
103
{
101
- * to match whatever its firmware does.
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
102
+ * firmware does: the initial value should be set by the board code
105
}
103
+ * (using the init-svtor property on the ARMSSE object) to match
106
+
104
+ * whatever its firmware does.
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
105
*/
108
+{
106
qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
107
/*
110
+}
108
- * Start all CPUs except CPU0 powered down. In real hardware it is
111
+
109
- * a configurable property of the SSE-200 which CPUs start powered up
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
110
- * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
113
+{
111
- * the boards we care about start CPU0 and leave CPU1 powered off,
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
112
- * we hard-code that for now. We can add QOM properties for this
115
+}
113
+ * CPUs start powered down if the corresponding bit in the CPUWAIT
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
+ * register is 1. In real hardware the CPUWAIT register reset value is
117
index XXXXXXX..XXXXXXX 100644
115
+ * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
118
--- a/target/arm/translate.c
116
+ * CPUWAIT1_RST parameters), but since all the boards we care about
119
+++ b/target/arm/translate.c
117
+ * start CPU0 and leave CPU1 powered off, we hard-code that in
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
118
+ * info->cpuwait_rst for now. We can add QOM properties for this
121
119
* later if necessary.
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
120
*/
123
{
121
- if (i > 0) {
124
- TCGv_i32 t = tcg_temp_new_i32();
122
+ if (extract32(info->cpuwait_rst, i, 1)) {
125
+ TCGv_i32 t;
123
object_property_set_bool(cpuobj, true, "start-powered-off", &err);
126
124
if (err) {
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
125
error_propagate(errp, err);
128
+ if (sh == 32) {
126
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
129
+ tcg_gen_movi_i32(d, 0);
127
/* System control registers */
130
+ return;
128
object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
131
+ }
129
"SYS_VERSION", &err);
132
+ t = tcg_temp_new_i32();
130
+ object_property_set_int(OBJECT(&s->sysctl), info->cpuwait_rst,
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
131
+ "CPUWAIT_RST", &err);
134
tcg_gen_sari_i32(d, a, sh);
132
+ object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
135
tcg_gen_add_i32(d, d, t);
133
+ "INITSVTOR0_RST", &err);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
134
+ object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
137
135
+ "INITSVTOR1_RST", &err);
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
136
object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
139
{
137
if (err) {
140
- TCGv_i32 t = tcg_temp_new_i32();
138
error_propagate(errp, err);
141
+ TCGv_i32 t;
139
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
142
140
index XXXXXXX..XXXXXXX 100644
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
141
--- a/hw/misc/iotkit-sysctl.c
144
+ if (sh == 32) {
142
+++ b/hw/misc/iotkit-sysctl.c
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
143
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
146
+ return;
144
s->reset_syndrome = 1;
147
+ }
145
s->reset_mask = 0;
148
+ t = tcg_temp_new_i32();
146
s->gretreg = 0;
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
147
- s->initsvtor0 = 0x10000000;
150
tcg_gen_shri_i32(d, a, sh);
148
- s->initsvtor1 = 0x10000000;
151
tcg_gen_add_i32(d, d, t);
149
- if (s->is_sse200) {
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
150
- /*
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
151
- * CPU 0 starts on, CPU 1 starts off. In real hardware this is
154
}
152
- * configurable by the SoC integrator as a verilog parameter.
155
153
- */
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
154
- s->cpuwait = 2;
157
+{
155
- } else {
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
156
- /* CPU 0 starts on */
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
157
- s->cpuwait = 0;
160
+ return false;
158
- }
161
+ }
159
+ s->initsvtor0 = s->initsvtor0_rst;
162
+ if (!dc_isar_feature(aa32_mve, s) ||
160
+ s->initsvtor1 = s->initsvtor1_rst;
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
161
+ s->cpuwait = s->cpuwait_rst;
164
+ a->rda == 13 || a->rda == 15) {
162
s->wicctrl = 0;
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
163
s->scsecctrl = 0;
166
+ unallocated_encoding(s);
164
s->fclk_div = 0;
167
+ return true;
165
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
168
+ }
166
169
+
167
static Property iotkit_sysctl_props[] = {
170
+ if (a->shim == 0) {
168
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
171
+ a->shim = 32;
169
+ DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
172
+ }
170
+ DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
171
+ 0x10000000),
174
+
172
+ DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
175
+ return true;
173
+ 0x10000000),
176
+}
174
DEFINE_PROP_END_OF_LIST()
177
+
175
};
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
176
179
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
181
+}
182
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
184
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
186
+}
187
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
189
+{
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
177
--
211
--
178
2.20.1
212
2.20.1
179
213
180
214
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190219222952.22183-4-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
7
---
8
target/arm/cpu.h | 5 ++
8
target/arm/helper-mve.h | 2 ++
9
target/arm/translate.c | 129 ++++++++++++++++++++++++++++++-----------
9
target/arm/translate.h | 1 +
10
2 files changed, 101 insertions(+), 33 deletions(-)
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
11
14
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-mve.h
15
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
17
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
20
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.h
28
+++ b/target/arm/translate.h
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
34
35
/**
36
* arm_tbflags_from_tb:
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
40
+++ b/target/arm/t32.decode
41
@@ -XXX,XX +XXX,XX @@
42
&mve_shl_ri rdalo rdahi shim
43
&mve_shl_rr rdalo rdahi rm
44
&mve_sh_ri rda shim
45
+&mve_sh_rr rda rm
46
47
# rdahi: bits [3:1] from insn, bit 0 is 1
48
# rdalo: bits [3:1] from insn, bit 0 is 0
49
@@ -XXX,XX +XXX,XX @@
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
52
&mve_sh_ri shim=%imm5_12_6
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
54
55
{
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
59
}
60
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
69
+ }
70
+
71
+ {
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
75
+ }
76
+
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
18
}
87
}
19
88
+
20
+static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
21
+{
90
+{
22
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
23
+}
92
+}
24
+
93
+
25
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
26
{
95
+{
27
/*
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.c
100
--- a/target/arm/translate.c
31
+++ b/target/arm/translate.c
101
+++ b/target/arm/translate.c
32
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
33
gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
34
int rd, rn, rm, opr_sz;
104
}
35
int data = 0;
105
36
- bool q;
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
37
-
107
+{
38
- q = extract32(insn, 6, 1);
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
39
- VFP_DREG_D(rd, insn);
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
40
- VFP_DREG_N(rn, insn);
110
+ return false;
41
- VFP_DREG_M(rm, insn);
42
- if ((rd | rn | rm) & q) {
43
- return 1;
44
- }
45
+ int off_rn, off_rm;
46
+ bool is_long = false, q = extract32(insn, 6, 1);
47
+ bool ptr_is_env = false;
48
49
if ((insn & 0xfe200f10) == 0xfc200800) {
50
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
51
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
52
return 1;
53
}
54
fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
55
+ } else if ((insn & 0xff300f10) == 0xfc200810) {
56
+ /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
57
+ int is_s = extract32(insn, 23, 1);
58
+ if (!dc_isar_feature(aa32_fhm, s)) {
59
+ return 1;
60
+ }
61
+ is_long = true;
62
+ data = is_s; /* is_2 == 0 */
63
+ fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
64
+ ptr_is_env = true;
65
} else {
66
return 1;
67
}
68
69
+ VFP_DREG_D(rd, insn);
70
+ if (rd & q) {
71
+ return 1;
72
+ }
111
+ }
73
+ if (q || !is_long) {
112
+ if (!dc_isar_feature(aa32_mve, s) ||
74
+ VFP_DREG_N(rn, insn);
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
75
+ VFP_DREG_M(rm, insn);
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
76
+ if ((rn | rm) & q & !is_long) {
115
+ a->rm == a->rda) {
77
+ return 1;
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
78
+ }
117
+ unallocated_encoding(s);
79
+ off_rn = vfp_reg_offset(1, rn);
118
+ return true;
80
+ off_rm = vfp_reg_offset(1, rm);
81
+ } else {
82
+ rn = VFP_SREG_N(insn);
83
+ rm = VFP_SREG_M(insn);
84
+ off_rn = vfp_reg_offset(0, rn);
85
+ off_rm = vfp_reg_offset(0, rm);
86
+ }
119
+ }
87
+
120
+
88
if (s->fp_excp_el) {
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
89
gen_exception_insn(s, 4, EXCP_UDEF,
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
90
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
123
+ return true;
91
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
124
+}
92
93
opr_sz = (1 + q) * 8;
94
if (fn_gvec_ptr) {
95
- TCGv_ptr fpst = get_fpstatus_ptr(1);
96
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
97
- vfp_reg_offset(1, rn),
98
- vfp_reg_offset(1, rm), fpst,
99
+ TCGv_ptr ptr;
100
+ if (ptr_is_env) {
101
+ ptr = cpu_env;
102
+ } else {
103
+ ptr = get_fpstatus_ptr(1);
104
+ }
105
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
106
opr_sz, opr_sz, data, fn_gvec_ptr);
107
- tcg_temp_free_ptr(fpst);
108
+ if (!ptr_is_env) {
109
+ tcg_temp_free_ptr(ptr);
110
+ }
111
} else {
112
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
113
- vfp_reg_offset(1, rn),
114
- vfp_reg_offset(1, rm),
115
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
116
opr_sz, opr_sz, data, fn_gvec);
117
}
118
return 0;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
120
gen_helper_gvec_3 *fn_gvec = NULL;
121
gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
122
int rd, rn, rm, opr_sz, data;
123
- bool q;
124
-
125
- q = extract32(insn, 6, 1);
126
- VFP_DREG_D(rd, insn);
127
- VFP_DREG_N(rn, insn);
128
- if ((rd | rn) & q) {
129
- return 1;
130
- }
131
+ int off_rn, off_rm;
132
+ bool is_long = false, q = extract32(insn, 6, 1);
133
+ bool ptr_is_env = false;
134
135
if ((insn & 0xff000f10) == 0xfe000800) {
136
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
137
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
138
} else if ((insn & 0xffb00f00) == 0xfe200d00) {
139
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
140
int u = extract32(insn, 4, 1);
141
+
125
+
142
if (!dc_isar_feature(aa32_dp, s)) {
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
143
return 1;
127
+{
144
}
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
145
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
129
+}
146
/* rm is just Vm, and index is M. */
147
data = extract32(insn, 5, 1); /* index */
148
rm = extract32(insn, 0, 4);
149
+ } else if ((insn & 0xffa00f10) == 0xfe000810) {
150
+ /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
151
+ int is_s = extract32(insn, 20, 1);
152
+ int vm20 = extract32(insn, 0, 3);
153
+ int vm3 = extract32(insn, 3, 1);
154
+ int m = extract32(insn, 5, 1);
155
+ int index;
156
+
130
+
157
+ if (!dc_isar_feature(aa32_fhm, s)) {
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
158
+ return 1;
132
+{
159
+ }
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
160
+ if (q) {
134
+}
161
+ rm = vm20;
135
+
162
+ index = m * 2 + vm3;
136
/*
163
+ } else {
137
* Multiply and multiply accumulate
164
+ rm = vm20 * 2 + m;
138
*/
165
+ index = vm3;
166
+ }
167
+ is_long = true;
168
+ data = (index << 2) | is_s; /* is_2 == 0 */
169
+ fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
170
+ ptr_is_env = true;
171
} else {
172
return 1;
173
}
174
175
+ VFP_DREG_D(rd, insn);
176
+ if (rd & q) {
177
+ return 1;
178
+ }
179
+ if (q || !is_long) {
180
+ VFP_DREG_N(rn, insn);
181
+ if (rn & q & !is_long) {
182
+ return 1;
183
+ }
184
+ off_rn = vfp_reg_offset(1, rn);
185
+ off_rm = vfp_reg_offset(1, rm);
186
+ } else {
187
+ rn = VFP_SREG_N(insn);
188
+ off_rn = vfp_reg_offset(0, rn);
189
+ off_rm = vfp_reg_offset(0, rm);
190
+ }
191
if (s->fp_excp_el) {
192
gen_exception_insn(s, 4, EXCP_UDEF,
193
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
195
196
opr_sz = (1 + q) * 8;
197
if (fn_gvec_ptr) {
198
- TCGv_ptr fpst = get_fpstatus_ptr(1);
199
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
200
- vfp_reg_offset(1, rn),
201
- vfp_reg_offset(1, rm), fpst,
202
+ TCGv_ptr ptr;
203
+ if (ptr_is_env) {
204
+ ptr = cpu_env;
205
+ } else {
206
+ ptr = get_fpstatus_ptr(1);
207
+ }
208
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
209
opr_sz, opr_sz, data, fn_gvec_ptr);
210
- tcg_temp_free_ptr(fpst);
211
+ if (!ptr_is_env) {
212
+ tcg_temp_free_ptr(ptr);
213
+ }
214
} else {
215
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
216
- vfp_reg_offset(1, rn),
217
- vfp_reg_offset(1, rm),
218
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
219
opr_sz, opr_sz, data, fn_gvec);
220
}
221
return 0;
222
--
139
--
223
2.20.1
140
2.20.1
224
141
225
142
diff view generated by jsdifflib