1
Another arm pullreq; nothing particularly exciting here.
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
-- PMM
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
5
6
The following changes since commit e27d5b488ef08408691bfed61f34ee2858136287:
7
8
Merge remote-tracking branch 'remotes/juanquintela/tags/pull-migration-pull-request' into staging (2020-02-28 14:02:31 +0000)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200228
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
13
8
14
for you to fetch changes up to 1904f9b5f1d94fe12fe021db6b504c87d684f6db:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
15
10
16
hw/intc/arm_gic_kvm: Don't assume kernel can provide a GICv2 (2020-02-28 16:14:57 +0000)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* hw/arm: Use TYPE_PL011 to create serial port
15
* more MVE instructions
21
* target/arm: Set ID_MMFR4.HPDS for aarch64_max_initfn
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
22
* hw/arm/integratorcp: Map the audio codec controller
17
* target/arm: Check NaN mode before silencing NaN
23
* GICv2: Correctly implement the limited number of priority bits
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
24
* target/arm: refactoring of VFP related feature checks and decode
19
* hw/arm: Add basic power management to raspi.
25
* xilinx_zynq: Fix USB port instantiation
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
26
* acceptance tests for n800, n810, integratorcp
27
* Implement v8.3-RCPC, v8.4-RCPC, v8.3-CCIDX
28
* arm_gic_kvm: Don't assume kernel can provide a GICv2
29
(provide better error message for user error)
30
21
31
----------------------------------------------------------------
22
----------------------------------------------------------------
32
Gavin Shan (1):
23
Joe Komlodi (1):
33
hw/arm: Use TYPE_PL011 to create serial port
24
target/arm: Check NaN mode before silencing NaN
34
25
35
Guenter Roeck (2):
26
Maxim Uvarov (1):
36
hw/arm/xilinx_zynq: Fix USB port instantiation
27
hw/gpio/gpio_pwr: use shutdown function for reboot
37
hw/usb/hcd-ehci-sysbus: Remove obsolete xlnx, ps7-usb class
38
28
39
Peter Maydell (5):
29
Nolan Leake (1):
40
target/arm: Fix wrong use of FIELD_EX32 on ID_AA64DFR0
30
hw/arm: Add basic power management to raspi.
41
target/arm: Implement v8.3-RCPC
42
target/arm: Implement v8.4-RCPC
43
target/arm: Implement ARMv8.3-CCIDX
44
hw/intc/arm_gic_kvm: Don't assume kernel can provide a GICv2
45
31
46
Philippe Mathieu-Daudé (3):
32
Patrick Venture (2):
47
hw/arm/integratorcp: Map the audio codec controller
33
docs/system/arm: Add quanta-q7l1-bmc reference
48
tests/acceptance: Extract boot_integratorcp() from test_integratorcp()
34
docs/system/arm: Add quanta-gbs-bmc reference
49
tests/acceptance/integratorcp: Verify Tux is displayed on framebuffer
50
35
51
Richard Henderson (17):
36
Peter Maydell (18):
52
target/arm: Set ID_MMFR4.HPDS for aarch64_max_initfn
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
53
target/arm: Add isar_feature_aa32_vfp_simd
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
54
target/arm: Rename isar_feature_aa32_fpdp_v2
39
target/arm: Make asimd_imm_const() public
55
target/arm: Add isar_feature_aa32_{fpsp_v2, fpsp_v3, fpdp_v3}
40
target/arm: Use asimd_imm_const for A64 decode
56
target/arm: Add isar_feature_aa64_fp_simd, isar_feature_aa32_vfp
41
target/arm: Use dup_const() instead of bitfield_replicate()
57
target/arm: Perform fpdp_v2 check first
42
target/arm: Implement MVE logical immediate insns
58
target/arm: Replace ARM_FEATURE_VFP3 checks with fp{sp, dp}_v3
43
target/arm: Implement MVE vector shift left by immediate insns
59
target/arm: Add missing checks for fpsp_v2
44
target/arm: Implement MVE vector shift right by immediate insns
60
target/arm: Replace ARM_FEATURE_VFP4 with isar_feature_aa32_simdfmac
45
target/arm: Implement MVE VSHLL
61
target/arm: Remove ARM_FEATURE_VFP check from disas_vfp_insn
46
target/arm: Implement MVE VSRI, VSLI
62
target/arm: Move VLLDM and VLSTM to vfp.decode
47
target/arm: Implement MVE VSHRN, VRSHRN
63
target/arm: Move the vfp decodetree calls next to the base isa
48
target/arm: Implement MVE saturating narrowing shifts
64
linux-user/arm: Replace ARM_FEATURE_VFP* tests for HWCAP
49
target/arm: Implement MVE VSHLC
65
target/arm: Remove ARM_FEATURE_VFP*
50
target/arm: Implement MVE VADDLV
66
target/arm: Add formats for some vfp 2 and 3-register insns
51
target/arm: Implement MVE long shifts by immediate
67
target/arm: Split VFM decode
52
target/arm: Implement MVE long shifts by register
68
target/arm: Split VMINMAXNM decode
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
69
55
70
Sai Pavan Boddu (3):
56
Philippe Mathieu-Daudé (1):
71
arm_gic: Mask the un-supported priority bits
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
72
cpu/a9mpcore: Set number of GIC priority bits to 5
73
cpu/arm11mpcore: Set number of GIC priority bits to 4
74
58
75
Thomas Huth (2):
59
docs/system/arm/aspeed.rst | 1 +
76
tests/acceptance: Add a test for the N800 and N810 arm machines
60
docs/system/arm/nuvoton.rst | 5 +-
77
tests/acceptance: Add a test for the integratorcp arm machine
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
78
82
79
include/hw/intc/arm_gic.h | 2 +
80
include/hw/intc/arm_gic_common.h | 1 +
81
target/arm/cpu.h | 88 +++++-
82
hw/arm/integratorcp.c | 1 +
83
hw/arm/sbsa-ref.c | 3 +-
84
hw/arm/virt.c | 3 +-
85
hw/arm/xilinx_zynq.c | 5 +-
86
hw/arm/xlnx-versal.c | 3 +-
87
hw/cpu/a9mpcore.c | 4 +
88
hw/cpu/arm11mpcore.c | 5 +
89
hw/intc/arm_gic.c | 33 +-
90
hw/intc/arm_gic_common.c | 1 +
91
hw/intc/arm_gic_kvm.c | 9 +
92
hw/intc/armv7m_nvic.c | 20 +-
93
hw/usb/hcd-ehci-sysbus.c | 17 -
94
linux-user/arm/signal.c | 4 +-
95
linux-user/elfload.c | 25 +-
96
target/arm/arch_dump.c | 11 +-
97
target/arm/cpu.c | 44 +--
98
target/arm/cpu64.c | 5 +-
99
target/arm/helper.c | 23 +-
100
target/arm/kvm32.c | 5 -
101
target/arm/kvm64.c | 1 -
102
target/arm/m_helper.c | 11 +-
103
target/arm/machine.c | 5 +-
104
target/arm/translate-a64.c | 114 +++++++
105
target/arm/translate-vfp.inc.c | 448 +++++++++++++++++----------
106
target/arm/translate.c | 122 ++------
107
MAINTAINERS | 2 +
108
hw/arm/Kconfig | 1 +
109
target/arm/vfp-uncond.decode | 12 +-
110
target/arm/vfp.decode | 153 ++++-----
111
tests/acceptance/machine_arm_integratorcp.py | 99 ++++++
112
tests/acceptance/machine_arm_n8x0.py | 49 +++
113
34 files changed, 865 insertions(+), 464 deletions(-)
114
create mode 100644 tests/acceptance/machine_arm_integratorcp.py
115
create mode 100644 tests/acceptance/machine_arm_n8x0.py
116
diff view generated by jsdifflib
Deleted patch
1
From: Gavin Shan <gshan@redhat.com>
2
1
3
This uses TYPE_PL011 when creating the serial port so that the code
4
looks cleaner.
5
6
Signed-off-by: Gavin Shan <gshan@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20200224222223.4128-1-gshan@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/sbsa-ref.c | 3 ++-
13
hw/arm/virt.c | 3 ++-
14
hw/arm/xlnx-versal.c | 3 ++-
15
3 files changed, 6 insertions(+), 3 deletions(-)
16
17
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/sbsa-ref.c
20
+++ b/hw/arm/sbsa-ref.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/pci-host/gpex.h"
23
#include "hw/qdev-properties.h"
24
#include "hw/usb.h"
25
+#include "hw/char/pl011.h"
26
#include "net/net.h"
27
28
#define RAMLIMIT_GB 8192
29
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, int uart,
30
{
31
hwaddr base = sbsa_ref_memmap[uart].base;
32
int irq = sbsa_ref_irqmap[uart];
33
- DeviceState *dev = qdev_create(NULL, "pl011");
34
+ DeviceState *dev = qdev_create(NULL, TYPE_PL011);
35
SysBusDevice *s = SYS_BUS_DEVICE(dev);
36
37
qdev_prop_set_chr(dev, "chardev", chr);
38
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/virt.c
41
+++ b/hw/arm/virt.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/mem/nvdimm.h"
44
#include "hw/acpi/generic_event_device.h"
45
#include "hw/virtio/virtio-iommu.h"
46
+#include "hw/char/pl011.h"
47
48
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
49
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
50
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, int uart,
51
int irq = vms->irqmap[uart];
52
const char compat[] = "arm,pl011\0arm,primecell";
53
const char clocknames[] = "uartclk\0apb_pclk";
54
- DeviceState *dev = qdev_create(NULL, "pl011");
55
+ DeviceState *dev = qdev_create(NULL, TYPE_PL011);
56
SysBusDevice *s = SYS_BUS_DEVICE(dev);
57
58
qdev_prop_set_chr(dev, "chardev", chr);
59
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/xlnx-versal.c
62
+++ b/hw/arm/xlnx-versal.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/misc/unimp.h"
65
#include "hw/intc/arm_gicv3_common.h"
66
#include "hw/arm/xlnx-versal.h"
67
+#include "hw/char/pl011.h"
68
69
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
70
#define GEM_REVISION 0x40070106
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
72
DeviceState *dev;
73
MemoryRegion *mr;
74
75
- dev = qdev_create(NULL, "pl011");
76
+ dev = qdev_create(NULL, TYPE_PL011);
77
s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
78
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
79
object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
80
--
81
2.20.1
82
83
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
We had set this for aarch32-only in arm_max_initfn, but
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
failed to set the same bit for aarch64.
4
entry.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Message-id: 20200218190958.745-2-richard.henderson@linaro.org
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu64.c | 1 +
11
docs/system/arm/aspeed.rst | 1 +
12
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
13
13
14
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu64.c
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/target/arm/cpu64.c
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ etc.
19
cpu->isar.id_mmfr3 = u;
19
AST2400 SoC based machines :
20
20
21
u = cpu->isar.id_mmfr4;
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
22
+ u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
23
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
23
24
cpu->isar.id_mmfr4 = u;
24
AST2500 SoC based machines :
25
25
26
--
26
--
27
2.20.1
27
2.20.1
28
28
29
29
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The Linux kernel displays errors why trying to detect the PL041
4
audio interface:
5
6
Linux version 4.16.0 (linus@genomnajs) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #142 PREEMPT Wed May 9 13:24:55 CEST 2018
7
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00093177
8
CPU: VIVT data cache, VIVT instruction cache
9
OF: fdt: Machine model: ARM Integrator/CP
10
...
11
OF: amba_device_add() failed (-19) for /fpga/aaci@1d000000
12
13
Since we have it already modelled, simply plug it.
14
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200223233033.15371-2-f4bug@amsat.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/integratorcp.c | 1 +
21
hw/arm/Kconfig | 1 +
22
2 files changed, 2 insertions(+)
23
24
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/integratorcp.c
27
+++ b/hw/arm/integratorcp.c
28
@@ -XXX,XX +XXX,XX @@ static void integratorcp_init(MachineState *machine)
29
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
30
qdev_connect_gpio_out(dev, 1,
31
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));
32
+ sysbus_create_varargs("pl041", 0x1d000000, pic[25], NULL);
33
34
if (nd_table[0].used)
35
smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
36
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/Kconfig
39
+++ b/hw/arm/Kconfig
40
@@ -XXX,XX +XXX,XX @@ config INTEGRATOR
41
select INTEGRATOR_DEBUG
42
select PL011 # UART
43
select PL031 # RTC
44
+ select PL041 # audio
45
select PL050 # keyboard/mouse
46
select PL110 # pl111 LCD controller
47
select PL181 # display
48
--
49
2.20.1
50
51
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Patrick Venture <venture@google.com>
2
2
3
USB ports on Xilinx Zync must be instantiated as TYPE_CHIPIDEA to work.
3
Add line item reference to quanta-gbs-bmc machine.
4
Linux expects and checks various chipidea registers, which do not exist
5
with the basic ehci emulation. This patch series fixes the problem.
6
4
7
Without this patch, USB ports fail to instantiate under Linux.
5
Signed-off-by: Patrick Venture <venture@google.com>
8
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
ci_hdrc ci_hdrc.0: doesn't support host
7
Message-id: 20210615192848.1065297-3-venture@google.com
10
ci_hdrc ci_hdrc.0: no supported roles
8
[PMM: fixed underline Sphinx warning]
11
12
With this patch, USB ports are instantiated, and it is possible
13
to boot from USB drive.
14
15
ci_hdrc ci_hdrc.0: EHCI Host Controller
16
ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
17
ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
18
usb 1-1: new full-speed USB device number 2 using ci_hdrc
19
usb 1-1: not running at top speed; connect to a high speed hub
20
usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x81 has invalid maxpacket 512, setting to 64
21
usb 1-1: config 1 interface 0 altsetting 0 endpoint 0x2 has invalid maxpacket 512, setting to 64
22
usb-storage 1-1:1.0: USB Mass Storage device detected
23
scsi host0: usb-storage 1-1:1.0
24
25
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
26
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
27
Message-id: 20200215122354.13706-2-linux@roeck-us.net
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
10
---
30
hw/arm/xilinx_zynq.c | 5 +++--
11
docs/system/arm/nuvoton.rst | 5 +++--
31
1 file changed, 3 insertions(+), 2 deletions(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
32
13
33
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
34
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/xilinx_zynq.c
16
--- a/docs/system/arm/nuvoton.rst
36
+++ b/hw/arm/xilinx_zynq.c
17
+++ b/docs/system/arm/nuvoton.rst
37
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
38
#include "hw/loader.h"
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
39
#include "hw/misc/zynq-xadc.h"
20
-=====================================================
40
#include "hw/ssi/ssi.h"
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
41
+#include "hw/usb/chipidea.h"
22
+================================================================
42
#include "qemu/error-report.h"
23
43
#include "hw/sd/sdhci.h"
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
44
#include "hw/char/cadence_uart.h"
25
designed to be used as Baseboard Management Controllers (BMCs) in various
45
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
46
zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false);
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
47
zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true);
28
Hyperscale applications. The following machines are based on this chip :
48
29
49
- sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
50
- sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
31
- ``quanta-gsj`` Quanta GSJ server BMC
51
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]);
32
52
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]);
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
53
54
cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
55
cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
56
--
34
--
57
2.20.1
35
2.20.1
58
36
59
37
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
Old kernels from the Meego project can be used to check that Linux
3
This is just enough to make reboot and poweroff work. Works for
4
is at least starting on these machines.
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
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
do what linux does for reset.
7
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
The watchdog timer functionality is not yet implemented.
9
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Message-id: 20200225172501.29609-2-philmd@redhat.com
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Message-Id: <20200129131920.22302-1-thuth@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
18
---
16
MAINTAINERS | 1 +
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
17
tests/acceptance/machine_arm_n8x0.py | 49 ++++++++++++++++++++++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
18
2 files changed, 50 insertions(+)
21
hw/arm/bcm2835_peripherals.c | 13 ++-
19
create mode 100644 tests/acceptance/machine_arm_n8x0.py
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
20
23
hw/misc/meson.build | 1 +
21
diff --git a/MAINTAINERS b/MAINTAINERS
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
22
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
23
--- a/MAINTAINERS
30
--- a/include/hw/arm/bcm2835_peripherals.h
24
+++ b/MAINTAINERS
31
+++ b/include/hw/arm/bcm2835_peripherals.h
25
@@ -XXX,XX +XXX,XX @@ F: hw/rtc/twl92230.c
32
@@ -XXX,XX +XXX,XX @@
26
F: include/hw/display/blizzard.h
33
#include "hw/misc/bcm2835_mphi.h"
27
F: include/hw/input/tsc2xxx.h
34
#include "hw/misc/bcm2835_thermal.h"
28
F: include/hw/misc/cbus.h
35
#include "hw/misc/bcm2835_cprman.h"
29
+F: tests/acceptance/machine_arm_n8x0.py
36
+#include "hw/misc/bcm2835_powermgt.h"
30
37
#include "hw/sd/sdhci.h"
31
Palm
38
#include "hw/sd/bcm2835_sdhost.h"
32
M: Andrzej Zaborowski <balrogg@gmail.com>
39
#include "hw/gpio/bcm2835_gpio.h"
33
diff --git a/tests/acceptance/machine_arm_n8x0.py b/tests/acceptance/machine_arm_n8x0.py
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
34
new file mode 100644
50
new file mode 100644
35
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
36
--- /dev/null
52
--- /dev/null
37
+++ b/tests/acceptance/machine_arm_n8x0.py
53
+++ b/include/hw/misc/bcm2835_powermgt.h
38
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
39
+# Functional test that boots a Linux kernel and checks the console
55
+/*
40
+#
56
+ * BCM2835 Power Management emulation
41
+# Copyright (c) 2020 Red Hat, Inc.
57
+ *
42
+#
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
43
+# Author:
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
44
+# Thomas Huth <thuth@redhat.com>
60
+ *
45
+#
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
46
+# This work is licensed under the terms of the GNU GPL, version 2 or
62
+ * See the COPYING file in the top-level directory.
47
+# later. See the COPYING file in the top-level directory.
63
+ */
48
+
64
+
49
+import os
65
+#ifndef BCM2835_POWERMGT_H
50
+
66
+#define BCM2835_POWERMGT_H
51
+from avocado import skipUnless
67
+
52
+from avocado_qemu import Test
68
+#include "hw/sysbus.h"
53
+from avocado_qemu import wait_for_console_pattern
69
+#include "qom/object.h"
54
+
70
+
55
+class N8x0Machine(Test):
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
56
+ """Boots the Linux kernel and checks that the console is operational"""
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
57
+
73
+
58
+ timeout = 90
74
+struct BCM2835PowerMgtState {
59
+
75
+ SysBusDevice busdev;
60
+ def __do_test_n8x0(self):
76
+ MemoryRegion iomem;
61
+ kernel_url = ('http://stskeeps.subnetmask.net/meego-n8x0/'
77
+
62
+ 'meego-arm-n8x0-1.0.80.20100712.1431-'
78
+ uint32_t rstc;
63
+ 'vmlinuz-2.6.35~rc4-129.1-n8x0')
79
+ uint32_t rsts;
64
+ kernel_hash = 'e9d5ab8d7548923a0061b6fbf601465e479ed269'
80
+ uint32_t wdog;
65
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
81
+};
66
+
82
+
67
+ self.vm.set_console(console_index=1)
83
+#endif
68
+ self.vm.add_args('-kernel', kernel_path,
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
69
+ '-append', 'printk.time=0 console=ttyS1')
85
index XXXXXXX..XXXXXXX 100644
70
+ self.vm.launch()
86
--- a/hw/arm/bcm2835_peripherals.c
71
+ wait_for_console_pattern(self, 'TSC2005 driver initializing')
87
+++ b/hw/arm/bcm2835_peripherals.c
72
+
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
73
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
89
74
+ def test_n800(self):
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
75
+ """
91
OBJECT(&s->gpu_bus_mr));
76
+ :avocado: tags=arch:arm
92
+
77
+ :avocado: tags=machine:n800
93
+ /* Power Management */
78
+ """
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
79
+ self.__do_test_n8x0()
95
+ TYPE_BCM2835_POWERMGT);
80
+
96
}
81
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
97
82
+ def test_n810(self):
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
83
+ """
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
84
+ :avocado: tags=arch:arm
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
85
+ :avocado: tags=machine:n810
101
INTERRUPT_USB));
86
+ """
102
87
+ self.__do_test_n8x0()
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
286
+++ b/hw/misc/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
288
'bcm2835_rng.c',
289
'bcm2835_thermal.c',
290
'bcm2835_cprman.c',
291
+ 'bcm2835_powermgt.c',
292
))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
88
--
295
--
89
2.20.1
296
2.20.1
90
297
91
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add a test that verifies the Tux logo is displayed on the framebuffer.
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
4
5
5
We simply follow the OpenCV "Template Matching with Multiple Objects"
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
tutorial, replacing Lionel Messi by Tux:
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
https://docs.opencv.org/4.2.0/d4/dc6/tutorial_py_template_matching.html
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
8
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
9
When OpenCV and NumPy are installed, this test can be run using:
10
console: [ 0.000000] CPU: div instructions available: patching division code
10
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
11
$ AVOCADO_ALLOW_UNTRUSTED_CODE=hmmm \
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
12
avocado --show=app,framebuffer run -t device:framebuffer \
13
...
13
tests/acceptance/machine_arm_integratorcp.py
14
console: Boot successful.
14
JOB ID : 8c46b0f8269242e87d738247883ea2a470df949e
15
console: cat /proc/cpuinfo
15
JOB LOG : avocado/job-results/job-2020-01-31T21.38-8c46b0f/job.log
16
console: / # cat /proc/cpuinfo
16
(1/1) tests/acceptance/machine_arm_integratorcp.py:IntegratorMachine.test_framebuffer_tux_logo:
17
...
17
framebuffer: found Tux at position [x, y] = (0, 0)
18
console: processor : 3
18
PASS (3.96 s)
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)
19
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
20
JOB TIME : 4.23 s
43
JOB TIME : 25.02 s
21
44
22
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
24
Message-id: 20200225172501.29609-5-philmd@redhat.com
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
25
Message-Id: <20200131211102.29612-3-f4bug@amsat.org>
26
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
49
---
29
tests/acceptance/machine_arm_integratorcp.py | 52 ++++++++++++++++++++
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
30
1 file changed, 52 insertions(+)
51
1 file changed, 43 insertions(+)
31
52
32
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
33
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/acceptance/machine_arm_integratorcp.py
55
--- a/tests/acceptance/boot_linux_console.py
35
+++ b/tests/acceptance/machine_arm_integratorcp.py
56
+++ b/tests/acceptance/boot_linux_console.py
36
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
37
# later. See the COPYING file in the top-level directory.
58
from avocado import skip
38
39
import os
40
+import logging
41
42
from avocado import skipUnless
59
from avocado import skipUnless
43
from avocado_qemu import Test
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
44
from avocado_qemu import wait_for_console_pattern
64
from avocado_qemu import wait_for_console_pattern
45
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')
46
+
81
+
47
+NUMPY_AVAILABLE = True
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
48
+try:
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
49
+ import numpy as np
84
+ 'arm/rootfs-armv7a.cpio.gz')
50
+except ImportError:
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
51
+ NUMPY_AVAILABLE = False
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)
52
+
89
+
53
+CV2_AVAILABLE = True
90
+ self.vm.set_console()
54
+try:
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
55
+ import cv2
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
56
+except ImportError:
93
+ 'panic=-1 noreboot ' +
57
+ CV2_AVAILABLE = False
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.')
58
+
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()
59
+
110
+
60
class IntegratorMachine(Test):
111
def test_arm_exynos4210_initrd(self):
61
62
timeout = 90
63
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
64
"""
112
"""
65
self.boot_integratorcp()
113
:avocado: tags=arch:arm
66
wait_for_console_pattern(self, 'Log in as root')
67
+
68
+ @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
69
+ @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed')
70
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
71
+ def test_framebuffer_tux_logo(self):
72
+ """
73
+ Boot Linux and verify the Tux logo is displayed on the framebuffer.
74
+ :avocado: tags=arch:arm
75
+ :avocado: tags=machine:integratorcp
76
+ :avocado: tags=device:pl110
77
+ :avocado: tags=device:framebuffer
78
+ """
79
+ screendump_path = os.path.join(self.workdir, "screendump.pbm")
80
+ tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/'
81
+ 'drivers/video/logo/logo_linux_vga16.ppm')
82
+ tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af'
83
+ tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash)
84
+
85
+ self.boot_integratorcp()
86
+ framebuffer_ready = 'Console: switching to colour frame buffer device'
87
+ wait_for_console_pattern(self, framebuffer_ready)
88
+ self.vm.command('human-monitor-command', command_line='stop')
89
+ self.vm.command('human-monitor-command',
90
+ command_line='screendump %s' % screendump_path)
91
+ logger = logging.getLogger('framebuffer')
92
+
93
+ cpu_count = 1
94
+ match_threshold = 0.92
95
+ screendump_bgr = cv2.imread(screendump_path)
96
+ screendump_gray = cv2.cvtColor(screendump_bgr, cv2.COLOR_BGR2GRAY)
97
+ result = cv2.matchTemplate(screendump_gray, cv2.imread(tuxlogo_path, 0),
98
+ cv2.TM_CCOEFF_NORMED)
99
+ loc = np.where(result >= match_threshold)
100
+ tux_count = 0
101
+ for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
102
+ logger.debug('found Tux at position [x, y] = %s', pt)
103
+ self.assertGreaterEqual(tux_count, cpu_count)
104
--
114
--
105
2.20.1
115
2.20.1
106
116
107
117
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
All A9 CPUs have a GIC with 5 bits of priority.
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
4
6
5
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
7
To avoid this, we check to see what NaN mode we're running in before we call
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
floatxx_silence_nan().
7
Message-id: 1582537164-764-3-git-send-email-sai.pavan.boddu@xilinx.com
9
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
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
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/cpu/a9mpcore.c | 4 ++++
16
target/arm/helper-a64.c | 12 +++++++++---
13
1 file changed, 4 insertions(+)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
14
19
15
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/cpu/a9mpcore.c
22
--- a/target/arm/helper-a64.c
18
+++ b/hw/cpu/a9mpcore.c
23
+++ b/target/arm/helper-a64.c
19
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
20
#include "hw/qdev-properties.h"
25
float16 nan = a;
21
#include "hw/core/cpu.h"
26
if (float16_is_signaling_nan(a, fpst)) {
22
27
float_raise(float_flag_invalid, fpst);
23
+#define A9_GIC_NUM_PRIORITY_BITS 5
28
- nan = float16_silence_nan(a, fpst);
24
+
29
+ if (!fpst->default_nan_mode) {
25
static void a9mp_priv_set_irq(void *opaque, int irq, int level)
30
+ nan = float16_silence_nan(a, fpst);
26
{
31
+ }
27
A9MPPrivState *s = (A9MPPrivState *)opaque;
32
}
28
@@ -XXX,XX +XXX,XX @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
33
if (fpst->default_nan_mode) {
29
gicdev = DEVICE(&s->gic);
34
nan = float16_default_nan(fpst);
30
qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
31
qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
36
float32 nan = a;
32
+ qdev_prop_set_uint32(gicdev, "num-priority-bits",
37
if (float32_is_signaling_nan(a, fpst)) {
33
+ A9_GIC_NUM_PRIORITY_BITS);
38
float_raise(float_flag_invalid, fpst);
34
39
- nan = float32_silence_nan(a, fpst);
35
/* Make the GIC's TZ support match the CPUs. We assume that
40
+ if (!fpst->default_nan_mode) {
36
* either all the CPUs have TZ, or none do.
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);
37
--
127
--
38
2.20.1
128
2.20.1
39
129
40
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
Use this in the places that were checking ARM_FEATURE_VFP, and
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
are obviously testing for the existance of the register set
4
function has to be used for machine shutdown. Otherwise we cause
5
as opposed to testing for some particular instruction extension.
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200224222232.13807-2-richard.henderson@linaro.org
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
10
[PMM: tweaked commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/cpu.h | 9 +++++++++
13
hw/gpio/gpio_pwr.c | 2 +-
13
hw/intc/armv7m_nvic.c | 20 ++++++++++----------
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
linux-user/arm/signal.c | 4 ++--
15
target/arm/arch_dump.c | 11 ++++++-----
16
target/arm/cpu.c | 4 ++--
17
target/arm/helper.c | 4 ++--
18
target/arm/m_helper.c | 11 ++++++-----
19
7 files changed, 37 insertions(+), 26 deletions(-)
20
15
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
18
--- a/hw/gpio/gpio_pwr.c
24
+++ b/target/arm/cpu.h
19
+++ b/hw/gpio/gpio_pwr.c
25
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
26
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
22
{
23
if (level) {
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
26
}
27
}
27
}
28
28
29
+static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
30
+{
31
+ /*
32
+ * Return true if either VFP or SIMD is implemented.
33
+ * In this case, a minimum of VFP w/ D0-D15.
34
+ */
35
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
36
+}
37
+
38
static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
39
{
40
/* Return true if D16-D31 are implemented */
41
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/intc/armv7m_nvic.c
44
+++ b/hw/intc/armv7m_nvic.c
45
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
46
case 0xd84: /* CSSELR */
47
return cpu->env.v7m.csselr[attrs.secure];
48
case 0xd88: /* CPACR */
49
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
50
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
51
return 0;
52
}
53
return cpu->env.v7m.cpacr[attrs.secure];
54
case 0xd8c: /* NSACR */
55
- if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
56
+ if (!attrs.secure || !cpu_isar_feature(aa32_vfp_simd, cpu)) {
57
return 0;
58
}
59
return cpu->env.v7m.nsacr;
60
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
61
}
62
return cpu->env.v7m.sfar;
63
case 0xf34: /* FPCCR */
64
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
65
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
66
return 0;
67
}
68
if (attrs.secure) {
69
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
70
return value;
71
}
72
case 0xf38: /* FPCAR */
73
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
74
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
75
return 0;
76
}
77
return cpu->env.v7m.fpcar[attrs.secure];
78
case 0xf3c: /* FPDSCR */
79
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
80
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
81
return 0;
82
}
83
return cpu->env.v7m.fpdscr[attrs.secure];
84
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
85
}
86
break;
87
case 0xd88: /* CPACR */
88
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
90
/* We implement only the Floating Point extension's CP10/CP11 */
91
cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
92
}
93
break;
94
case 0xd8c: /* NSACR */
95
- if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
96
+ if (attrs.secure && cpu_isar_feature(aa32_vfp_simd, cpu)) {
97
/* We implement only the Floating Point extension's CP10/CP11 */
98
cpu->env.v7m.nsacr = value & (3 << 10);
99
}
100
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
101
break;
102
}
103
case 0xf34: /* FPCCR */
104
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
105
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
106
/* Not all bits here are banked. */
107
uint32_t fpccr_s;
108
109
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
110
}
111
break;
112
case 0xf38: /* FPCAR */
113
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
114
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
115
value &= ~7;
116
cpu->env.v7m.fpcar[attrs.secure] = value;
117
}
118
break;
119
case 0xf3c: /* FPDSCR */
120
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
121
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
122
value &= 0x07c00000;
123
cpu->env.v7m.fpdscr[attrs.secure] = value;
124
}
125
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/linux-user/arm/signal.c
128
+++ b/linux-user/arm/signal.c
129
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
130
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
131
/* Save coprocessor signal frame. */
132
regspace = uc->tuc_regspace;
133
- if (arm_feature(env, ARM_FEATURE_VFP)) {
134
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
135
regspace = setup_sigframe_v2_vfp(regspace, env);
136
}
137
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
138
@@ -XXX,XX +XXX,XX @@ static int do_sigframe_return_v2(CPUARMState *env,
139
140
/* Restore coprocessor signal frame */
141
regspace = uc->tuc_regspace;
142
- if (arm_feature(env, ARM_FEATURE_VFP)) {
143
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
144
regspace = restore_sigframe_v2_vfp(env, regspace);
145
if (!regspace) {
146
return 1;
147
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/target/arm/arch_dump.c
150
+++ b/target/arm/arch_dump.c
151
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
152
int cpuid, void *opaque)
153
{
154
struct arm_note note;
155
- CPUARMState *env = &ARM_CPU(cs)->env;
156
+ ARMCPU *cpu = ARM_CPU(cs);
157
+ CPUARMState *env = &cpu->env;
158
DumpState *s = opaque;
159
- int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);
160
+ int ret, i;
161
+ bool fpvalid = cpu_isar_feature(aa32_vfp_simd, cpu);
162
163
arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));
164
165
@@ -XXX,XX +XXX,XX @@ int cpu_get_dump_info(ArchDumpInfo *info,
166
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
167
{
168
ARMCPU *cpu = ARM_CPU(first_cpu);
169
- CPUARMState *env = &cpu->env;
170
size_t note_size;
171
172
if (class == ELFCLASS64) {
173
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
174
note_size += AARCH64_PRFPREG_NOTE_SIZE;
175
#ifdef TARGET_AARCH64
176
if (cpu_isar_feature(aa64_sve, cpu)) {
177
- note_size += AARCH64_SVE_NOTE_SIZE(env);
178
+ note_size += AARCH64_SVE_NOTE_SIZE(&cpu->env);
179
}
180
#endif
181
} else {
182
note_size = ARM_PRSTATUS_NOTE_SIZE;
183
- if (arm_feature(env, ARM_FEATURE_VFP)) {
184
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
185
note_size += ARM_VFP_NOTE_SIZE;
186
}
187
}
188
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
189
index XXXXXXX..XXXXXXX 100644
190
--- a/target/arm/cpu.c
191
+++ b/target/arm/cpu.c
192
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
193
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
194
}
195
196
- if (arm_feature(env, ARM_FEATURE_VFP)) {
197
+ if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
198
env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
199
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
200
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
201
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
202
int numvfpregs = 0;
203
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
204
numvfpregs = 32;
205
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
206
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
207
numvfpregs = 16;
208
}
209
for (i = 0; i < numvfpregs; i++) {
210
diff --git a/target/arm/helper.c b/target/arm/helper.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/target/arm/helper.c
213
+++ b/target/arm/helper.c
214
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
215
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
216
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
217
*/
218
- if (arm_feature(env, ARM_FEATURE_VFP)) {
219
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
220
/* VFP coprocessor: cp10 & cp11 [23:20] */
221
mask |= (1 << 31) | (1 << 30) | (0xf << 20);
222
223
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
224
} else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
225
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
226
35, "arm-vfp3.xml", 0);
227
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
228
+ } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
229
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
230
19, "arm-vfp.xml", 0);
231
}
232
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/arm/m_helper.c
235
+++ b/target/arm/m_helper.c
236
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
237
*/
238
uint32_t sig = 0xfefa125a;
239
240
- if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
241
+ if (!cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))
242
+ || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
243
sig |= 1;
244
}
245
return sig;
246
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
247
248
if (dotailchain) {
249
/* Sanitize LR FType and PREFIX bits */
250
- if (!arm_feature(env, ARM_FEATURE_VFP)) {
251
+ if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
252
lr |= R_V7M_EXCRET_FTYPE_MASK;
253
}
254
lr = deposit32(lr, 24, 8, 0xff);
255
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
256
257
ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
258
259
- if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
260
+ if (!ftype && !cpu_isar_feature(aa32_vfp_simd, cpu)) {
261
qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
262
"exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
263
"if FPU not present\n",
264
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
265
* SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
266
* RES0 if the FPU is not present, and is stored in the S bank
267
*/
268
- if (arm_feature(env, ARM_FEATURE_VFP) &&
269
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env)) &&
270
extract32(env->v7m.nsacr, 10, 1)) {
271
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
272
env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
273
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
274
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
275
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
276
}
277
- if (arm_feature(env, ARM_FEATURE_VFP)) {
278
+ if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
279
/*
280
* SFPA is RAZ/WI from NS or if no FPU.
281
* FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
282
--
29
--
283
2.20.1
30
2.20.1
284
31
285
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In do_ldst(), the calculation of the offset needs to be based on the
2
size of the memory access, not the size of the elements in the
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
2
5
3
The old name, isar_feature_aa32_fpdp, does not reflect
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
that the test includes VFPv2. We will introduce another
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
feature tests for VFPv3.
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-mve.c | 17 +++++++++--------
11
1 file changed, 9 insertions(+), 8 deletions(-)
6
12
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200224222232.13807-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 4 ++--
13
target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
14
2 files changed, 22 insertions(+), 22 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
15
--- a/target/arm/translate-mve.c
19
+++ b/target/arm/cpu.h
16
+++ b/target/arm/translate-mve.c
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
21
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
18
}
22
}
19
}
23
20
24
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
25
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
23
+ unsigned msize)
26
{
24
{
27
- /* Return true if CPU supports double precision floating point */
25
TCGv_i32 addr;
28
+ /* Return true if CPU supports double precision floating point, VFPv2 */
26
uint32_t offset;
29
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
28
return true;
29
}
30
31
- offset = a->imm << a->size;
32
+ offset = a->imm << msize;
33
if (!a->a) {
34
offset = -offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
38
{ NULL, NULL }
39
};
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
30
}
42
}
31
43
32
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
33
index XXXXXXX..XXXXXXX 100644
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
34
--- a/target/arm/translate-vfp.inc.c
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
35
+++ b/target/arm/translate-vfp.inc.c
47
{ \
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
37
return false;
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); \
38
}
54
}
39
55
40
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
41
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
42
return false;
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
43
}
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
44
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
45
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
46
return false;
62
47
}
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
48
64
{
49
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
50
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
51
return false;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
55
return false;
56
}
57
58
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
59
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
60
return false;
61
}
62
63
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
64
return false;
65
}
66
67
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
68
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
69
return false;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
73
return false;
74
}
75
76
- if (!dc_isar_feature(aa32_fpdp, s)) {
77
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
78
return false;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
82
return false;
83
}
84
85
- if (!dc_isar_feature(aa32_fpdp, s)) {
86
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
87
return false;
88
}
89
90
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
91
return false;
92
}
93
94
- if (!dc_isar_feature(aa32_fpdp, s)) {
95
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
96
return false;
97
}
98
99
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
100
return false;
101
}
102
103
- if (!dc_isar_feature(aa32_fpdp, s)) {
104
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
105
return false;
106
}
107
108
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
109
return false;
110
}
111
112
- if (!dc_isar_feature(aa32_fpdp, s)) {
113
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
114
return false;
115
}
116
117
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
118
return false;
119
}
120
121
- if (!dc_isar_feature(aa32_fpdp, s)) {
122
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
123
return false;
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
127
return false;
128
}
129
130
- if (!dc_isar_feature(aa32_fpdp, s)) {
131
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
132
return false;
133
}
134
135
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
136
return false;
137
}
138
139
- if (!dc_isar_feature(aa32_fpdp, s)) {
140
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
141
return false;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
145
return false;
146
}
147
148
- if (!dc_isar_feature(aa32_fpdp, s)) {
149
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
150
return false;
151
}
152
153
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
154
return false;
155
}
156
157
- if (!dc_isar_feature(aa32_fpdp, s)) {
158
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
159
return false;
160
}
161
162
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
163
return false;
164
}
165
166
- if (!dc_isar_feature(aa32_fpdp, s)) {
167
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
168
return false;
169
}
170
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
172
return false;
173
}
174
175
- if (!dc_isar_feature(aa32_fpdp, s)) {
176
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
177
return false;
178
}
179
180
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
181
return false;
182
}
183
184
- if (!dc_isar_feature(aa32_fpdp, s)) {
185
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
186
return false;
187
}
188
189
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
190
return false;
191
}
192
193
- if (!dc_isar_feature(aa32_fpdp, s)) {
194
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
195
return false;
196
}
197
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
199
return false;
200
}
201
202
- if (!dc_isar_feature(aa32_fpdp, s)) {
203
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
204
return false;
205
}
206
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
208
return false;
209
}
210
211
- if (!dc_isar_feature(aa32_fpdp, s)) {
212
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
213
return false;
214
}
215
216
--
65
--
217
2.20.1
66
2.20.1
218
67
219
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
Sort this check to the start of a trans_* function.
10
In particular, fixing the second of these allows us to recast
4
Merge this with any existing test for fpdp_v2.
11
the implementation to avoid 128-bit arithmetic entirely.
5
12
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Since the element size here is always 4, we can also drop the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
parameterization of ESIZE to make the code a little more readable.
8
Message-id: 20200224222232.13807-8-richard.henderson@linaro.org
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
10
---
20
---
11
target/arm/translate-vfp.inc.c | 24 ++++++++----------------
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
12
1 file changed, 8 insertions(+), 16 deletions(-)
22
1 file changed, 21 insertions(+), 17 deletions(-)
13
23
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
26
--- a/target/arm/mve_helper.c
17
+++ b/target/arm/translate-vfp.inc.c
27
+++ b/target/arm/mve_helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
28
@@ -XXX,XX +XXX,XX @@
19
* VFPv2 allows access to FPSID from userspace; VFPv3 restricts
29
*/
20
* all ID registers to privileged access only.
30
21
*/
31
#include "qemu/osdep.h"
22
- if (IS_USER(s) && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
32
-#include "qemu/int128.h"
23
+ if (IS_USER(s) && dc_isar_feature(aa32_fpsp_v3, s)) {
33
#include "cpu.h"
24
return false;
34
#include "internals.h"
25
}
35
#include "vec_internal.h"
26
ignore_vfp_enabled = true;
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
28
case ARM_VFP_FPINST:
38
29
case ARM_VFP_FPINST2:
39
/*
30
/* Not present in VFPv3 */
40
- * Rounding multiply add long dual accumulate high: we must keep
31
- if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
41
- * a 72-bit internal accumulator value and return the top 64 bits.
32
+ if (IS_USER(s) || dc_isar_feature(aa32_fpsp_v3, s)) {
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
33
return false;
43
+ * this is implemented with a 72-bit internal accumulator value of which
34
}
44
+ * the top 64 bits are returned. We optimize this to avoid having to
35
break;
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
46
+ * is squashed back into 64-bits after each beat.
37
47
*/
38
vd = a->vd;
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
39
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
40
- if (!dc_isar_feature(aa32_fpshvec, s) &&
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
41
- (veclen != 0 || s->vec_stride != 0)) {
51
void *vm, uint64_t a) \
42
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
52
{ \
43
return false;
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; \
44
}
81
}
45
82
46
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
47
+ if (!dc_isar_feature(aa32_fpshvec, s) &&
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
48
+ (veclen != 0 || s->vec_stride != 0)) {
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
49
return false;
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
50
}
87
51
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
53
90
54
vd = a->vd;
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
55
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
56
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
57
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
58
return false;
95
59
}
96
/* Vector add across vector */
60
97
#define DO_VADDV(OP, ESIZE, TYPE) \
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
62
return false;
63
}
64
65
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
66
- return false;
67
- }
68
-
69
if (!vfp_access_check(s)) {
70
return true;
71
}
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
73
TCGv_ptr fpst;
74
int frac_bits;
75
76
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
77
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
78
return false;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
82
TCGv_ptr fpst;
83
int frac_bits;
84
85
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
86
- return false;
87
- }
88
-
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
90
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
91
return false;
92
}
93
94
--
98
--
95
2.20.1
99
2.20.1
96
100
97
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
2
5
3
Have the calls adjacent as an intermediate step toward
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
actually merging the decodes.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
5
14
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
index XXXXXXX..XXXXXXX 100644
8
Message-id: 20200224222232.13807-13-richard.henderson@linaro.org
17
--- a/target/arm/translate.h
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
+++ b/target/arm/translate.h
10
---
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
11
target/arm/translate.c | 83 +++++++++++++++---------------------------
20
return opc | s->be_data;
12
1 file changed, 29 insertions(+), 54 deletions(-)
21
}
13
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
{
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
116
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
117
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
19
tcg_temp_free_i32(tmp);
119
a64_translate_init();
20
}
120
}
21
121
22
-/*
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
23
- * Disassemble a VFP instruction. Returns nonzero if an error occurred
123
+{
24
- * (ie. an undefined instruction).
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
25
- */
125
+ switch (cmode) {
26
-static int disas_vfp_insn(DisasContext *s, uint32_t insn)
126
+ case 0: case 1:
27
-{
127
+ /* no-op */
28
- /*
128
+ break;
29
- * If the decodetree decoder handles this insn it will always
129
+ case 2: case 3:
30
- * emit code to either execute the insn or generate an appropriate
130
+ imm <<= 8;
31
- * exception; so we don't need to ever return non-zero to tell
131
+ break;
32
- * the calling code to emit an UNDEF exception.
132
+ case 4: case 5:
33
- */
133
+ imm <<= 16;
34
- if (extract32(insn, 28, 4) == 0xf) {
134
+ break;
35
- if (disas_vfp_uncond(s, insn)) {
135
+ case 6: case 7:
36
- return 0;
136
+ imm <<= 24;
37
- }
137
+ break;
38
- } else {
138
+ case 8: case 9:
39
- if (disas_vfp(s, insn)) {
139
+ imm |= imm << 16;
40
- return 0;
140
+ break;
41
- }
141
+ case 10: case 11:
42
- }
142
+ imm = (imm << 8) | (imm << 24);
43
- /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
143
+ break;
44
- return 1;
144
+ case 12:
45
-}
145
+ imm = (imm << 8) | 0xff;
46
-
146
+ break;
47
static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
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)
48
{
181
{
49
#ifndef CONFIG_USER_ONLY
50
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
51
ARCH(5);
52
53
/* Unconditional instructions. */
54
- if (disas_a32_uncond(s, insn)) {
55
+ /* TODO: Perhaps merge these into one decodetree output file. */
56
+ if (disas_a32_uncond(s, insn) ||
57
+ disas_vfp_uncond(s, insn)) {
58
return;
59
}
60
/* fall back to legacy decoder */
61
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
62
}
63
return;
64
}
65
- if ((insn & 0x0f000e10) == 0x0e000a00) {
66
- /* VFP. */
67
- if (disas_vfp_insn(s, insn)) {
68
- goto illegal_op;
69
- }
70
- return;
71
- }
72
if ((insn & 0x0e000f00) == 0x0c000100) {
73
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
74
/* iWMMXt register transfer. */
75
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
76
arm_skip_unless(s, cond);
77
}
78
79
- if (disas_a32(s, insn)) {
80
+ /* TODO: Perhaps merge these into one decodetree output file. */
81
+ if (disas_a32(s, insn) ||
82
+ disas_vfp(s, insn)) {
83
return;
84
}
85
/* fall back to legacy decoder */
86
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
87
case 0xd:
88
case 0xe:
89
if (((insn >> 8) & 0xe) == 10) {
90
- /* VFP. */
91
- if (disas_vfp_insn(s, insn)) {
92
- goto illegal_op;
93
- }
94
- } else if (disas_coproc_insn(s, insn)) {
95
+ /* VFP, but failed disas_vfp. */
96
+ goto illegal_op;
97
+ }
98
+ if (disas_coproc_insn(s, insn)) {
99
/* Coprocessor. */
100
goto illegal_op;
101
}
102
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
103
ARCH(6T2);
104
}
105
106
- if (disas_t32(s, insn)) {
107
+ /*
108
+ * TODO: Perhaps merge these into one decodetree output file.
109
+ * Note disas_vfp is written for a32 with cond field in the
110
+ * top nibble. The t32 encoding requires 0xe in the top nibble.
111
+ */
112
+ if (disas_t32(s, insn) ||
113
+ disas_vfp_uncond(s, insn) ||
114
+ ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
115
return;
116
}
117
/* fall back to legacy decoder */
118
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
119
goto illegal_op; /* op0 = 0b11 : unallocated */
120
}
121
122
- if (disas_vfp_insn(s, insn)) {
123
- if (((insn >> 8) & 0xe) == 10 &&
124
- dc_isar_feature(aa32_fpsp_v2, s)) {
125
- /* FP, and the CPU supports it */
126
- goto illegal_op;
127
- } else {
128
- /* All other insns: NOCP */
129
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
130
- syn_uncategorized(),
131
- default_exception_el(s));
132
- }
133
+ if (((insn >> 8) & 0xe) == 10 &&
134
+ dc_isar_feature(aa32_fpsp_v2, s)) {
135
+ /* FP, and the CPU supports it */
136
+ goto illegal_op;
137
+ } else {
138
+ /* All other insns: NOCP */
139
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
140
+ syn_uncategorized(),
141
+ default_exception_el(s));
142
}
143
break;
144
}
145
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
146
goto illegal_op;
147
}
148
} else if (((insn >> 8) & 0xe) == 10) {
149
- if (disas_vfp_insn(s, insn)) {
150
- goto illegal_op;
151
- }
152
+ /* VFP, but failed disas_vfp. */
153
+ goto illegal_op;
154
} else {
155
if (insn & (1 << 28))
156
goto illegal_op;
157
--
182
--
158
2.20.1
183
2.20.1
159
184
160
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
2
5
3
All remaining tests for VFP4 are for fused multiply-add insns.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 3 +-
11
target/arm/translate-a64.c | 86 ++++----------------------------------
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
4
14
5
Since the MVFR1 field is used for both VFP and NEON, move its adjustment
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
6
from the !has_neon block to the (!has_vfp && !has_neon) block.
7
8
Test for vfp of the appropraite width alongside the test for simdfmac
9
within translate-vfp.inc.c. Within disas_neon_data_insn, we have
10
already tested for ARM_FEATURE_NEON.
11
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20200224222232.13807-10-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 12 ++++++++++++
18
target/arm/cpu.c | 6 +++++-
19
target/arm/translate-vfp.inc.c | 22 ++++++++++++++++++----
20
target/arm/translate.c | 2 +-
21
4 files changed, 36 insertions(+), 6 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
17
--- a/target/arm/translate.h
26
+++ b/target/arm/cpu.h
18
+++ b/target/arm/translate.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
28
return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
20
* VMVN and VBIC (when cmode < 14 && op == 1).
29
}
21
*
30
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+/*
23
- * callers must catch this.
32
+ * Note that this ID register field covers both VFP and Neon FMAC,
24
+ * callers must catch this; we return the 64-bit constant value defined
33
+ * so should usually be tested in combination with some other
25
+ * for AArch64.
34
+ * check that confirms the presence of whichever of VFP or Neon is
26
*
35
+ * relevant, to avoid accidentally enabling a Neon feature on
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
36
+ * a VFP-no-Neon core or vice-versa.
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
37
+ */
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
38
+static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id)
30
index XXXXXXX..XXXXXXX 100644
39
+{
31
--- a/target/arm/translate-a64.c
40
+ return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0;
32
+++ b/target/arm/translate-a64.c
41
+}
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
42
+
43
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
44
{
34
{
45
return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
35
int rd = extract32(insn, 0, 5);
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
int cmode = extract32(insn, 12, 4);
47
index XXXXXXX..XXXXXXX 100644
37
- int cmode_3_1 = extract32(cmode, 1, 3);
48
--- a/target/arm/cpu.c
38
- int cmode_0 = extract32(cmode, 0, 1);
49
+++ b/target/arm/cpu.c
39
int o2 = extract32(insn, 11, 1);
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
51
u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
41
bool is_neg = extract32(insn, 29, 1);
52
u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
53
u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
43
return;
54
- u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
55
cpu->isar.mvfr1 = u;
56
57
u = cpu->isar.mvfr2;
58
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
59
u = cpu->isar.mvfr0;
60
u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
61
cpu->isar.mvfr0 = u;
62
+
63
+ /* Despite the name, this field covers both VFP and Neon */
64
+ u = cpu->isar.mvfr1;
65
+ u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
66
+ cpu->isar.mvfr1 = u;
67
}
44
}
68
45
69
if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
46
- /* See AdvSIMDExpandImm() in ARM ARM */
70
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
47
- switch (cmode_3_1) {
71
index XXXXXXX..XXXXXXX 100644
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
72
--- a/target/arm/translate-vfp.inc.c
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
73
+++ b/target/arm/translate-vfp.inc.c
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
75
52
- {
76
/*
53
- int shift = cmode_3_1 * 8;
77
* Present in VFPv4 only.
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
78
+ * Note that we can't rely on the SIMDFMAC check alone, because
55
- break;
79
+ * in a Neon-no-VFP core that ID register field will be non-zero.
56
- }
80
+ */
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
81
+ if (!dc_isar_feature(aa32_simdfmac, s) ||
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
82
+ !dc_isar_feature(aa32_fpsp_v2, s)) {
59
- {
83
+ return false;
60
- int shift = (cmode_3_1 & 0x1) * 8;
84
+ }
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
85
+ /*
62
- break;
86
* In v7A, UNPREDICTABLE with non-zero vector length/stride; from
63
- }
87
* v8A, must UNDEF. We choose to UNDEF for both v7A and v8A.
64
- case 6:
88
*/
65
- if (cmode_0) {
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4) ||
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
90
- (s->vec_len != 0 || s->vec_stride != 0)) {
67
- imm = (abcdefgh << 16) | 0xffff;
91
+ if (s->vec_len != 0 || s->vec_stride != 0) {
68
- } else {
92
return false;
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);
93
}
130
}
94
131
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
96
97
/*
98
* Present in VFPv4 only.
99
+ * Note that we can't rely on the SIMDFMAC check alone, because
100
+ * in a Neon-no-VFP core that ID register field will be non-zero.
101
+ */
102
+ if (!dc_isar_feature(aa32_simdfmac, s) ||
103
+ !dc_isar_feature(aa32_fpdp_v2, s)) {
104
+ return false;
105
+ }
106
+ /*
107
* In v7A, UNPREDICTABLE with non-zero vector length/stride; from
108
* v8A, must UNDEF. We choose to UNDEF for both v7A and v8A.
109
*/
110
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4) ||
111
- (s->vec_len != 0 || s->vec_stride != 0)) {
112
+ if (s->vec_len != 0 || s->vec_stride != 0) {
113
return false;
114
}
115
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
135
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
136
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
121
}
138
case 14:
122
break;
139
if (op) {
123
case NEON_3R_VFM_VQRDMLSH:
140
/*
124
- if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
141
- * This is the only case where the top and bottom 32 bits
125
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
142
- * of the encoded constant differ.
126
return 1;
143
+ * This and cmode == 15 op == 1 are the only cases where
127
}
144
+ * the top and bottom 32 bits of the encoded constant differ.
128
break;
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
150
break;
151
case 15:
152
+ if (op) {
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
129
--
168
--
130
2.20.1
169
2.20.1
131
170
132
171
diff view generated by jsdifflib
1
The v8.3-RCPC extension implements three new load instructions
1
Use dup_const() instead of bitfield_replicate() in
2
which provide slightly weaker consistency guarantees than the
2
disas_simd_mod_imm().
3
existing load-acquire operations. For QEMU we choose to simply
3
4
implement them with a full LDAQ barrier.
4
(We can't replace the other use of bitfield_replicate() in this file,
5
in logic_imm_decode_wmask(), because that location needs to handle 2
6
and 4 bit elements, which dup_const() cannot.)
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224172846.13053-3-peter.maydell@linaro.org
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
9
---
11
---
10
target/arm/cpu.h | 5 +++++
12
target/arm/translate-a64.c | 2 +-
11
linux-user/elfload.c | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
target/arm/cpu64.c | 1 +
13
target/arm/translate-a64.c | 24 ++++++++++++++++++++++++
14
4 files changed, 31 insertions(+)
15
14
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
21
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
22
}
23
24
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
27
+}
28
+
29
/*
30
* Feature tests for "does this exist in either 32-bit or 64-bit?"
31
*/
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
38
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
39
GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
40
+ GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
41
42
return hwcaps;
43
}
44
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu64.c
47
+++ b/target/arm/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
51
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
52
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 1); /* ARMv8.3-RCPC */
53
cpu->isar.id_aa64isar1 = t;
54
55
t = cpu->isar.id_aa64pfr0;
56
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
57
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
61
int rs = extract32(insn, 16, 5);
20
/* FMOV (vector, immediate) - half-precision */
62
int rn = extract32(insn, 5, 5);
21
imm = vfp_expand_imm(MO_16, abcdefgh);
63
int o3_opc = extract32(insn, 12, 4);
22
/* now duplicate across the lanes */
64
+ bool r = extract32(insn, 22, 1);
23
- imm = bitfield_replicate(imm, 16);
65
+ bool a = extract32(insn, 23, 1);
24
+ imm = dup_const(MO_16, imm);
66
TCGv_i64 tcg_rs, clean_addr;
25
} else {
67
AtomicThreeOpFn *fn;
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
68
69
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
70
case 010: /* SWP */
71
fn = tcg_gen_atomic_xchg_i64;
72
break;
73
+ case 014: /* LDAPR, LDAPRH, LDAPRB */
74
+ if (!dc_isar_feature(aa64_rcpc_8_3, s) ||
75
+ rs != 31 || a != 1 || r != 0) {
76
+ unallocated_encoding(s);
77
+ return;
78
+ }
79
+ break;
80
default:
81
unallocated_encoding(s);
82
return;
83
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
84
gen_check_sp_alignment(s);
85
}
27
}
86
clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
87
+
88
+ if (o3_opc == 014) {
89
+ /*
90
+ * LDAPR* are a special case because they are a simple load, not a
91
+ * fetch-and-do-something op.
92
+ * The architectural consistency requirements here are weaker than
93
+ * full load-acquire (we only need "load-acquire processor consistent"),
94
+ * but we choose to implement them as full LDAQ.
95
+ */
96
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false,
97
+ true, rt, disas_ldst_compute_iss_sf(size, false, 0), true);
98
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
99
+ return;
100
+ }
101
+
102
tcg_rs = read_cpu_reg(s, rs, true);
103
104
if (o3_opc == 1) { /* LDCLR */
105
--
28
--
106
2.20.1
29
2.20.1
107
30
108
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
3
Now that we no longer have an early check for ARM_FEATURE_VFP,
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
we can use the proper ISA check in trans_VLLDM_VLSTM.
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(+)
5
15
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200224222232.13807-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-vfp.inc.c | 39 +++++++++++++++++++++++++
12
target/arm/translate.c | 53 ++++++----------------------------
13
target/arm/vfp.decode | 2 ++
14
3 files changed, 50 insertions(+), 44 deletions(-)
15
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.inc.c
18
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/translate-vfp.inc.c
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
tcg_temp_free_ptr(fpst);
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);
22
return true;
120
return true;
23
}
121
}
24
+
122
+
25
+/*
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
26
+ * Decode VLLDM and VLSTM are nonstandard because:
27
+ * * if there is no FPU then these insns must NOP in
28
+ * Secure state and UNDEF in Nonsecure state
29
+ * * if there is an FPU then these insns do not have
30
+ * the usual behaviour that vfp_access_check() provides of
31
+ * being controlled by CPACR/NSACR enable bits or the
32
+ * lazy-stacking logic.
33
+ */
34
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
35
+{
124
+{
36
+ TCGv_i32 fptr;
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
37
+
127
+
38
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
128
+ if (!dc_isar_feature(aa32_mve, s) ||
39
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
40
+ return false;
131
+ return false;
41
+ }
132
+ }
42
+ /* If not secure, UNDEF. */
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
43
+ if (!s->v8m_secure) {
44
+ return false;
45
+ }
46
+ /* If no fpu, NOP. */
47
+ if (!dc_isar_feature(aa32_vfp, s)) {
48
+ return true;
134
+ return true;
49
+ }
135
+ }
50
+
136
+
51
+ fptr = load_reg(s, a->rn);
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
52
+ if (a->l) {
53
+ gen_helper_v7m_vlldm(cpu_env, fptr);
54
+ } else {
55
+ gen_helper_v7m_vlstm(cpu_env, fptr);
56
+ }
57
+ tcg_temp_free_i32(fptr);
58
+
138
+
59
+ /* End the TB, because we have updated FP control bits */
139
+ qd = mve_qreg_ptr(a->qd);
60
+ s->base.is_jmp = DISAS_UPDATE;
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
61
+ return true;
143
+ return true;
62
+}
144
+}
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
68
goto illegal_op; /* op0 = 0b11 : unallocated */
69
}
70
71
- /*
72
- * Decode VLLDM and VLSTM first: these are nonstandard because:
73
- * * if there is no FPU then these insns must NOP in
74
- * Secure state and UNDEF in Nonsecure state
75
- * * if there is an FPU then these insns do not have
76
- * the usual behaviour that disas_vfp_insn() provides of
77
- * being controlled by CPACR/NSACR enable bits or the
78
- * lazy-stacking logic.
79
- */
80
- if (arm_dc_feature(s, ARM_FEATURE_V8) &&
81
- (insn & 0xffa00f00) == 0xec200a00) {
82
- /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
83
- * - VLLDM, VLSTM
84
- * We choose to UNDEF if the RAZ bits are non-zero.
85
- */
86
- if (!s->v8m_secure || (insn & 0x0040f0ff)) {
87
+ if (disas_vfp_insn(s, insn)) {
88
+ if (((insn >> 8) & 0xe) == 10 &&
89
+ dc_isar_feature(aa32_fpsp_v2, s)) {
90
+ /* FP, and the CPU supports it */
91
goto illegal_op;
92
+ } else {
93
+ /* All other insns: NOCP */
94
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
95
+ syn_uncategorized(),
96
+ default_exception_el(s));
97
}
98
-
99
- if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
100
- uint32_t rn = (insn >> 16) & 0xf;
101
- TCGv_i32 fptr = load_reg(s, rn);
102
-
103
- if (extract32(insn, 20, 1)) {
104
- gen_helper_v7m_vlldm(cpu_env, fptr);
105
- } else {
106
- gen_helper_v7m_vlstm(cpu_env, fptr);
107
- }
108
- tcg_temp_free_i32(fptr);
109
-
110
- /* End the TB, because we have updated FP control bits */
111
- s->base.is_jmp = DISAS_UPDATE;
112
- }
113
- break;
114
}
115
- if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
116
- ((insn >> 8) & 0xe) == 10) {
117
- /* FP, and the CPU supports it */
118
- if (disas_vfp_insn(s, insn)) {
119
- goto illegal_op;
120
- }
121
- break;
122
- }
123
-
124
- /* All other insns: NOCP */
125
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
126
- default_exception_el(s));
127
break;
128
}
129
if ((insn & 0xfe000a00) == 0xfc000800
130
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/vfp.decode
133
+++ b/target/arm/vfp.decode
134
@@ -XXX,XX +XXX,XX @@ VCVT_sp_int ---- 1110 1.11 110 s:1 .... 1010 rz:1 1.0 .... \
135
vd=%vd_sp vm=%vm_sp
136
VCVT_dp_int ---- 1110 1.11 110 s:1 .... 1011 rz:1 1.0 .... \
137
vd=%vd_sp vm=%vm_dp
138
+
145
+
139
+VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
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
+}
140
--
171
--
141
2.20.1
172
2.20.1
142
173
143
174
diff view generated by jsdifflib
1
In our KVM GICv2 realize function, we try to cope with old kernels
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
that don't provide the device control API (KVM_CAP_DEVICE_CTRL): we
2
and VQSHLU.
3
try to use the device control, and if that fails we fall back to
3
4
assuming that the kernel has the old style KVM_CREATE_IRQCHIP and
4
The size-and-immediate encoding here is the same as Neon, and we
5
that it will provide a GICv2.
5
handle it the same way neon-dp.decode does.
6
7
This doesn't cater for the possibility of a kernel and hardware which
8
only provide a GICv3, which is very common now. On that setup we
9
will abort() later on in kvm_arm_pmu_set_irq() when we try to wire up
10
an interrupt to the GIC we failed to create:
11
12
qemu-system-aarch64: PMU: KVM_SET_DEVICE_ATTR: Invalid argument
13
qemu-system-aarch64: failed to set irq for PMU
14
Aborted
15
16
If the kernel advertises KVM_CAP_DEVICE_CTRL we should trust it if it
17
says it can't create a GICv2, rather than assuming it has one. We
18
can then produce a more helpful error message including a hint about
19
the most probable reason for the failure.
20
21
If the kernel doesn't advertise KVM_CAP_DEVICE_CTRL then it is truly
22
ancient by this point but we might as well still fall back to a
23
KVM_CREATE_IRQCHIP GICv2.
24
25
With this patch then the user misconfiguration which previously
26
caused an abort now prints:
27
qemu-system-aarch64: Initialization of device kvm-arm-gic failed: error creating in-kernel VGIC: No such device
28
Perhaps the host CPU does not support GICv2?
29
6
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Reviewed-by: Andrew Jones <drjones@redhat.com>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
33
Tested-by: Andrew Jones <drjones@redhat.com>
34
Message-id: 20200225182435.1131-1-peter.maydell@linaro.org
35
---
10
---
36
hw/intc/arm_gic_kvm.c | 9 +++++++++
11
target/arm/helper-mve.h | 16 +++++++++++
37
1 file changed, 9 insertions(+)
12
target/arm/mve.decode | 23 +++++++++++++++
38
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
39
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
40
index XXXXXXX..XXXXXXX 100644
15
4 files changed, 147 insertions(+)
41
--- a/hw/intc/arm_gic_kvm.c
16
42
+++ b/hw/intc/arm_gic_kvm.c
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
43
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
18
index XXXXXXX..XXXXXXX 100644
44
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
19
--- a/target/arm/helper-mve.h
45
&error_abort);
20
+++ b/target/arm/helper-mve.h
46
}
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
47
+ } else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
48
+ error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
49
+ error_append_hint(errp,
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
50
+ "Perhaps the host CPU does not support GICv2?\n");
25
+
51
} else if (ret != -ENODEV && ret != -ENOTSUP) {
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+ /*
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+ * Very ancient kernel without KVM_CAP_DEVICE_CTRL: assume that
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
+ * ENODEV or ENOTSUP mean "can't create GICv2 with KVM_CREATE_DEVICE",
29
+
55
+ * and that we will get a GICv2 via KVM_CREATE_IRQCHIP.
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
+ */
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
57
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
58
return;
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)
59
}
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)
60
--
224
--
61
2.20.1
225
2.20.1
62
226
63
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
3
Passing the raw o1 and o2 fields from the manual is less
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
instructive than it might be. Do the full decode and let
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the trans_* functions pass in booleans to a helper.
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 12 ++++++++++++
11
target/arm/translate.h | 20 ++++++++++++++++++++
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(-)
6
17
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200224222232.13807-17-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-vfp.inc.c | 52 ++++++++++++++++++++++++++++++----
13
target/arm/vfp.decode | 17 +++++------
14
2 files changed, 55 insertions(+), 14 deletions(-)
15
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.inc.c
20
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/translate-vfp.inc.c
21
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
21
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
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;
22
}
51
}
23
52
24
-static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
53
+static inline int rsub_64(DisasContext *s, int x)
25
+static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
26
{
27
/*
28
* VFNMA : fd = muladd(-fd, fn, fm)
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
30
31
neon_load_reg32(vn, a->vn);
32
neon_load_reg32(vm, a->vm);
33
- if (a->o2) {
34
+ if (neg_n) {
35
/* VFNMS, VFMS */
36
gen_helper_vfp_negs(vn, vn);
37
}
38
neon_load_reg32(vd, a->vd);
39
- if (a->o1 & 1) {
40
+ if (neg_d) {
41
/* VFNMA, VFNMS */
42
gen_helper_vfp_negs(vd, vd);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
45
return true;
46
}
47
48
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
49
+static bool trans_VFMA_sp(DisasContext *s, arg_VFMA_sp *a)
50
+{
54
+{
51
+ return do_vfm_sp(s, a, false, false);
55
+ return 64 - x;
52
+}
56
+}
53
+
57
+
54
+static bool trans_VFMS_sp(DisasContext *s, arg_VFMS_sp *a)
58
+static inline int rsub_32(DisasContext *s, int x)
55
+{
59
+{
56
+ return do_vfm_sp(s, a, true, false);
60
+ return 32 - x;
57
+}
61
+}
58
+
62
+
59
+static bool trans_VFNMA_sp(DisasContext *s, arg_VFNMA_sp *a)
63
+static inline int rsub_16(DisasContext *s, int x)
60
+{
64
+{
61
+ return do_vfm_sp(s, a, false, true);
65
+ return 16 - x;
62
+}
66
+}
63
+
67
+
64
+static bool trans_VFNMS_sp(DisasContext *s, arg_VFNMS_sp *a)
68
+static inline int rsub_8(DisasContext *s, int x)
65
+{
69
+{
66
+ return do_vfm_sp(s, a, true, true);
70
+ return 8 - x;
67
+}
71
+}
68
+
72
+
69
+static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
70
{
74
{
71
/*
75
return (dc->features & (1ULL << feature)) != 0;
72
* VFNMA : fd = muladd(-fd, fn, fm)
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
73
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
77
index XXXXXXX..XXXXXXX 100644
74
78
--- a/target/arm/mve.decode
75
neon_load_reg64(vn, a->vn);
79
+++ b/target/arm/mve.decode
76
neon_load_reg64(vm, a->vm);
80
@@ -XXX,XX +XXX,XX @@
77
- if (a->o2) {
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
78
+ if (neg_n) {
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
79
/* VFNMS, VFMS */
83
80
gen_helper_vfp_negd(vn, vn);
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
81
}
85
+%rshift_i5 16:5 !function=rsub_32
82
neon_load_reg64(vd, a->vd);
86
+%rshift_i4 16:4 !function=rsub_16
83
- if (a->o1 & 1) {
87
+%rshift_i3 16:3 !function=rsub_8
84
+ if (neg_d) {
88
+
85
/* VFNMA, VFNMS */
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
86
gen_helper_vfp_negd(vd, vd);
90
+ size=0 shift=%rshift_i3
87
}
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
88
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
92
+ size=1 shift=%rshift_i4
89
return true;
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;
90
}
163
}
91
164
92
+static bool trans_VFMA_dp(DisasContext *s, arg_VFMA_dp *a)
165
-static inline int rsub_64(DisasContext *s, int x)
93
+{
166
-{
94
+ return do_vfm_dp(s, a, false, false);
167
- return 64 - x;
95
+}
168
-}
96
+
169
-
97
+static bool trans_VFMS_dp(DisasContext *s, arg_VFMS_dp *a)
170
-static inline int rsub_32(DisasContext *s, int x)
98
+{
171
-{
99
+ return do_vfm_dp(s, a, true, false);
172
- return 32 - x;
100
+}
173
-}
101
+
174
-static inline int rsub_16(DisasContext *s, int x)
102
+static bool trans_VFNMA_dp(DisasContext *s, arg_VFNMA_dp *a)
175
-{
103
+{
176
- return 16 - x;
104
+ return do_vfm_dp(s, a, false, true);
177
-}
105
+}
178
-static inline int rsub_8(DisasContext *s, int x)
106
+
179
-{
107
+static bool trans_VFNMS_dp(DisasContext *s, arg_VFNMS_dp *a)
180
- return 8 - x;
108
+{
181
-}
109
+ return do_vfm_dp(s, a, true, true);
182
-
110
+}
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
111
+
112
static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
113
{
184
{
114
uint32_t delta_d = 0;
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
115
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/vfp.decode
118
+++ b/target/arm/vfp.decode
119
@@ -XXX,XX +XXX,XX @@ VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... @vfp_dnm_d
120
VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
121
VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
122
123
-VFM_sp ---- 1110 1.01 .... .... 1010 . o2:1 . 0 .... \
124
- vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=1
125
-VFM_dp ---- 1110 1.01 .... .... 1011 . o2:1 . 0 .... \
126
- vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=1
127
-VFM_sp ---- 1110 1.10 .... .... 1010 . o2:1 . 0 .... \
128
- vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=2
129
-VFM_dp ---- 1110 1.10 .... .... 1011 . o2:1 . 0 .... \
130
- vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=2
131
+VFMA_sp ---- 1110 1.10 .... .... 1010 .0. 0 .... @vfp_dnm_s
132
+VFMS_sp ---- 1110 1.10 .... .... 1010 .1. 0 .... @vfp_dnm_s
133
+VFNMA_sp ---- 1110 1.01 .... .... 1010 .0. 0 .... @vfp_dnm_s
134
+VFNMS_sp ---- 1110 1.01 .... .... 1010 .1. 0 .... @vfp_dnm_s
135
+
136
+VFMA_dp ---- 1110 1.10 .... .... 1011 .0.0 .... @vfp_dnm_d
137
+VFMS_dp ---- 1110 1.10 .... .... 1011 .1.0 .... @vfp_dnm_d
138
+VFNMA_dp ---- 1110 1.01 .... .... 1011 .0.0 .... @vfp_dnm_d
139
+VFNMS_dp ---- 1110 1.01 .... .... 1011 .1.0 .... @vfp_dnm_d
140
141
VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
142
vd=%vd_sp imm=%vmov_imm
143
--
186
--
144
2.20.1
187
2.20.1
145
188
146
189
diff view generated by jsdifflib
1
The ARMv8.3-CCIDX extension makes the CCSIDR_EL1 system ID registers
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
have a format that uses the full 64 bit width of the register, and
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
adds a new CCSIDR2 register so AArch32 can get at the high 32 bits.
3
and the T2 encoding is a special case where the shift count is always
4
4
equal to the element size.
5
QEMU doesn't implement caches, so we just treat these ID registers as
6
opaque values that are set to the correct constant values for each
7
CPU. The only thing we need to do is allow 64-bit values in our
8
cssidr[] array and provide the CCSIDR2 accessors.
9
10
We don't set the CCIDX field in our 'max' CPU because the CCSIDR
11
constant values we use are the same as the ones used by the
12
Cortex-A57 and they are in the old 32-bit format. This means
13
that the extra regdef added here is unused currently, but it
14
means that whenever in the future we add a CPU that does need
15
the new 64-bit format it will just work when we set the cssidr
16
values and the ID registers for it.
17
5
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20200224182626.29252-1-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
21
---
9
---
22
target/arm/cpu.h | 17 ++++++++++++++++-
10
target/arm/helper-mve.h | 9 +++++++
23
target/arm/helper.c | 19 +++++++++++++++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
24
2 files changed, 35 insertions(+), 1 deletion(-)
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
25
15
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
18
--- a/target/arm/helper-mve.h
29
+++ b/target/arm/cpu.h
19
+++ b/target/arm/helper-mve.h
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
/* The elements of this array are the CCSIDR values for each cache,
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
*/
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
- uint32_t ccsidr[16];
24
+
35
+ uint64_t ccsidr[16];
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
uint64_t reset_cbar;
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
uint32_t reset_auxcr;
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
bool reset_hivecs;
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
}
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
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 @@
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
40
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
44
+{
60
+{
45
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
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
46
+}
67
+}
47
+
68
+
48
/*
49
* 64-bit feature tests via id registers.
50
*/
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
52
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
53
}
54
55
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
56
+{
69
+{
57
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
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
72
+
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+}
74
+}
59
+
75
+
60
/*
61
* Feature tests for "does this exist in either 32-bit or 64-bit?"
62
*/
63
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
64
return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
65
}
66
67
+static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
68
+{
76
+{
69
+ return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
79
+
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
70
+}
81
+}
71
+
82
+
72
/*
83
+{
73
* Forward to the above feature tests given an ARMCPU pointer.
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
74
*/
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
86
+
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
88
+}
89
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
76
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/helper.c
111
--- a/target/arm/mve_helper.c
78
+++ b/target/arm/helper.c
112
+++ b/target/arm/mve_helper.c
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
80
REGINFO_SENTINEL
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
81
};
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
82
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
83
+static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
84
+{
85
+ /* Read the high 32 bits of the current CCSIDR */
86
+ return extract64(ccsidr_read(env, ri), 32, 32);
87
+}
88
+
117
+
89
+static const ARMCPRegInfo ccsidr2_reginfo[] = {
118
+/*
90
+ { .name = "CCSIDR2", .state = ARM_CP_STATE_BOTH,
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
91
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 2,
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
92
+ .access = PL1_R,
121
+ * the input, and LESIZE, LTYPE for the output.
93
+ .accessfn = access_aa64_tid2,
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
94
+ .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
123
+ * because the long shift is strictly left-only.
95
+ REGINFO_SENTINEL
124
+ */
96
+};
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
97
+
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
98
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
127
+ void *vm, uint32_t shift) \
99
bool isread)
128
+ { \
100
{
129
+ LTYPE *d = vd; \
101
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
130
+ TYPE *m = vm; \
102
define_arm_cp_regs(cpu, predinv_reginfo);
131
+ uint16_t mask = mve_element_mask(env); \
103
}
132
+ unsigned le; \
104
133
+ assert(shift <= 16); \
105
+ if (cpu_isar_feature(any_ccidx, cpu)) {
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
106
+ define_arm_cp_regs(cpu, ccsidr2_reginfo);
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); \
107
+ }
139
+ }
108
+
140
+
109
#ifndef CONFIG_USER_ONLY
141
+#define DO_VSHLL_ALL(OP, TOP) \
110
/*
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
111
* Register redirections and aliases must be done last,
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)
112
--
172
--
113
2.20.1
173
2.20.1
114
174
115
175
diff view generated by jsdifflib
1
We missed an instance of using FIELD_EX32 on a 64-bit ID
1
Implement the MVE VSRI and VSLI insns, which perform a
2
register, in isar_feature_aa64_pmu_8_4(). Fix it.
2
shift-and-insert operation.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200224172846.13053-2-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
8
---
7
---
9
target/arm/cpu.h | 4 ++--
8
target/arm/helper-mve.h | 8 ++++++++
10
1 file changed, 2 insertions(+), 2 deletions(-)
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(+)
11
13
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
16
--- a/target/arm/helper-mve.h
15
+++ b/target/arm/cpu.h
17
+++ b/target/arm/helper-mve.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
17
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
18
static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
{
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
- return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
22
+
21
- FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
}
26
+
25
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
+
26
/*
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
{ \
27
--
114
--
28
2.20.1
115
2.20.1
29
116
30
117
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
2
3
The GICv2 allows the implementation to implement a variable number
3
do_urshr() is borrowed from sve_helper.c.
4
of priority bits; unimplemented bits in the priority registers
5
are read as zeros, writes ignored. We were previously always
6
implementing a full 8 bits of priority, which is allowed but not
7
what the real hardware typically does (which is usually to have
8
4 or 5 bits of priority).
9
4
10
Add a new device property to allow the number of implemented
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
property bits to be specified.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 10 ++++++++++
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(+)
12
14
13
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
14
Message-id: 1582537164-764-2-git-send-email-sai.pavan.boddu@xilinx.com
15
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
[PMM: improved commit message]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/intc/arm_gic.h | 2 ++
21
include/hw/intc/arm_gic_common.h | 1 +
22
hw/intc/arm_gic.c | 33 ++++++++++++++++++++++++++++++--
23
hw/intc/arm_gic_common.c | 1 +
24
4 files changed, 35 insertions(+), 2 deletions(-)
25
26
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
27
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/intc/arm_gic.h
17
--- a/target/arm/helper-mve.h
29
+++ b/include/hw/intc/arm_gic.h
18
+++ b/target/arm/helper-mve.h
30
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
/* Number of SGI target-list bits */
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
#define GIC_TARGETLIST_BITS 8
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+#define GIC_MAX_PRIORITY_BITS 8
23
+
35
+#define GIC_MIN_PRIORITY_BITS 4
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
#define TYPE_ARM_GIC "arm_gic"
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
#define ARM_GIC(obj) \
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
28
+
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
40
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/intc/arm_gic_common.h
35
--- a/target/arm/mve.decode
42
+++ b/include/hw/intc/arm_gic_common.h
36
+++ b/target/arm/mve.decode
43
@@ -XXX,XX +XXX,XX @@ typedef struct GICState {
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
44
uint16_t priority_mask[GIC_NCPU_VCPU];
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
uint16_t running_priority[GIC_NCPU_VCPU];
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
uint16_t current_pending[GIC_NCPU_VCPU];
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
+ uint32_t n_prio_bits;
41
+
48
42
+# Narrowing shifts (which only support b and h sizes)
49
/* If we present the GICv2 without security extensions to a guest,
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
50
* the guest can configure the GICC_CTLR to configure group 1 binary point
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
51
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/intc/arm_gic.c
54
--- a/target/arm/mve_helper.c
54
+++ b/hw/intc/arm_gic.c
55
+++ b/target/arm/mve_helper.c
55
@@ -XXX,XX +XXX,XX @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs)
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
56
return ret;
57
57
}
58
DO_VSHLL_ALL(vshllb, false)
58
59
DO_VSHLL_ALL(vshllt, true)
59
+static uint32_t gic_fullprio_mask(GICState *s, int cpu)
60
+
61
+/*
62
+ * Narrowing right shifts, taking a double sized input, shifting it
63
+ * and putting the result in either the top or bottom half of the output.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
65
+ */
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)
60
+{
88
+{
61
+ /*
89
+ if (likely(sh < 64)) {
62
+ * Return a mask word which clears the unimplemented priority
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
63
+ * bits from a priority value for an interrupt. (Not to be
91
+ } else if (sh == 64) {
64
+ * confused with the group priority, whose mask depends on BPR.)
92
+ return x >> 63;
65
+ */
66
+ int priBits;
67
+
68
+ if (gic_is_vcpu(cpu)) {
69
+ priBits = GIC_VIRT_MAX_GROUP_PRIO_BITS;
70
+ } else {
93
+ } else {
71
+ priBits = s->n_prio_bits;
94
+ return 0;
72
+ }
95
+ }
73
+ return ~0U << (8 - priBits);
74
+}
96
+}
75
+
97
+
76
void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
77
MemTxAttrs attrs)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
78
{
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
79
@@ -XXX,XX +XXX,XX @@ void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
101
index XXXXXXX..XXXXXXX 100644
80
val = 0x80 | (val >> 1); /* Non-secure view */
102
--- a/target/arm/translate-mve.c
81
}
103
+++ b/target/arm/translate-mve.c
82
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
83
+ val &= gic_fullprio_mask(s, cpu);
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
84
+
108
+
85
if (irq < GIC_INTERNAL) {
109
+#define DO_2SHIFT_N(INSN, FN) \
86
s->priority1[irq][cpu] = val;
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
87
} else {
111
+ { \
88
@@ -XXX,XX +XXX,XX @@ static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq,
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
89
}
113
+ gen_helper_mve_##FN##b, \
90
prio = (prio << 1) & 0xff; /* Non-secure view */
114
+ gen_helper_mve_##FN##h, \
91
}
115
+ }; \
92
- return prio;
116
+ return do_2shift(s, a, fns[a->size], false); \
93
+ return prio & gic_fullprio_mask(s, cpu);
94
}
95
96
static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
97
@@ -XXX,XX +XXX,XX @@ static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
98
return;
99
}
100
}
101
- s->priority_mask[cpu] = pmask;
102
+ s->priority_mask[cpu] = pmask & gic_fullprio_mask(s, cpu);
103
}
104
105
static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs)
106
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
107
return;
108
}
109
110
+ if (s->n_prio_bits > GIC_MAX_PRIORITY_BITS ||
111
+ (s->virt_extn ? s->n_prio_bits < GIC_VIRT_MAX_GROUP_PRIO_BITS :
112
+ s->n_prio_bits < GIC_MIN_PRIORITY_BITS)) {
113
+ error_setg(errp, "num-priority-bits cannot be greater than %d"
114
+ " or less than %d", GIC_MAX_PRIORITY_BITS,
115
+ s->virt_extn ? GIC_VIRT_MAX_GROUP_PRIO_BITS :
116
+ GIC_MIN_PRIORITY_BITS);
117
+ return;
118
+ }
117
+ }
119
+
118
+
120
/* This creates distributor, main CPU interface (s->cpuiomem[0]) and if
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
121
* enabled, virtualization extensions related interfaces (main virtual
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
122
* interface (s->vifaceiomem[0]) and virtual CPU interface).
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
123
diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
124
index XXXXXXX..XXXXXXX 100644
125
--- a/hw/intc/arm_gic_common.c
126
+++ b/hw/intc/arm_gic_common.c
127
@@ -XXX,XX +XXX,XX @@ static Property arm_gic_common_properties[] = {
128
DEFINE_PROP_BOOL("has-security-extensions", GICState, security_extn, 0),
129
/* True if the GIC should implement the virtualization extensions */
130
DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn, 0),
131
+ DEFINE_PROP_UINT32("num-priority-bits", GICState, n_prio_bits, 8),
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
135
--
123
--
136
2.20.1
124
2.20.1
137
125
138
126
diff view generated by jsdifflib
Deleted patch
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
2
1
3
The GIC built into the ARM11MPCore is always implemented with 4
4
priority bits; set the GIC property accordingly.
5
6
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1582537164-764-4-git-send-email-sai.pavan.boddu@xilinx.com
9
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: tweaked commit message]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/cpu/arm11mpcore.c | 5 +++++
15
1 file changed, 5 insertions(+)
16
17
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/cpu/arm11mpcore.c
20
+++ b/hw/cpu/arm11mpcore.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/irq.h"
23
#include "hw/qdev-properties.h"
24
25
+#define ARM11MPCORE_NUM_GIC_PRIORITY_BITS 4
26
27
static void mpcore_priv_set_irq(void *opaque, int irq, int level)
28
{
29
@@ -XXX,XX +XXX,XX @@ static void mpcore_priv_realize(DeviceState *dev, Error **errp)
30
31
qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
32
qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
33
+ qdev_prop_set_uint32(gicdev, "num-priority-bits",
34
+ ARM11MPCORE_NUM_GIC_PRIORITY_BITS);
35
+
36
+
37
object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
38
if (err != NULL) {
39
error_propagate(errp, err);
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
1
The v8.4-RCPC extension implements some new instructions:
1
Implement the MVE saturating shift-right-and-narrow insns
2
* LDAPUR, LDAPURB, LDAPURH, LDAPRSB, LDAPRSH, LDAPRSW
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
* STLUR, STLURB, STLURH
3
4
4
do_srshr() is borrowed from sve_helper.c.
5
These are all in a new subgroup of encodings that sits below the
6
top-level "Loads and Stores" group in the Arm ARM.
7
8
The STLUR* instructions have standard store-release semantics; the
9
LDAPUR* have Load-AcquirePC semantics, but (as with LDAPR*) we choose
10
to implement them as the slightly stronger Load-Acquire.
11
5
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200224172846.13053-4-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
15
---
9
---
16
target/arm/cpu.h | 5 +++
10
target/arm/helper-mve.h | 30 +++++++++++
17
linux-user/elfload.c | 1 +
11
target/arm/mve.decode | 28 ++++++++++
18
target/arm/cpu64.c | 2 +-
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
19
target/arm/translate-a64.c | 90 ++++++++++++++++++++++++++++++++++++++
13
target/arm/translate-mve.c | 12 +++++
20
4 files changed, 97 insertions(+), 1 deletion(-)
14
4 files changed, 174 insertions(+)
21
15
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
18
--- a/target/arm/helper-mve.h
25
+++ b/target/arm/cpu.h
19
+++ b/target/arm/helper-mve.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
}
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
24
+
31
+{
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+}
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
/*
29
+
36
* Feature tests for "does this exist in either 32-bit or 64-bit?"
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
*/
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
index XXXXXXX..XXXXXXX 100644
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
--- a/linux-user/elfload.c
34
+
41
+++ b/linux-user/elfload.c
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
39
+
46
+ GET_FEATURE_ID(aa64_rcpc_8_4, ARM_HWCAP_A64_ILRCPC);
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
return hwcaps;
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
}
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
44
+
51
index XXXXXXX..XXXXXXX 100644
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
--- a/target/arm/cpu64.c
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+++ b/target/arm/cpu64.c
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
49
+
56
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
57
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
58
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 1); /* ARMv8.3-RCPC */
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
59
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
60
cpu->isar.id_aa64isar1 = t;
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
61
55
index XXXXXXX..XXXXXXX 100644
62
t = cpu->isar.id_aa64pfr0;
56
--- a/target/arm/mve.decode
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
+++ b/target/arm/mve.decode
64
index XXXXXXX..XXXXXXX 100644
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
65
--- a/target/arm/translate-a64.c
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
66
+++ b/target/arm/translate-a64.c
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
67
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
68
}
95
}
69
}
96
}
70
97
71
+/*
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
72
+ * LDAPR/STLR (unscaled immediate)
73
+ *
74
+ * 31 30 24 22 21 12 10 5 0
75
+ * +------+-------------+-----+---+--------+-----+----+-----+
76
+ * | size | 0 1 1 0 0 1 | opc | 0 | imm9 | 0 0 | Rn | Rt |
77
+ * +------+-------------+-----+---+--------+-----+----+-----+
78
+ *
79
+ * Rt: source or destination register
80
+ * Rn: base register
81
+ * imm9: unscaled immediate offset
82
+ * opc: 00: STLUR*, 01/10/11: various LDAPUR*
83
+ * size: size of load/store
84
+ */
85
+static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
86
+{
99
+{
87
+ int rt = extract32(insn, 0, 5);
100
+ if (likely(sh < 64)) {
88
+ int rn = extract32(insn, 5, 5);
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
89
+ int offset = sextract32(insn, 12, 9);
90
+ int opc = extract32(insn, 22, 2);
91
+ int size = extract32(insn, 30, 2);
92
+ TCGv_i64 clean_addr, dirty_addr;
93
+ bool is_store = false;
94
+ bool is_signed = false;
95
+ bool extend = false;
96
+ bool iss_sf;
97
+
98
+ if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
99
+ unallocated_encoding(s);
100
+ return;
101
+ }
102
+
103
+ switch (opc) {
104
+ case 0: /* STLURB */
105
+ is_store = true;
106
+ break;
107
+ case 1: /* LDAPUR* */
108
+ break;
109
+ case 2: /* LDAPURS* 64-bit variant */
110
+ if (size == 3) {
111
+ unallocated_encoding(s);
112
+ return;
113
+ }
114
+ is_signed = true;
115
+ break;
116
+ case 3: /* LDAPURS* 32-bit variant */
117
+ if (size > 1) {
118
+ unallocated_encoding(s);
119
+ return;
120
+ }
121
+ is_signed = true;
122
+ extend = true; /* zero-extend 32->64 after signed load */
123
+ break;
124
+ default:
125
+ g_assert_not_reached();
126
+ }
127
+
128
+ iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
129
+
130
+ if (rn == 31) {
131
+ gen_check_sp_alignment(s);
132
+ }
133
+
134
+ dirty_addr = read_cpu_reg_sp(s, rn, 1);
135
+ tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
136
+ clean_addr = clean_data_tbi(s, dirty_addr);
137
+
138
+ if (is_store) {
139
+ /* Store-Release semantics */
140
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
141
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt, iss_sf, true);
142
+ } else {
102
+ } else {
143
+ /*
103
+ /* Rounding the sign bit always produces 0. */
144
+ * Load-AcquirePC semantics; we implement as the slightly more
104
+ return 0;
145
+ * restrictive Load-Acquire.
146
+ */
147
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, is_signed, extend,
148
+ true, rt, iss_sf, true);
149
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
150
+ }
105
+ }
151
+}
106
+}
152
+
107
+
153
/* Load/store register (all forms) */
108
DO_VSHRN_ALL(vshrn, DO_SHR)
154
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
155
{
110
+
156
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
157
case 0x0d: /* AdvSIMD load/store single structure */
112
+ bool *satp)
158
disas_ldst_single_struct(s, insn);
113
+{
159
break;
114
+ if (val > max) {
160
+ case 0x19: /* LDAPR/STLR (unscaled immediate) */
115
+ *satp = true;
161
+ if (extract32(insn, 10, 2) != 0 ||
116
+ return max;
162
+ extract32(insn, 21, 1) != 0) {
117
+ } else if (val < min) {
163
+ unallocated_encoding(s);
118
+ *satp = true;
164
+ break;
119
+ return min;
165
+ }
120
+ } else {
166
+ disas_ldst_ldapr_stlr(s, insn);
121
+ return val;
167
+ break;
122
+ }
168
default:
123
+}
169
unallocated_encoding(s);
124
+
170
break;
125
+/* Saturating narrowing right shifts */
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
128
+ void *vm, uint32_t shift) \
129
+ { \
130
+ LTYPE *m = vm; \
131
+ TYPE *d = vd; \
132
+ uint16_t mask = mve_element_mask(env); \
133
+ bool qc = false; \
134
+ unsigned le; \
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
136
+ bool sat = false; \
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
140
+ } \
141
+ if (qc) { \
142
+ env->vfp.qc[0] = qc; \
143
+ } \
144
+ mve_advance_vpt(env); \
145
+ }
146
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
150
+
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
154
+
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
158
+
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
162
+
163
+#define DO_SHRN_SB(N, M, SATP) \
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
165
+#define DO_SHRN_UB(N, M, SATP) \
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
167
+#define DO_SHRUN_B(N, M, SATP) \
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
169
+
170
+#define DO_SHRN_SH(N, M, SATP) \
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
172
+#define DO_SHRN_UH(N, M, SATP) \
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
174
+#define DO_SHRUN_H(N, M, SATP) \
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
176
+
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)
171
--
224
--
172
2.20.1
225
2.20.1
173
226
174
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
We will eventually remove the early ARM_FEATURE_VFP test,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
so add a proper test for each trans_* that does not already
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
have another ISA test.
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
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(+)
6
14
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200224222232.13807-9-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-vfp.inc.c | 78 ++++++++++++++++++++++++++++++----
13
1 file changed, 69 insertions(+), 9 deletions(-)
14
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
17
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
int pass;
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
uint32_t offset;
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
23
+
24
+ if (a->size == 2
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
25
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
26
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mve.decode
28
+++ b/target/arm/mve.decode
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
33
+
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
46
+{
47
+ uint32_t *d = vd;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
52
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
27
+ return false;
101
+ return false;
28
+ }
102
+ }
29
+
103
+ if (a->rdm == 13 || a->rdm == 15) {
30
/* UNDEF accesses to D16-D31 if they don't exist */
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
31
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
32
return false;
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
34
pass = extract32(offset, 2, 1);
35
offset = extract32(offset, 0, 2) * 8;
36
37
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
38
- return false;
39
- }
40
-
41
if (!vfp_access_check(s)) {
42
return true;
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
45
int pass;
46
uint32_t offset;
47
48
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
49
+ if (a->size == 2
50
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
51
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
52
+ return false;
105
+ return false;
53
+ }
106
+ }
54
+
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
55
/* UNDEF accesses to D16-D31 if they don't exist */
108
+ return true;
56
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
57
return false;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
59
pass = extract32(offset, 2, 1);
60
offset = extract32(offset, 0, 2) * 8;
61
62
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
- return false;
64
- }
65
-
66
if (!vfp_access_check(s)) {
67
return true;
68
}
69
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
70
TCGv_i32 tmp;
71
bool ignore_vfp_enabled = false;
72
73
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
74
+ return false;
75
+ }
109
+ }
76
+
110
+
77
if (arm_dc_feature(s, ARM_FEATURE_M)) {
111
+ qd = mve_qreg_ptr(a->qd);
78
/*
112
+ rdm = load_reg(s, a->rdm);
79
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
114
+ store_reg(s, a->rdm, rdm);
81
{
115
+ tcg_temp_free_ptr(qd);
82
TCGv_i32 tmp;
116
+ mve_update_eci(s);
83
117
+ return true;
84
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
118
+}
85
+ return false;
86
+ }
87
+
88
if (!vfp_access_check(s)) {
89
return true;
90
}
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
92
{
93
TCGv_i32 tmp;
94
95
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
96
+ return false;
97
+ }
98
+
99
/*
100
* VMOV between two general-purpose registers and two single precision
101
* floating point registers
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
103
104
/*
105
* VMOV between two general-purpose registers and one double precision
106
- * floating point register
107
+ * floating point register. Note that this does not require support
108
+ * for double precision arithmetic.
109
*/
110
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
111
+ return false;
112
+ }
113
114
/* UNDEF accesses to D16-D31 if they don't exist */
115
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
116
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
117
uint32_t offset;
118
TCGv_i32 addr, tmp;
119
120
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
121
+ return false;
122
+ }
123
+
124
if (!vfp_access_check(s)) {
125
return true;
126
}
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
128
TCGv_i32 addr;
129
TCGv_i64 tmp;
130
131
+ /* Note that this does not require support for double arithmetic. */
132
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
133
+ return false;
134
+ }
135
+
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
138
return false;
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
140
TCGv_i32 addr, tmp;
141
int i, n;
142
143
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ return false;
145
+ }
146
+
147
n = a->imm;
148
149
if (n == 0 || (a->vd + n) > 32) {
150
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
151
TCGv_i64 tmp;
152
int i, n;
153
154
+ /* Note that this does not require support for double arithmetic. */
155
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
+ return false;
157
+ }
158
+
159
n = a->imm >> 1;
160
161
if (n == 0 || (a->vd + n) > 32 || n > 16) {
162
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
163
TCGv_i32 f0, f1, fd;
164
TCGv_ptr fpst;
165
166
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
167
+ return false;
168
+ }
169
+
170
if (!dc_isar_feature(aa32_fpshvec, s) &&
171
(veclen != 0 || s->vec_stride != 0)) {
172
return false;
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
174
int veclen = s->vec_len;
175
TCGv_i32 f0, fd;
176
177
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
178
+ return false;
179
+ }
180
+
181
if (!dc_isar_feature(aa32_fpshvec, s) &&
182
(veclen != 0 || s->vec_stride != 0)) {
183
return false;
184
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
185
{
186
TCGv_i32 vd, vm;
187
188
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
189
+ return false;
190
+ }
191
+
192
/* Vm/M bits must be zero for the Z variant */
193
if (a->z && a->vm != 0) {
194
return false;
195
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
196
TCGv_i32 vm;
197
TCGv_ptr fpst;
198
199
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
200
+ return false;
201
+ }
202
+
203
if (!vfp_access_check(s)) {
204
return true;
205
}
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
207
TCGv_i32 vm;
208
TCGv_ptr fpst;
209
210
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
211
+ return false;
212
+ }
213
+
214
if (!vfp_access_check(s)) {
215
return true;
216
}
217
--
119
--
218
2.20.1
120
2.20.1
219
121
220
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
2
4
3
Shuffle the order of the checks so that we test the ISA
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
before we test anything else, such as the register arguments.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 3 ++
10
target/arm/mve.decode | 6 +++-
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
5
14
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-vfp.inc.c | 140 +++++++++++++++++----------------
12
1 file changed, 71 insertions(+), 69 deletions(-)
13
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
17
--- a/target/arm/helper-mve.h
17
+++ b/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
return false;
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
}
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
22
22
- /* UNDEF accesses to D16-D31 if they don't exist */
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
23
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
- ((a->vm | a->vn | a->vd) & 0x10)) {
25
+
25
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
return false;
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
}
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
28
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
30
index XXXXXXX..XXXXXXX 100644
30
+ /* UNDEF accesses to D16-D31 if they don't exist */
31
--- a/target/arm/mve.decode
31
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
32
+++ b/target/arm/mve.decode
32
+ ((a->vm | a->vn | a->vd) & 0x10)) {
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
33
return false;
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
}
35
35
36
# Vector add across vector
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
37
return false;
38
+{
38
}
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
39
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
40
- /* UNDEF accesses to D16-D31 if they don't exist */
41
+ rdahi=%rdahi rdalo=%rdalo
41
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
42
+}
42
- ((a->vm | a->vn | a->vd) & 0x10)) {
43
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
# Predicate operations
44
return false;
45
%mask_22_13 22:1 13:3
45
}
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
46
47
index XXXXXXX..XXXXXXX 100644
47
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
48
--- a/target/arm/mve_helper.c
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+++ b/target/arm/mve_helper.c
49
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
50
+ ((a->vm | a->vn | a->vd) & 0x10)) {
51
DO_VADDV(vaddvuh, 2, uint16_t)
51
return false;
52
DO_VADDV(vaddvuw, 4, uint32_t)
52
}
53
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
55
return false;
56
+ uint64_t ra) \
56
}
57
+ { \
57
58
+ uint16_t mask = mve_element_mask(env); \
58
- /* UNDEF accesses to D16-D31 if they don't exist */
59
+ unsigned e; \
59
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
60
+ TYPE *m = vm; \
60
- ((a->vm | a->vd) & 0x10)) {
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
+ if (mask & 1) { \
62
return false;
63
+ ra += (LTYPE)m[H4(e)]; \
63
}
64
+ } \
64
65
+ } \
65
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
66
+ mve_advance_vpt(env); \
66
+ /* UNDEF accesses to D16-D31 if they don't exist */
67
+ return ra; \
67
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
68
+ } \
68
+ ((a->vm | a->vd) & 0x10)) {
69
+
69
return false;
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
70
}
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
71
72
+
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
73
/* Shifts by immediate */
73
return false;
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
74
}
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
75
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
76
- /* UNDEF accesses to D16-D31 if they don't exist */
77
index XXXXXXX..XXXXXXX 100644
77
- if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
78
--- a/target/arm/translate-mve.c
78
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
79
+++ b/target/arm/translate-mve.c
79
return false;
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
80
}
81
return true;
81
82
}
82
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
83
83
+ /* UNDEF accesses to D16-D31 if they don't exist */
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
84
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
85
+{
85
return false;
86
+ /*
86
}
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
87
88
+ * elements of the vector into a 64-bit result stored in
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
+ * a pair of general-purpose registers.
89
TCGv_i64 f0, f1, fd;
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
90
TCGv_ptr fpst;
91
+ */
91
92
+ TCGv_ptr qm;
92
- /* UNDEF accesses to D16-D31 if they don't exist */
93
+ TCGv_i64 rda;
93
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
94
+ TCGv_i32 rdalo, rdahi;
94
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
+
95
return false;
96
+ if (!dc_isar_feature(aa32_mve, s)) {
96
}
97
98
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ /* UNDEF accesses to D16-D31 if they don't exist */
100
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
101
return false;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
105
int veclen = s->vec_len;
106
TCGv_i64 f0, fd;
107
108
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
110
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
115
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
117
return false;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
121
return false;
122
}
123
124
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
125
+ /* UNDEF accesses to D16-D31 if they don't exist. */
126
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
127
+ ((a->vd | a->vn | a->vm) & 0x10)) {
128
return false;
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
132
133
vd = a->vd;
134
135
- /* UNDEF accesses to D16-D31 if they don't exist. */
136
- if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
137
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
138
return false;
139
}
140
141
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
142
+ /* UNDEF accesses to D16-D31 if they don't exist. */
143
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
144
return false;
145
}
146
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
148
{
149
TCGv_i64 vd, vm;
150
151
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
152
+ return false;
97
+ return false;
153
+ }
98
+ }
154
+
99
+ /*
155
/* Vm/M bits must be zero for the Z variant */
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
156
if (a->z && a->vm != 0) {
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
157
return false;
102
+ */
158
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
159
return false;
160
}
161
162
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
163
- return false;
164
- }
165
-
166
if (!vfp_access_check(s)) {
167
return true;
168
}
169
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
170
TCGv_i32 tmp;
171
TCGv_i64 vd;
172
173
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
174
+ return false;
104
+ return false;
175
+ }
105
+ }
176
+
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
177
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
107
+ return true;
178
return false;
179
}
180
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
181
return false;
182
}
183
184
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
185
- return false;
186
- }
187
-
188
if (!vfp_access_check(s)) {
189
return true;
190
}
191
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
192
TCGv_i32 tmp;
193
TCGv_i64 vm;
194
195
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
196
+ return false;
197
+ }
108
+ }
198
+
109
+
199
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
110
+ /*
200
return false;
111
+ * This insn is subject to beat-wise execution. Partial execution
201
}
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
203
return false;
114
+ */
204
}
115
+ if (a->a || mve_skip_first_beat(s)) {
205
116
+ /* Accumulate input from RdaHi:RdaLo */
206
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
117
+ rda = tcg_temp_new_i64();
207
- return false;
118
+ rdalo = load_reg(s, a->rdalo);
208
- }
119
+ rdahi = load_reg(s, a->rdahi);
209
-
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
210
if (!vfp_access_check(s)) {
121
+ tcg_temp_free_i32(rdalo);
211
return true;
122
+ tcg_temp_free_i32(rdahi);
212
}
123
+ } else {
213
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
124
+ /* Accumulate starting at zero */
214
TCGv_ptr fpst;
125
+ rda = tcg_const_i64(0);
215
TCGv_i64 tmp;
216
217
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
218
+ return false;
219
+ }
126
+ }
220
+
127
+
221
if (!dc_isar_feature(aa32_vrint, s)) {
128
+ qm = mve_qreg_ptr(a->qm);
222
return false;
129
+ if (a->u) {
223
}
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
224
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
131
+ } else {
225
return false;
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
226
}
227
228
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
229
- return false;
230
- }
231
-
232
if (!vfp_access_check(s)) {
233
return true;
234
}
235
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
236
TCGv_i64 tmp;
237
TCGv_i32 tcg_rmode;
238
239
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
240
+ return false;
241
+ }
133
+ }
134
+ tcg_temp_free_ptr(qm);
242
+
135
+
243
if (!dc_isar_feature(aa32_vrint, s)) {
136
+ rdalo = tcg_temp_new_i32();
244
return false;
137
+ rdahi = tcg_temp_new_i32();
245
}
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
246
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
247
return false;
140
+ store_reg(s, a->rdalo, rdalo);
248
}
141
+ store_reg(s, a->rdahi, rdahi);
249
142
+ tcg_temp_free_i64(rda);
250
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
143
+ mve_update_eci(s);
251
- return false;
144
+ return true;
252
- }
145
+}
253
-
254
if (!vfp_access_check(s)) {
255
return true;
256
}
257
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
258
TCGv_ptr fpst;
259
TCGv_i64 tmp;
260
261
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
262
+ return false;
263
+ }
264
+
146
+
265
if (!dc_isar_feature(aa32_vrint, s)) {
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
266
return false;
148
{
267
}
149
TCGv_ptr qd;
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
return false;
270
}
271
272
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
273
- return false;
274
- }
275
-
276
if (!vfp_access_check(s)) {
277
return true;
278
}
279
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
280
TCGv_i64 vd;
281
TCGv_i32 vm;
282
283
- /* UNDEF accesses to D16-D31 if they don't exist. */
284
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
285
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
286
return false;
287
}
288
289
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
290
+ /* UNDEF accesses to D16-D31 if they don't exist. */
291
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
292
return false;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
296
TCGv_i64 vm;
297
TCGv_i32 vd;
298
299
- /* UNDEF accesses to D16-D31 if they don't exist. */
300
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
301
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
302
return false;
303
}
304
305
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
306
+ /* UNDEF accesses to D16-D31 if they don't exist. */
307
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
308
return false;
309
}
310
311
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
312
TCGv_i64 vd;
313
TCGv_ptr fpst;
314
315
- /* UNDEF accesses to D16-D31 if they don't exist. */
316
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
317
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
318
return false;
319
}
320
321
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
322
+ /* UNDEF accesses to D16-D31 if they don't exist. */
323
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
324
return false;
325
}
326
327
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
328
TCGv_i32 vd;
329
TCGv_i64 vm;
330
331
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
332
+ return false;
333
+ }
334
+
335
if (!dc_isar_feature(aa32_jscvt, s)) {
336
return false;
337
}
338
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
339
return false;
340
}
341
342
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
343
- return false;
344
- }
345
-
346
if (!vfp_access_check(s)) {
347
return true;
348
}
349
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
350
TCGv_ptr fpst;
351
int frac_bits;
352
353
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
354
+ return false;
355
+ }
356
+
357
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
358
return false;
359
}
360
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
361
return false;
362
}
363
364
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
365
- return false;
366
- }
367
-
368
if (!vfp_access_check(s)) {
369
return true;
370
}
371
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
372
TCGv_i64 vm;
373
TCGv_ptr fpst;
374
375
- /* UNDEF accesses to D16-D31 if they don't exist. */
376
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
377
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
378
return false;
379
}
380
381
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
382
+ /* UNDEF accesses to D16-D31 if they don't exist. */
383
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
384
return false;
385
}
386
387
--
150
--
388
2.20.1
151
2.20.1
389
152
390
153
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The MVE extension to v8.1M includes some new shift instructions which
2
2
sit entirely within the non-coprocessor part of the encoding space
3
We cannot easily create "any" functions for these, because the
3
and which operate only on general-purpose registers. They take up
4
ID_AA64PFR0 fields for FP and SIMD signal "enabled" with zero.
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
Which means that an aarch32-only cpu will return incorrect results
5
with Rm == 13 or 15.
6
when testing the aarch64 registers.
6
7
7
Implement the long shifts by immediate, which perform shifts on a
8
To use these, we must either have context or additionally test
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
vs ARM_FEATURE_AARCH64.
9
an immediate shift count between 1 and 32.
10
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
Message-id: 20200224222232.13807-5-richard.henderson@linaro.org
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
15
---
27
---
16
target/arm/cpu.h | 11 +++++++++++
28
target/arm/helper-mve.h | 3 ++
17
target/arm/cpu.c | 9 ++++++---
29
target/arm/translate.h | 1 +
18
target/arm/machine.c | 5 +++--
30
target/arm/t32.decode | 28 +++++++++++++
19
3 files changed, 20 insertions(+), 5 deletions(-)
31
target/arm/mve_helper.c | 10 +++++
20
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
5 files changed, 132 insertions(+)
22
index XXXXXXX..XXXXXXX 100644
34
23
--- a/target/arm/cpu.h
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
+++ b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
25
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
37
--- a/target/arm/helper-mve.h
26
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
38
+++ b/target/arm/helper-mve.h
27
}
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id)
41
30
+{
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
31
+ return isar_feature_aa32_fpsp_v2(id) || isar_feature_aa32_fpdp_v2(id);
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
+{
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
133
return true;
134
}
135
136
+/*
137
+ * v8.1M MVE wide-shifts
138
+ */
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
140
+ WideShiftImmFn *fn)
141
+{
142
+ TCGv_i64 rda;
143
+ TCGv_i32 rdalo, rdahi;
144
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
147
+ return false;
148
+ }
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
158
+ return true;
159
+ }
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
32
+}
224
+}
33
+
225
+
34
/*
226
/*
35
* We always set the FP and SIMD FP16 fields to indicate identical
227
* Multiply and multiply accumulate
36
* levels of support (assuming SIMD is implemented at all), so
228
*/
37
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
38
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
39
}
40
41
+static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
42
+{
43
+ /* We always set the AdvSIMD and FP fields identically. */
44
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
45
+}
46
+
47
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
48
{
49
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
50
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/cpu.c
53
+++ b/target/arm/cpu.c
54
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
55
* KVM does not currently allow us to lie to the guest about its
56
* ID/feature registers, so the guest always sees what the host has.
57
*/
58
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
59
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
60
+ ? cpu_isar_feature(aa64_fp_simd, cpu)
61
+ : cpu_isar_feature(aa32_vfp, cpu)) {
62
cpu->has_vfp = true;
63
if (!kvm_enabled()) {
64
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
66
* We rely on no XScale CPU having VFP so we can use the same bits in the
67
* TB flags field for VECSTRIDE and XSCALE_CPAR.
68
*/
69
- assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
70
- arm_feature(env, ARM_FEATURE_XSCALE)));
71
+ assert(arm_feature(&cpu->env, ARM_FEATURE_AARCH64) ||
72
+ !cpu_isar_feature(aa32_vfp_simd, cpu) ||
73
+ !arm_feature(env, ARM_FEATURE_XSCALE));
74
75
if (arm_feature(env, ARM_FEATURE_V7) &&
76
!arm_feature(env, ARM_FEATURE_M) &&
77
diff --git a/target/arm/machine.c b/target/arm/machine.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/machine.c
80
+++ b/target/arm/machine.c
81
@@ -XXX,XX +XXX,XX @@
82
static bool vfp_needed(void *opaque)
83
{
84
ARMCPU *cpu = opaque;
85
- CPUARMState *env = &cpu->env;
86
87
- return arm_feature(env, ARM_FEATURE_VFP);
88
+ return (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
89
+ ? cpu_isar_feature(aa64_fp_simd, cpu)
90
+ : cpu_isar_feature(aa32_vfp_simd, cpu));
91
}
92
93
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
94
--
229
--
95
2.20.1
230
2.20.1
96
231
97
232
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
We now have proper ISA checks within each trans_* function.
3
the shift count in another general-purpose register, which might be
4
4
either positive or negative.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
Message-id: 20200224222232.13807-11-richard.henderson@linaro.org
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
11
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
9
---
15
---
10
target/arm/translate.c | 4 ----
16
target/arm/helper-mve.h | 6 +++
11
1 file changed, 4 deletions(-)
17
target/arm/translate.h | 1 +
12
18
target/arm/t32.decode | 16 +++++--
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
21
5 files changed, 182 insertions(+), 3 deletions(-)
22
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
26
+++ b/target/arm/helper-mve.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
30
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
42
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
48
49
/**
50
* arm_tbflags_from_tb:
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
55
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
57
58
&mve_shl_ri rdalo rdahi shim
59
+&mve_shl_rr rdalo rdahi rm
60
61
# rdahi: bits [3:1] from insn, bit 0 is 1
62
# rdalo: bits [3:1] from insn, bit 0 is 0
63
@@ -XXX,XX +XXX,XX @@
64
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
213
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
214
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
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
18
*/
290
*/
19
static int disas_vfp_insn(DisasContext *s, uint32_t insn)
20
{
21
- if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
22
- return 1;
23
- }
24
-
25
/*
26
* If the decodetree decoder handles this insn it will always
27
* emit code to either execute the insn or generate an appropriate
28
--
291
--
29
2.20.1
292
2.20.1
30
293
31
294
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
We will shortly use these to test for VFPv2 and VFPv3
3
4
in different situations.
4
These patterns overlap with the long-shift-by-immediates,
5
5
so we have to rearrange the grouping a little here.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
10
---
10
---
11
target/arm/cpu.h | 18 ++++++++++++++++++
11
target/arm/helper-mve.h | 3 ++
12
1 file changed, 18 insertions(+)
12
target/arm/translate.h | 1 +
13
13
target/arm/t32.decode | 31 ++++++++++++++-----
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
target/arm/mve_helper.c | 10 ++++++
15
index XXXXXXX..XXXXXXX 100644
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
--- a/target/arm/cpu.h
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
+++ b/target/arm/cpu.h
17
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
21
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
32
+++ b/target/arm/translate.h
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
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
20
}
105
}
21
106
+
22
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
23
+{
108
+{
24
+ /* Return true if CPU supports single precision floating point, VFPv2 */
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
25
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
110
+}
26
+}
111
+
27
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
28
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
113
+{
29
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
30
+ /* Return true if CPU supports single precision floating point, VFPv3 */
115
+}
31
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
+}
117
index XXXXXXX..XXXXXXX 100644
33
+
118
--- a/target/arm/translate.c
34
static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
119
+++ b/target/arm/translate.c
35
{
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
36
/* Return true if CPU supports double precision floating point, VFPv2 */
121
37
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
38
}
154
}
39
155
40
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
41
+{
157
+{
42
+ /* Return true if CPU supports double precision floating point, VFPv3 */
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
43
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
160
+ return false;
161
+ }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
177
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
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);
44
+}
206
+}
45
+
207
+
46
/*
208
/*
47
* We always set the FP and SIMD FP16 fields to indicate identical
209
* Multiply and multiply accumulate
48
* levels of support (assuming SIMD is implemented at all), so
210
*/
49
--
211
--
50
2.20.1
212
2.20.1
51
213
52
214
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Use isar feature tests instead of feature bit tests.
4
5
Although none of QEMUs current cpus have VFPv3 without D32,
6
replace the large comment explaining why with one line that
7
sets ARM_HWCAP_ARM_VFPv3D16 under the correct conditions.
8
Mirror the test sequence used in the linux kernel.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20200224222232.13807-14-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
linux-user/elfload.c | 23 +++++++++++++----------
16
1 file changed, 13 insertions(+), 10 deletions(-)
17
18
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/elfload.c
21
+++ b/linux-user/elfload.c
22
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
23
24
/* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
25
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
26
- GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
27
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
28
GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
29
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
30
- GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
31
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
32
- GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
33
+ GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
34
GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
35
GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
36
- /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
37
- * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
38
- * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
39
- * to our VFP_FP16 feature bit.
40
- */
41
- GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
42
- GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
43
+ GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
44
+
45
+ if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
46
+ cpu_isar_feature(aa32_fpdp_v3, cpu)) {
47
+ hwcaps |= ARM_HWCAP_ARM_VFPv3;
48
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
49
+ hwcaps |= ARM_HWCAP_ARM_VFPD32;
50
+ } else {
51
+ hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
52
+ }
53
+ }
54
+ GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
55
56
return hwcaps;
57
}
58
--
59
2.20.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We have converted all tests against these features
4
to ISAR tests.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 3 ---
12
target/arm/cpu.c | 25 -------------------------
13
target/arm/cpu64.c | 3 ---
14
target/arm/kvm32.c | 5 -----
15
target/arm/kvm64.c | 1 -
16
5 files changed, 37 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
23
* mapping in linux-user/elfload.c:get_elf_hwcap().
24
*/
25
enum arm_features {
26
- ARM_FEATURE_VFP,
27
ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
28
ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
29
ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
30
@@ -XXX,XX +XXX,XX @@ enum arm_features {
31
ARM_FEATURE_V7,
32
ARM_FEATURE_THUMB2,
33
ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
34
- ARM_FEATURE_VFP3,
35
ARM_FEATURE_NEON,
36
ARM_FEATURE_M, /* Microcontroller profile. */
37
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
38
@@ -XXX,XX +XXX,XX @@ enum arm_features {
39
ARM_FEATURE_V5,
40
ARM_FEATURE_STRONGARM,
41
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
42
- ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
43
ARM_FEATURE_GENERIC_TIMER,
44
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
45
ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
50
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
51
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
52
set_feature(&cpu->env, ARM_FEATURE_PMSA);
53
}
54
- /* Similarly for the VFP feature bits */
55
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
56
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
57
- }
58
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
59
- set_feature(&cpu->env, ARM_FEATURE_VFP);
60
- }
61
62
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
63
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
64
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
65
uint64_t t;
66
uint32_t u;
67
68
- unset_feature(env, ARM_FEATURE_VFP);
69
- unset_feature(env, ARM_FEATURE_VFP3);
70
- unset_feature(env, ARM_FEATURE_VFP4);
71
-
72
t = cpu->isar.id_aa64isar1;
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
74
cpu->isar.id_aa64isar1 = t;
75
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
76
77
cpu->dtb_compatible = "arm,arm926";
78
set_feature(&cpu->env, ARM_FEATURE_V5);
79
- set_feature(&cpu->env, ARM_FEATURE_VFP);
80
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
81
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
82
cpu->midr = 0x41069265;
83
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
84
85
cpu->dtb_compatible = "arm,arm1026";
86
set_feature(&cpu->env, ARM_FEATURE_V5);
87
- set_feature(&cpu->env, ARM_FEATURE_VFP);
88
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
89
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
90
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
91
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
92
93
cpu->dtb_compatible = "arm,arm1136";
94
set_feature(&cpu->env, ARM_FEATURE_V6);
95
- set_feature(&cpu->env, ARM_FEATURE_VFP);
96
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
97
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
98
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
99
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
100
cpu->dtb_compatible = "arm,arm1136";
101
set_feature(&cpu->env, ARM_FEATURE_V6K);
102
set_feature(&cpu->env, ARM_FEATURE_V6);
103
- set_feature(&cpu->env, ARM_FEATURE_VFP);
104
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
105
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
106
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
107
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
108
109
cpu->dtb_compatible = "arm,arm1176";
110
set_feature(&cpu->env, ARM_FEATURE_V6K);
111
- set_feature(&cpu->env, ARM_FEATURE_VFP);
112
set_feature(&cpu->env, ARM_FEATURE_VAPA);
113
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
114
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
115
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
116
117
cpu->dtb_compatible = "arm,arm11mpcore";
118
set_feature(&cpu->env, ARM_FEATURE_V6K);
119
- set_feature(&cpu->env, ARM_FEATURE_VFP);
120
set_feature(&cpu->env, ARM_FEATURE_VAPA);
121
set_feature(&cpu->env, ARM_FEATURE_MPIDR);
122
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
123
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
124
set_feature(&cpu->env, ARM_FEATURE_M);
125
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
126
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
127
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
128
cpu->midr = 0x410fc240; /* r0p0 */
129
cpu->pmsav7_dregion = 8;
130
cpu->isar.mvfr0 = 0x10110021;
131
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
132
set_feature(&cpu->env, ARM_FEATURE_M);
133
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
134
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
135
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
136
cpu->midr = 0x411fc272; /* r1p2 */
137
cpu->pmsav7_dregion = 8;
138
cpu->isar.mvfr0 = 0x10110221;
139
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
140
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
141
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
142
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
143
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
144
cpu->midr = 0x410fd213; /* r0p3 */
145
cpu->pmsav7_dregion = 16;
146
cpu->sau_sregion = 8;
147
@@ -XXX,XX +XXX,XX @@ static void cortex_r5f_initfn(Object *obj)
148
ARMCPU *cpu = ARM_CPU(obj);
149
150
cortex_r5_initfn(obj);
151
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
152
cpu->isar.mvfr0 = 0x10110221;
153
cpu->isar.mvfr1 = 0x00000011;
154
}
155
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
156
157
cpu->dtb_compatible = "arm,cortex-a8";
158
set_feature(&cpu->env, ARM_FEATURE_V7);
159
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
160
set_feature(&cpu->env, ARM_FEATURE_NEON);
161
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
162
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
163
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
164
165
cpu->dtb_compatible = "arm,cortex-a9";
166
set_feature(&cpu->env, ARM_FEATURE_V7);
167
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
168
set_feature(&cpu->env, ARM_FEATURE_NEON);
169
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
170
set_feature(&cpu->env, ARM_FEATURE_EL3);
171
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
172
173
cpu->dtb_compatible = "arm,cortex-a7";
174
set_feature(&cpu->env, ARM_FEATURE_V7VE);
175
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
176
set_feature(&cpu->env, ARM_FEATURE_NEON);
177
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
178
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
179
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
180
181
cpu->dtb_compatible = "arm,cortex-a15";
182
set_feature(&cpu->env, ARM_FEATURE_V7VE);
183
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
184
set_feature(&cpu->env, ARM_FEATURE_NEON);
185
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
186
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
187
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/target/arm/cpu64.c
190
+++ b/target/arm/cpu64.c
191
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
192
193
cpu->dtb_compatible = "arm,cortex-a57";
194
set_feature(&cpu->env, ARM_FEATURE_V8);
195
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
196
set_feature(&cpu->env, ARM_FEATURE_NEON);
197
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
198
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
199
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
200
201
cpu->dtb_compatible = "arm,cortex-a53";
202
set_feature(&cpu->env, ARM_FEATURE_V8);
203
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
204
set_feature(&cpu->env, ARM_FEATURE_NEON);
205
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
206
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
207
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
208
209
cpu->dtb_compatible = "arm,cortex-a72";
210
set_feature(&cpu->env, ARM_FEATURE_V8);
211
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
212
set_feature(&cpu->env, ARM_FEATURE_NEON);
213
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
214
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
215
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/target/arm/kvm32.c
218
+++ b/target/arm/kvm32.c
219
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
220
* bits, but a few must be tested.
221
*/
222
set_feature(&features, ARM_FEATURE_V7VE);
223
- set_feature(&features, ARM_FEATURE_VFP3);
224
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
225
226
if (extract32(id_pfr0, 12, 4) == 1) {
227
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
228
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
229
set_feature(&features, ARM_FEATURE_NEON);
230
}
231
- if (extract32(ahcf->isar.mvfr1, 28, 4) == 1) {
232
- /* FMAC support implies VFPv4 */
233
- set_feature(&features, ARM_FEATURE_VFP4);
234
- }
235
236
ahcf->features = features;
237
238
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/kvm64.c
241
+++ b/target/arm/kvm64.c
242
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
243
* feature bits.
244
*/
245
set_feature(&features, ARM_FEATURE_V8);
246
- set_feature(&features, ARM_FEATURE_VFP4);
247
set_feature(&features, ARM_FEATURE_NEON);
248
set_feature(&features, ARM_FEATURE_AARCH64);
249
set_feature(&features, ARM_FEATURE_PMU);
250
--
251
2.20.1
252
253
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Those vfp instructions without extra opcode fields can
4
share a common @format for brevity.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200224222232.13807-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/vfp.decode | 134 ++++++++++++++++--------------------------
12
1 file changed, 52 insertions(+), 82 deletions(-)
13
14
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/vfp.decode
17
+++ b/target/arm/vfp.decode
18
@@ -XXX,XX +XXX,XX @@
19
20
%vmov_imm 16:4 0:4
21
22
+@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
23
+@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
+
25
+@vfp_dm_ss ................................ vm=%vm_sp vd=%vd_sp
26
+@vfp_dm_dd ................................ vm=%vm_dp vd=%vd_dp
27
+@vfp_dm_ds ................................ vm=%vm_sp vd=%vd_dp
28
+@vfp_dm_sd ................................ vm=%vm_dp vd=%vd_sp
29
+
30
# VMOV scalar to general-purpose register; note that this does
31
# include some Neon cases.
32
VMOV_to_gp ---- 1110 u:1 1. 1 .... rt:4 1011 ... 1 0000 \
33
@@ -XXX,XX +XXX,XX @@ VDUP ---- 1110 1 b:1 q:1 0 .... rt:4 1011 . 0 e:1 1 0000 \
34
vn=%vn_dp
35
36
VMSR_VMRS ---- 1110 111 l:1 reg:4 rt:4 1010 0001 0000
37
-VMOV_single ---- 1110 000 l:1 .... rt:4 1010 . 001 0000 \
38
- vn=%vn_sp
39
+VMOV_single ---- 1110 000 l:1 .... rt:4 1010 . 001 0000 vn=%vn_sp
40
41
-VMOV_64_sp ---- 1100 010 op:1 rt2:4 rt:4 1010 00.1 .... \
42
- vm=%vm_sp
43
-VMOV_64_dp ---- 1100 010 op:1 rt2:4 rt:4 1011 00.1 .... \
44
- vm=%vm_dp
45
+VMOV_64_sp ---- 1100 010 op:1 rt2:4 rt:4 1010 00.1 .... vm=%vm_sp
46
+VMOV_64_dp ---- 1100 010 op:1 rt2:4 rt:4 1011 00.1 .... vm=%vm_dp
47
48
# Note that the half-precision variants of VLDR and VSTR are
49
# not part of this decodetree at all because they have bits [9:8] == 0b01
50
-VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 \
51
- vd=%vd_sp
52
-VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 \
53
- vd=%vd_dp
54
+VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 vd=%vd_sp
55
+VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 vd=%vd_dp
56
57
# We split the load/store multiple up into two patterns to avoid
58
# overlap with other insns in the "Advanced SIMD load/store and 64-bit move"
59
@@ -XXX,XX +XXX,XX @@ VLDM_VSTM_dp ---- 1101 0.1 l:1 rn:4 .... 1011 imm:8 \
60
vd=%vd_dp p=1 u=0 w=1
61
62
# 3-register VFP data-processing; bits [23,21:20,6] identify the operation.
63
-VMLA_sp ---- 1110 0.00 .... .... 1010 .0.0 .... \
64
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
65
-VMLA_dp ---- 1110 0.00 .... .... 1011 .0.0 .... \
66
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
67
+VMLA_sp ---- 1110 0.00 .... .... 1010 .0.0 .... @vfp_dnm_s
68
+VMLA_dp ---- 1110 0.00 .... .... 1011 .0.0 .... @vfp_dnm_d
69
70
-VMLS_sp ---- 1110 0.00 .... .... 1010 .1.0 .... \
71
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
72
-VMLS_dp ---- 1110 0.00 .... .... 1011 .1.0 .... \
73
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
74
+VMLS_sp ---- 1110 0.00 .... .... 1010 .1.0 .... @vfp_dnm_s
75
+VMLS_dp ---- 1110 0.00 .... .... 1011 .1.0 .... @vfp_dnm_d
76
77
-VNMLS_sp ---- 1110 0.01 .... .... 1010 .0.0 .... \
78
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
79
-VNMLS_dp ---- 1110 0.01 .... .... 1011 .0.0 .... \
80
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
81
+VNMLS_sp ---- 1110 0.01 .... .... 1010 .0.0 .... @vfp_dnm_s
82
+VNMLS_dp ---- 1110 0.01 .... .... 1011 .0.0 .... @vfp_dnm_d
83
84
-VNMLA_sp ---- 1110 0.01 .... .... 1010 .1.0 .... \
85
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
86
-VNMLA_dp ---- 1110 0.01 .... .... 1011 .1.0 .... \
87
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
88
+VNMLA_sp ---- 1110 0.01 .... .... 1010 .1.0 .... @vfp_dnm_s
89
+VNMLA_dp ---- 1110 0.01 .... .... 1011 .1.0 .... @vfp_dnm_d
90
91
-VMUL_sp ---- 1110 0.10 .... .... 1010 .0.0 .... \
92
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
93
-VMUL_dp ---- 1110 0.10 .... .... 1011 .0.0 .... \
94
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
95
+VMUL_sp ---- 1110 0.10 .... .... 1010 .0.0 .... @vfp_dnm_s
96
+VMUL_dp ---- 1110 0.10 .... .... 1011 .0.0 .... @vfp_dnm_d
97
98
-VNMUL_sp ---- 1110 0.10 .... .... 1010 .1.0 .... \
99
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
100
-VNMUL_dp ---- 1110 0.10 .... .... 1011 .1.0 .... \
101
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
102
+VNMUL_sp ---- 1110 0.10 .... .... 1010 .1.0 .... @vfp_dnm_s
103
+VNMUL_dp ---- 1110 0.10 .... .... 1011 .1.0 .... @vfp_dnm_d
104
105
-VADD_sp ---- 1110 0.11 .... .... 1010 .0.0 .... \
106
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
107
-VADD_dp ---- 1110 0.11 .... .... 1011 .0.0 .... \
108
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
109
+VADD_sp ---- 1110 0.11 .... .... 1010 .0.0 .... @vfp_dnm_s
110
+VADD_dp ---- 1110 0.11 .... .... 1011 .0.0 .... @vfp_dnm_d
111
112
-VSUB_sp ---- 1110 0.11 .... .... 1010 .1.0 .... \
113
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
114
-VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... \
115
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
116
+VSUB_sp ---- 1110 0.11 .... .... 1010 .1.0 .... @vfp_dnm_s
117
+VSUB_dp ---- 1110 0.11 .... .... 1011 .1.0 .... @vfp_dnm_d
118
119
-VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... \
120
- vm=%vm_sp vn=%vn_sp vd=%vd_sp
121
-VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... \
122
- vm=%vm_dp vn=%vn_dp vd=%vd_dp
123
+VDIV_sp ---- 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
124
+VDIV_dp ---- 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
125
126
VFM_sp ---- 1110 1.01 .... .... 1010 . o2:1 . 0 .... \
127
vm=%vm_sp vn=%vn_sp vd=%vd_sp o1=1
128
@@ -XXX,XX +XXX,XX @@ VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
129
VMOV_imm_dp ---- 1110 1.11 .... .... 1011 0000 .... \
130
vd=%vd_dp imm=%vmov_imm
131
132
-VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... \
133
- vd=%vd_sp vm=%vm_sp
134
-VMOV_reg_dp ---- 1110 1.11 0000 .... 1011 01.0 .... \
135
- vd=%vd_dp vm=%vm_dp
136
+VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... @vfp_dm_ss
137
+VMOV_reg_dp ---- 1110 1.11 0000 .... 1011 01.0 .... @vfp_dm_dd
138
139
-VABS_sp ---- 1110 1.11 0000 .... 1010 11.0 .... \
140
- vd=%vd_sp vm=%vm_sp
141
-VABS_dp ---- 1110 1.11 0000 .... 1011 11.0 .... \
142
- vd=%vd_dp vm=%vm_dp
143
+VABS_sp ---- 1110 1.11 0000 .... 1010 11.0 .... @vfp_dm_ss
144
+VABS_dp ---- 1110 1.11 0000 .... 1011 11.0 .... @vfp_dm_dd
145
146
-VNEG_sp ---- 1110 1.11 0001 .... 1010 01.0 .... \
147
- vd=%vd_sp vm=%vm_sp
148
-VNEG_dp ---- 1110 1.11 0001 .... 1011 01.0 .... \
149
- vd=%vd_dp vm=%vm_dp
150
+VNEG_sp ---- 1110 1.11 0001 .... 1010 01.0 .... @vfp_dm_ss
151
+VNEG_dp ---- 1110 1.11 0001 .... 1011 01.0 .... @vfp_dm_dd
152
153
-VSQRT_sp ---- 1110 1.11 0001 .... 1010 11.0 .... \
154
- vd=%vd_sp vm=%vm_sp
155
-VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... \
156
- vd=%vd_dp vm=%vm_dp
157
+VSQRT_sp ---- 1110 1.11 0001 .... 1010 11.0 .... @vfp_dm_ss
158
+VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... @vfp_dm_dd
159
160
VCMP_sp ---- 1110 1.11 010 z:1 .... 1010 e:1 1.0 .... \
161
vd=%vd_sp vm=%vm_sp
162
@@ -XXX,XX +XXX,XX @@ VCVT_f32_f16 ---- 1110 1.11 0010 .... 1010 t:1 1.0 .... \
163
VCVT_f64_f16 ---- 1110 1.11 0010 .... 1011 t:1 1.0 .... \
164
vd=%vd_dp vm=%vm_sp
165
166
-# VCVTB and VCVTT to f16: Vd format is always vd_sp; Vm format depends on size bit
167
+# VCVTB and VCVTT to f16: Vd format is always vd_sp;
168
+# Vm format depends on size bit
169
VCVT_f16_f32 ---- 1110 1.11 0011 .... 1010 t:1 1.0 .... \
170
vd=%vd_sp vm=%vm_sp
171
VCVT_f16_f64 ---- 1110 1.11 0011 .... 1011 t:1 1.0 .... \
172
vd=%vd_sp vm=%vm_dp
173
174
-VRINTR_sp ---- 1110 1.11 0110 .... 1010 01.0 .... \
175
- vd=%vd_sp vm=%vm_sp
176
-VRINTR_dp ---- 1110 1.11 0110 .... 1011 01.0 .... \
177
- vd=%vd_dp vm=%vm_dp
178
+VRINTR_sp ---- 1110 1.11 0110 .... 1010 01.0 .... @vfp_dm_ss
179
+VRINTR_dp ---- 1110 1.11 0110 .... 1011 01.0 .... @vfp_dm_dd
180
181
-VRINTZ_sp ---- 1110 1.11 0110 .... 1010 11.0 .... \
182
- vd=%vd_sp vm=%vm_sp
183
-VRINTZ_dp ---- 1110 1.11 0110 .... 1011 11.0 .... \
184
- vd=%vd_dp vm=%vm_dp
185
+VRINTZ_sp ---- 1110 1.11 0110 .... 1010 11.0 .... @vfp_dm_ss
186
+VRINTZ_dp ---- 1110 1.11 0110 .... 1011 11.0 .... @vfp_dm_dd
187
188
-VRINTX_sp ---- 1110 1.11 0111 .... 1010 01.0 .... \
189
- vd=%vd_sp vm=%vm_sp
190
-VRINTX_dp ---- 1110 1.11 0111 .... 1011 01.0 .... \
191
- vd=%vd_dp vm=%vm_dp
192
+VRINTX_sp ---- 1110 1.11 0111 .... 1010 01.0 .... @vfp_dm_ss
193
+VRINTX_dp ---- 1110 1.11 0111 .... 1011 01.0 .... @vfp_dm_dd
194
195
-# VCVT between single and double: Vm precision depends on size; Vd is its reverse
196
-VCVT_sp ---- 1110 1.11 0111 .... 1010 11.0 .... \
197
- vd=%vd_dp vm=%vm_sp
198
-VCVT_dp ---- 1110 1.11 0111 .... 1011 11.0 .... \
199
- vd=%vd_sp vm=%vm_dp
200
+# VCVT between single and double:
201
+# Vm precision depends on size; Vd is its reverse
202
+VCVT_sp ---- 1110 1.11 0111 .... 1010 11.0 .... @vfp_dm_ds
203
+VCVT_dp ---- 1110 1.11 0111 .... 1011 11.0 .... @vfp_dm_sd
204
205
# VCVT from integer to floating point: Vm always single; Vd depends on size
206
VCVT_int_sp ---- 1110 1.11 1000 .... 1010 s:1 1.0 .... \
207
@@ -XXX,XX +XXX,XX @@ VCVT_int_dp ---- 1110 1.11 1000 .... 1011 s:1 1.0 .... \
208
vd=%vd_dp vm=%vm_sp
209
210
# VJCVT is always dp to sp
211
-VJCVT ---- 1110 1.11 1001 .... 1011 11.0 .... \
212
- vd=%vd_sp vm=%vm_dp
213
+VJCVT ---- 1110 1.11 1001 .... 1011 11.0 .... @vfp_dm_sd
214
215
# VCVT between floating-point and fixed-point. The immediate value
216
# is in the same format as a Vm single-precision register number.
217
--
218
2.20.1
219
220
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
Passing the raw op field from the manual is less instructive
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
than it might be. Do the full decode and use the existing
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
helpers to perform the expansion.
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 2 ++
9
target/arm/translate.h | 1 +
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(-)
6
14
7
Since these are v8 insns, VECLEN+VECSTRIDE are already RES0.
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200224222232.13807-18-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/translate-vfp.inc.c | 109 +++++++++++----------------------
15
target/arm/vfp-uncond.decode | 12 ++--
16
2 files changed, 44 insertions(+), 77 deletions(-)
17
18
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-vfp.inc.c
17
--- a/target/arm/helper-mve.h
21
+++ b/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
return true;
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);
24
}
87
}
25
88
+
26
-static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
27
-{
90
+{
28
- uint32_t rd, rn, rm;
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
29
- bool dp = a->dp;
92
+}
30
- bool vmin = a->op;
93
+
31
- TCGv_ptr fpst;
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
32
-
95
+{
33
- if (!dc_isar_feature(aa32_vminmaxnm, s)) {
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
34
- return false;
97
+}
35
- }
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
-
99
index XXXXXXX..XXXXXXX 100644
37
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
100
--- a/target/arm/translate.c
38
- return false;
101
+++ b/target/arm/translate.c
39
- }
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
40
-
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
41
- /* UNDEF accesses to D16-D31 if they don't exist */
42
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
43
- ((a->vm | a->vn | a->vd) & 0x10)) {
44
- return false;
45
- }
46
-
47
- rd = a->vd;
48
- rn = a->vn;
49
- rm = a->vm;
50
-
51
- if (!vfp_access_check(s)) {
52
- return true;
53
- }
54
-
55
- fpst = get_fpstatus_ptr(0);
56
-
57
- if (dp) {
58
- TCGv_i64 frn, frm, dest;
59
-
60
- frn = tcg_temp_new_i64();
61
- frm = tcg_temp_new_i64();
62
- dest = tcg_temp_new_i64();
63
-
64
- neon_load_reg64(frn, rn);
65
- neon_load_reg64(frm, rm);
66
- if (vmin) {
67
- gen_helper_vfp_minnumd(dest, frn, frm, fpst);
68
- } else {
69
- gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
70
- }
71
- neon_store_reg64(dest, rd);
72
- tcg_temp_free_i64(frn);
73
- tcg_temp_free_i64(frm);
74
- tcg_temp_free_i64(dest);
75
- } else {
76
- TCGv_i32 frn, frm, dest;
77
-
78
- frn = tcg_temp_new_i32();
79
- frm = tcg_temp_new_i32();
80
- dest = tcg_temp_new_i32();
81
-
82
- neon_load_reg32(frn, rn);
83
- neon_load_reg32(frm, rm);
84
- if (vmin) {
85
- gen_helper_vfp_minnums(dest, frn, frm, fpst);
86
- } else {
87
- gen_helper_vfp_maxnums(dest, frn, frm, fpst);
88
- }
89
- neon_store_reg32(dest, rd);
90
- tcg_temp_free_i32(frn);
91
- tcg_temp_free_i32(frm);
92
- tcg_temp_free_i32(dest);
93
- }
94
-
95
- tcg_temp_free_ptr(fpst);
96
- return true;
97
-}
98
-
99
/*
100
* Table for converting the most common AArch32 encoding of
101
* rounding mode to arm_fprounding order (which matches the
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
103
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
104
}
104
}
105
105
106
+static bool trans_VMINNM_sp(DisasContext *s, arg_VMINNM_sp *a)
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
107
+{
107
+{
108
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
109
+ return false;
110
+ return false;
110
+ }
111
+ }
111
+ return do_vfp_3op_sp(s, gen_helper_vfp_minnums,
112
+ if (!dc_isar_feature(aa32_mve, s) ||
112
+ a->vd, a->vn, a->vm, false);
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
113
+}
124
+}
114
+
125
+
115
+static bool trans_VMAXNM_sp(DisasContext *s, arg_VMAXNM_sp *a)
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
116
+{
127
+{
117
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
118
+ return false;
119
+ }
120
+ return do_vfp_3op_sp(s, gen_helper_vfp_maxnums,
121
+ a->vd, a->vn, a->vm, false);
122
+}
129
+}
123
+
130
+
124
+static bool trans_VMINNM_dp(DisasContext *s, arg_VMINNM_dp *a)
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
125
+{
132
+{
126
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
127
+ return false;
128
+ }
129
+ return do_vfp_3op_dp(s, gen_helper_vfp_minnumd,
130
+ a->vd, a->vn, a->vm, false);
131
+}
134
+}
132
+
135
+
133
+static bool trans_VMAXNM_dp(DisasContext *s, arg_VMAXNM_dp *a)
136
/*
134
+{
137
* Multiply and multiply accumulate
135
+ if (!dc_isar_feature(aa32_vminmaxnm, s)) {
138
*/
136
+ return false;
137
+ }
138
+ return do_vfp_3op_dp(s, gen_helper_vfp_maxnumd,
139
+ a->vd, a->vn, a->vm, false);
140
+}
141
+
142
static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
143
{
144
/*
145
diff --git a/target/arm/vfp-uncond.decode b/target/arm/vfp-uncond.decode
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/vfp-uncond.decode
148
+++ b/target/arm/vfp-uncond.decode
149
@@ -XXX,XX +XXX,XX @@
150
%vd_dp 22:1 12:4
151
%vd_sp 12:4 22:1
152
153
+@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
154
+@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp
155
+
156
VSEL 1111 1110 0. cc:2 .... .... 1010 .0.0 .... \
157
vm=%vm_sp vn=%vn_sp vd=%vd_sp dp=0
158
VSEL 1111 1110 0. cc:2 .... .... 1011 .0.0 .... \
159
vm=%vm_dp vn=%vn_dp vd=%vd_dp dp=1
160
161
-VMINMAXNM 1111 1110 1.00 .... .... 1010 . op:1 .0 .... \
162
- vm=%vm_sp vn=%vn_sp vd=%vd_sp dp=0
163
-VMINMAXNM 1111 1110 1.00 .... .... 1011 . op:1 .0 .... \
164
- vm=%vm_dp vn=%vn_dp vd=%vd_dp dp=1
165
+VMAXNM_sp 1111 1110 1.00 .... .... 1010 .0.0 .... @vfp_dnm_s
166
+VMINNM_sp 1111 1110 1.00 .... .... 1010 .1.0 .... @vfp_dnm_s
167
+
168
+VMAXNM_dp 1111 1110 1.00 .... .... 1011 .0.0 .... @vfp_dnm_d
169
+VMINNM_dp 1111 1110 1.00 .... .... 1011 .1.0 .... @vfp_dnm_d
170
171
VRINT 1111 1110 1.11 10 rm:2 .... 1010 01.0 .... \
172
vm=%vm_sp vd=%vd_sp dp=0
173
--
139
--
174
2.20.1
140
2.20.1
175
141
176
142
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
Xilinx USB devices are now instantiated through TYPE_CHIPIDEA,
4
and xlnx support in the EHCI code is no longer needed.
5
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
8
Message-id: 20200215122354.13706-3-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/usb/hcd-ehci-sysbus.c | 17 -----------------
12
1 file changed, 17 deletions(-)
13
14
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/usb/hcd-ehci-sysbus.c
17
+++ b/hw/usb/hcd-ehci-sysbus.c
18
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ehci_platform_type_info = {
19
.class_init = ehci_platform_class_init,
20
};
21
22
-static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
23
-{
24
- SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
25
- DeviceClass *dc = DEVICE_CLASS(oc);
26
-
27
- set_bit(DEVICE_CATEGORY_USB, dc->categories);
28
- sec->capsbase = 0x100;
29
- sec->opregbase = 0x140;
30
-}
31
-
32
-static const TypeInfo ehci_xlnx_type_info = {
33
- .name = "xlnx,ps7-usb",
34
- .parent = TYPE_SYS_BUS_EHCI,
35
- .class_init = ehci_xlnx_class_init,
36
-};
37
-
38
static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
39
{
40
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
41
@@ -XXX,XX +XXX,XX @@ static void ehci_sysbus_register_types(void)
42
{
43
type_register_static(&ehci_type_info);
44
type_register_static(&ehci_platform_type_info);
45
- type_register_static(&ehci_xlnx_type_info);
46
type_register_static(&ehci_exynos4210_type_info);
47
type_register_static(&ehci_tegra2_type_info);
48
type_register_static(&ehci_ppc4xx_type_info);
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
There is a kernel and initrd available on github which we can use
4
for testing this machine.
5
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200225172501.29609-3-philmd@redhat.com
12
Message-Id: <20200131170233.14584-1-thuth@redhat.com>
13
[PMD: Renamed test method, moved description from class to method]
14
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
MAINTAINERS | 1 +
18
tests/acceptance/machine_arm_integratorcp.py | 43 ++++++++++++++++++++
19
2 files changed, 44 insertions(+)
20
create mode 100644 tests/acceptance/machine_arm_integratorcp.py
21
22
diff --git a/MAINTAINERS b/MAINTAINERS
23
index XXXXXXX..XXXXXXX 100644
24
--- a/MAINTAINERS
25
+++ b/MAINTAINERS
26
@@ -XXX,XX +XXX,XX @@ S: Maintained
27
F: hw/arm/integratorcp.c
28
F: hw/misc/arm_integrator_debug.c
29
F: include/hw/misc/arm_integrator_debug.h
30
+F: tests/acceptance/machine_arm_integratorcp.py
31
32
MCIMX6UL EVK / i.MX6ul
33
M: Peter Maydell <peter.maydell@linaro.org>
34
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
35
new file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- /dev/null
38
+++ b/tests/acceptance/machine_arm_integratorcp.py
39
@@ -XXX,XX +XXX,XX @@
40
+# Functional test that boots a Linux kernel and checks the console
41
+#
42
+# Copyright (c) 2020 Red Hat, Inc.
43
+#
44
+# Author:
45
+# Thomas Huth <thuth@redhat.com>
46
+#
47
+# This work is licensed under the terms of the GNU GPL, version 2 or
48
+# later. See the COPYING file in the top-level directory.
49
+
50
+import os
51
+
52
+from avocado import skipUnless
53
+from avocado_qemu import Test
54
+from avocado_qemu import wait_for_console_pattern
55
+
56
+class IntegratorMachine(Test):
57
+
58
+ timeout = 90
59
+
60
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
61
+ def test_integratorcp_console(self):
62
+ """
63
+ Boots the Linux kernel and checks that the console is operational
64
+ :avocado: tags=arch:arm
65
+ :avocado: tags=machine:integratorcp
66
+ """
67
+ kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/'
68
+ 'arm-test/kernel/zImage.integrator')
69
+ kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468'
70
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
71
+
72
+ initrd_url = ('https://github.com/zayac/qemu-arm/raw/master/'
73
+ 'arm-test/kernel/arm_root.img')
74
+ initrd_hash = 'b51e4154285bf784e017a37586428332d8c7bd8b'
75
+ initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
76
+
77
+ self.vm.set_console()
78
+ self.vm.add_args('-kernel', kernel_path,
79
+ '-initrd', initrd_path,
80
+ '-append', 'printk.time=0 console=ttyAMA0')
81
+ self.vm.launch()
82
+ wait_for_console_pattern(self, 'Log in as root')
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
As we want to re-use this code, extract it as a new function.
4
Since we are using the PL011 serial console, add a Avocado tag
5
to ease filtering of tests.
6
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200225172501.29609-4-philmd@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
tests/acceptance/machine_arm_integratorcp.py | 18 +++++++++++-------
14
1 file changed, 11 insertions(+), 7 deletions(-)
15
16
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/acceptance/machine_arm_integratorcp.py
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/acceptance/machine_arm_integratorcp.py
19
+++ b/tests/acceptance/machine_arm_integratorcp.py
20
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
21
22
timeout = 90
23
24
- @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
25
- def test_integratorcp_console(self):
26
- """
27
- Boots the Linux kernel and checks that the console is operational
28
- :avocado: tags=arch:arm
29
- :avocado: tags=machine:integratorcp
30
- """
31
+ def boot_integratorcp(self):
32
kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/'
33
'arm-test/kernel/zImage.integrator')
34
kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468'
35
@@ -XXX,XX +XXX,XX @@ class IntegratorMachine(Test):
36
'-initrd', initrd_path,
37
'-append', 'printk.time=0 console=ttyAMA0')
38
self.vm.launch()
39
+
40
+ @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
41
+ def test_integratorcp_console(self):
42
+ """
43
+ Boots the Linux kernel and checks that the console is operational
44
+ :avocado: tags=arch:arm
45
+ :avocado: tags=machine:integratorcp
46
+ :avocado: tags=device:pl011
47
+ """
48
+ self.boot_integratorcp()
49
wait_for_console_pattern(self, 'Log in as root')
50
--
51
2.20.1
52
53
diff view generated by jsdifflib