1
The following changes since commit 4cc10cae64c51e17844dc4358481c393d7bf1ed4:
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-05-06 18:56:17 +0100)
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210510
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
8
8
9
for you to fetch changes up to 8f96812baa53005f32aece3e30b140826c20aa19:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
10
10
11
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9 (2021-05-10 13:24:09 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* docs: fix link in sbsa description
15
* more MVE instructions
16
* linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
17
* target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
17
* target/arm: Check NaN mode before silencing NaN
18
* target/arm: Split neon and vfp translation to their own
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
19
compilation units
19
* hw/arm: Add basic power management to raspi.
20
* target/arm: Make WFI a NOP for userspace emulators
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
21
* hw/sd/omap_mmc: Use device_cold_reset() instead of
22
device_legacy_reset()
23
* include: More fixes for 'extern "C"' block use
24
* hw/arm/imx25_pdk: Fix error message for invalid RAM size
25
* hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
26
* hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
27
21
28
----------------------------------------------------------------
22
----------------------------------------------------------------
29
Alex Bennée (1):
23
Joe Komlodi (1):
30
docs: fix link in sbsa description
24
target/arm: Check NaN mode before silencing NaN
31
25
32
Guenter Roeck (1):
26
Maxim Uvarov (1):
33
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
27
hw/gpio/gpio_pwr: use shutdown function for reboot
34
28
35
Peter Maydell (22):
29
Nolan Leake (1):
36
target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
30
hw/arm: Add basic power management to raspi.
37
target/arm: Move constant expanders to translate.h
31
38
target/arm: Share unallocated_encoding() and gen_exception_insn()
32
Patrick Venture (2):
39
target/arm: Make functions used by m-nocp global
33
docs/system/arm: Add quanta-q7l1-bmc reference
40
target/arm: Split m-nocp trans functions into their own file
34
docs/system/arm: Add quanta-gbs-bmc reference
41
target/arm: Move gen_aa32 functions to translate-a32.h
35
42
target/arm: Move vfp_{load, store}_reg{32, 64} to translate-vfp.c.inc
36
Peter Maydell (18):
43
target/arm: Make functions used by translate-vfp global
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
44
target/arm: Make translate-vfp.c.inc its own compilation unit
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
45
target/arm: Move vfp_reg_ptr() to translate-neon.c.inc
39
target/arm: Make asimd_imm_const() public
46
target/arm: Delete unused typedef
40
target/arm: Use asimd_imm_const for A64 decode
47
target/arm: Move NeonGenThreeOpEnvFn typedef to translate.h
41
target/arm: Use dup_const() instead of bitfield_replicate()
48
target/arm: Make functions used by translate-neon global
42
target/arm: Implement MVE logical immediate insns
49
target/arm: Make translate-neon.c.inc its own compilation unit
43
target/arm: Implement MVE vector shift left by immediate insns
50
target/arm: Make WFI a NOP for userspace emulators
44
target/arm: Implement MVE vector shift right by immediate insns
51
hw/sd/omap_mmc: Use device_cold_reset() instead of device_legacy_reset()
45
target/arm: Implement MVE VSHLL
52
osdep: Make os-win32.h and os-posix.h handle 'extern "C"' themselves
46
target/arm: Implement MVE VSRI, VSLI
53
include/qemu/bswap.h: Handle being included outside extern "C" block
47
target/arm: Implement MVE VSHRN, VRSHRN
54
include/disas/dis-asm.h: Handle being included outside 'extern "C"'
48
target/arm: Implement MVE saturating narrowing shifts
55
hw/misc/mps2-scc: Add "QEMU interface" comment
49
target/arm: Implement MVE VSHLC
56
hw/misc/mps2-scc: Support using CFG0 bit 0 for remapping
50
target/arm: Implement MVE VADDLV
57
hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
58
55
59
Philippe Mathieu-Daudé (1):
56
Philippe Mathieu-Daudé (1):
60
hw/arm/imx25_pdk: Fix error message for invalid RAM size
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
61
58
62
Richard Henderson (1):
59
docs/system/arm/aspeed.rst | 1 +
63
linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
64
82
65
docs/system/arm/mps2.rst | 10 +
66
docs/system/arm/sbsa.rst | 2 +-
67
include/disas/dis-asm.h | 12 +-
68
include/hw/misc/mps2-scc.h | 21 ++
69
include/qemu/bswap.h | 26 ++-
70
include/qemu/osdep.h | 8 +-
71
include/sysemu/os-posix.h | 8 +
72
include/sysemu/os-win32.h | 8 +
73
target/arm/translate-a32.h | 144 +++++++++++++
74
target/arm/translate-a64.h | 2 -
75
target/arm/translate.h | 29 +++
76
hw/arm/imx25_pdk.c | 5 +-
77
hw/arm/mps2-tz.c | 108 +++++++++-
78
hw/arm/xilinx_zynq.c | 2 +-
79
hw/misc/mps2-scc.c | 13 +-
80
hw/sd/omap_mmc.c | 2 +-
81
linux-user/elfload.c | 13 ++
82
target/arm/helper.c | 2 +-
83
target/arm/op_helper.c | 12 ++
84
target/arm/translate-a64.c | 15 --
85
target/arm/translate-m-nocp.c | 221 ++++++++++++++++++++
86
.../arm/{translate-neon.c.inc => translate-neon.c} | 19 +-
87
.../arm/{translate-vfp.c.inc => translate-vfp.c} | 230 +++------------------
88
target/arm/translate.c | 200 ++++--------------
89
disas/arm-a64.cc | 2 -
90
disas/nanomips.cpp | 2 -
91
target/arm/meson.build | 15 +-
92
27 files changed, 718 insertions(+), 413 deletions(-)
93
create mode 100644 target/arm/translate-a32.h
94
create mode 100644 target/arm/translate-m-nocp.c
95
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
96
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (94%)
97
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Patrick Venture <venture@google.com>
2
2
3
Commit dfc388797cc4 ("hw/arm: xlnx: Set all boards' GEM 'phy-addr'
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
property value to 23") configured the PHY address for xilinx-zynq-a9
4
entry.
5
to 23. When trying to boot xilinx-zynq-a9 with zynq-zc702.dtb or
6
zynq-zc706.dtb, this results in the following error message when
7
trying to use the Ethernet interface.
8
5
9
macb e000b000.ethernet eth0: Could not attach PHY (-19)
6
Signed-off-by: Patrick Venture <venture@google.com>
10
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
The devicetree files for ZC702 and ZC706 configure PHY address 7. The
8
Message-id: 20210615192848.1065297-2-venture@google.com
12
documentation for the ZC702 and ZC706 evaluation boards suggest that the
13
PHY address is 7, not 23. Other boards use PHY address 0, 1, 3, or 7.
14
I was unable to find a documentation or a devicetree file suggesting
15
or using PHY address 23. The Ethernet interface starts working with
16
zynq-zc702.dtb and zynq-zc706.dtb when setting the PHY address to 7,
17
so let's use it.
18
19
Cc: Bin Meng <bin.meng@windriver.com>
20
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
21
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
22
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20210504124140.1100346-1-linux@roeck-us.net
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
10
---
26
hw/arm/xilinx_zynq.c | 2 +-
11
docs/system/arm/aspeed.rst | 1 +
27
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+)
28
13
29
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
30
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/xilinx_zynq.c
16
--- a/docs/system/arm/aspeed.rst
32
+++ b/hw/arm/xilinx_zynq.c
17
+++ b/docs/system/arm/aspeed.rst
33
@@ -XXX,XX +XXX,XX @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
18
@@ -XXX,XX +XXX,XX @@ etc.
34
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
19
AST2400 SoC based machines :
35
qdev_set_nic_properties(dev, nd);
20
36
}
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
37
- object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
38
+ object_property_set_int(OBJECT(dev), "phy-addr", 7, &error_abort);
23
39
s = SYS_BUS_DEVICE(dev);
24
AST2500 SoC based machines :
40
sysbus_realize_and_unref(s, &error_fatal);
25
41
sysbus_mmio_map(s, 0, base);
42
--
26
--
43
2.20.1
27
2.20.1
44
28
45
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
These three features are already enabled by TCG, but are missing
3
Add line item reference to quanta-gbs-bmc machine.
4
their hwcap bits. Update HWCAP2 from linux v5.12.
5
4
6
Cc: qemu-stable@nongnu.org (for 6.0.1)
5
Signed-off-by: Patrick Venture <venture@google.com>
7
Buglink: https://bugs.launchpad.net/bugs/1926044
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
Message-id: 20210427214108.88503-1-richard.henderson@linaro.org
8
[PMM: fixed underline Sphinx warning]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
linux-user/elfload.c | 13 +++++++++++++
11
docs/system/arm/nuvoton.rst | 5 +++--
13
1 file changed, 13 insertions(+)
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
13
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
16
--- a/docs/system/arm/nuvoton.rst
18
+++ b/linux-user/elfload.c
17
+++ b/docs/system/arm/nuvoton.rst
19
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@
20
ARM_HWCAP2_A64_SVESM4 = 1 << 6,
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
20
-=====================================================
22
ARM_HWCAP2_A64_FRINT = 1 << 8,
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
+ ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
22
+================================================================
24
+ ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
23
25
+ ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
+ ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
+ ARM_HWCAP2_A64_I8MM = 1 << 13,
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
+ ARM_HWCAP2_A64_BF16 = 1 << 14,
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
+ ARM_HWCAP2_A64_DGH = 1 << 15,
28
Hyperscale applications. The following machines are based on this chip :
30
+ ARM_HWCAP2_A64_RNG = 1 << 16,
29
31
+ ARM_HWCAP2_A64_BTI = 1 << 17,
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
+ ARM_HWCAP2_A64_MTE = 1 << 18,
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
};
32
34
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
35
#define ELF_HWCAP get_elf_hwcap()
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
37
GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
38
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
39
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
40
+ GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
41
+ GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
42
+ GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
43
44
return hwcaps;
45
}
46
--
34
--
47
2.20.1
35
2.20.1
48
36
49
37
diff view generated by jsdifflib
1
We want to split out the .c.inc files which are currently included
1
From: Nolan Leake <nolan@sigbus.net>
2
into translate.c so they are separate compilation units. To do this
2
3
we need to make some functions which are currently file-local to
3
This is just enough to make reboot and poweroff work. Works for
4
translate.c have global scope; create a translate-a32.h paralleling
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
the existing translate-a64.h as a place for these declarations to
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
live, so that code moved into the new compilation units can call
6
do what linux does for reset.
7
them.
7
8
8
The watchdog timer functionality is not yet implemented.
9
The functions made global here are those required by the
9
10
m-nocp.decode functions, except that I have converted the whole
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
family of {read,write}_neon_element* and also both the load_cpu and
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
store_cpu functions for consistency, even though m-nocp only wants a
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
few functions from each.
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
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/]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210430132740.10391-4-peter.maydell@linaro.org
18
---
18
---
19
target/arm/translate-a32.h | 57 ++++++++++++++++++++++++++++++++++
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
20
target/arm/translate.c | 39 +++++------------------
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
21
target/arm/translate-vfp.c.inc | 2 +-
21
hw/arm/bcm2835_peripherals.c | 13 ++-
22
3 files changed, 65 insertions(+), 33 deletions(-)
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
create mode 100644 target/arm/translate-a32.h
23
hw/misc/meson.build | 1 +
24
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
32
@@ -XXX,XX +XXX,XX @@
33
#include "hw/misc/bcm2835_mphi.h"
34
#include "hw/misc/bcm2835_thermal.h"
35
#include "hw/misc/bcm2835_cprman.h"
36
+#include "hw/misc/bcm2835_powermgt.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/sd/bcm2835_sdhost.h"
39
#include "hw/gpio/bcm2835_gpio.h"
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
26
new file mode 100644
50
new file mode 100644
27
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
28
--- /dev/null
52
--- /dev/null
29
+++ b/target/arm/translate-a32.h
53
+++ b/include/hw/misc/bcm2835_powermgt.h
30
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
31
+/*
55
+/*
32
+ * AArch32 translation, common definitions.
56
+ * BCM2835 Power Management emulation
33
+ *
57
+ *
34
+ * Copyright (c) 2021 Linaro, Ltd.
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
35
+ *
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
36
+ * This library is free software; you can redistribute it and/or
60
+ *
37
+ * modify it under the terms of the GNU Lesser General Public
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38
+ * License as published by the Free Software Foundation; either
62
+ * See the COPYING file in the top-level directory.
39
+ * version 2.1 of the License, or (at your option) any later version.
40
+ *
41
+ * This library is distributed in the hope that it will be useful,
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
+ * Lesser General Public License for more details.
45
+ *
46
+ * You should have received a copy of the GNU Lesser General Public
47
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
48
+ */
63
+ */
49
+
64
+
50
+#ifndef TARGET_ARM_TRANSLATE_A64_H
65
+#ifndef BCM2835_POWERMGT_H
51
+#define TARGET_ARM_TRANSLATE_A64_H
66
+#define BCM2835_POWERMGT_H
52
+
67
+
53
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
68
+#include "hw/sysbus.h"
54
+void arm_gen_condlabel(DisasContext *s);
69
+#include "qom/object.h"
55
+bool vfp_access_check(DisasContext *s);
70
+
56
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
57
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
58
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
73
+
59
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
74
+struct BCM2835PowerMgtState {
60
+
75
+ SysBusDevice busdev;
61
+static inline TCGv_i32 load_cpu_offset(int offset)
76
+ MemoryRegion iomem;
62
+{
77
+
63
+ TCGv_i32 tmp = tcg_temp_new_i32();
78
+ uint32_t rstc;
64
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
79
+ uint32_t rsts;
65
+ return tmp;
80
+ uint32_t wdog;
66
+}
81
+};
67
+
68
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
69
+
70
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
71
+{
72
+ tcg_gen_st_i32(var, cpu_env, offset);
73
+ tcg_temp_free_i32(var);
74
+}
75
+
76
+#define store_cpu_field(var, name) \
77
+ store_cpu_offset(var, offsetof(CPUARMState, name))
78
+
79
+/* Create a new temporary and set it to the value of a CPU register. */
80
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
81
+{
82
+ TCGv_i32 tmp = tcg_temp_new_i32();
83
+ load_reg_var(s, tmp, reg);
84
+ return tmp;
85
+}
86
+
82
+
87
+#endif
83
+#endif
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
89
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate.c
86
--- a/hw/arm/bcm2835_peripherals.c
91
+++ b/target/arm/translate.c
87
+++ b/hw/arm/bcm2835_peripherals.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
96
}
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
92
@@ -XXX,XX +XXX,XX @@
122
@@ -XXX,XX +XXX,XX @@
93
#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
123
+/*
94
124
+ * BCM2835 Power Management emulation
95
#include "translate.h"
125
+ *
96
+#include "translate-a32.h"
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
97
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
98
#if defined(CONFIG_USER_ONLY)
128
+ *
99
#define IS_USER(s) 1
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
100
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
130
+ * See the COPYING file in the top-level directory.
101
}
131
+ */
102
132
+
103
/* Generate a label used for skipping this instruction */
133
+#include "qemu/osdep.h"
104
-static void arm_gen_condlabel(DisasContext *s)
134
+#include "qemu/log.h"
105
+void arm_gen_condlabel(DisasContext *s)
135
+#include "qemu/module.h"
106
{
136
+#include "hw/misc/bcm2835_powermgt.h"
107
if (!s->condjmp) {
137
+#include "migration/vmstate.h"
108
s->condlabel = gen_new_label();
138
+#include "sysemu/runstate.h"
109
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
139
+
110
}
140
+#define PASSWORD 0x5a000000
111
}
141
+#define PASSWORD_MASK 0xff000000
112
142
+
113
-static inline TCGv_i32 load_cpu_offset(int offset)
143
+#define R_RSTC 0x1c
114
-{
144
+#define V_RSTC_RESET 0x20
115
- TCGv_i32 tmp = tcg_temp_new_i32();
145
+#define R_RSTS 0x20
116
- tcg_gen_ld_i32(tmp, cpu_env, offset);
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
117
- return tmp;
147
+#define R_WDOG 0x24
118
-}
148
+
119
-
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
120
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
150
+ unsigned size)
121
-
151
+{
122
-static inline void store_cpu_offset(TCGv_i32 var, int offset)
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
123
-{
153
+ uint32_t res = 0;
124
- tcg_gen_st_i32(var, cpu_env, offset);
154
+
125
- tcg_temp_free_i32(var);
155
+ switch (offset) {
126
-}
156
+ case R_RSTC:
127
-
157
+ res = s->rstc;
128
-#define store_cpu_field(var, name) \
158
+ break;
129
- store_cpu_offset(var, offsetof(CPUARMState, name))
159
+ case R_RSTS:
130
-
160
+ res = s->rsts;
131
/* The architectural value of PC. */
161
+ break;
132
static uint32_t read_pc(DisasContext *s)
162
+ case R_WDOG:
133
{
163
+ res = s->wdog;
134
@@ -XXX,XX +XXX,XX @@ static uint32_t read_pc(DisasContext *s)
164
+ break;
135
}
165
+
136
166
+ default:
137
/* Set a variable to the value of a CPU register. */
167
+ qemu_log_mask(LOG_UNIMP,
138
-static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
139
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
169
+ "\n", offset);
140
{
170
+ res = 0;
141
if (reg == 15) {
171
+ break;
142
tcg_gen_movi_i32(var, read_pc(s));
172
+ }
143
@@ -XXX,XX +XXX,XX @@ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
173
+
144
}
174
+ return res;
145
}
175
+}
146
176
+
147
-/* Create a new temporary and set it to the value of a CPU register. */
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
148
-static inline TCGv_i32 load_reg(DisasContext *s, int reg)
178
+ uint64_t value, unsigned size)
149
-{
179
+{
150
- TCGv_i32 tmp = tcg_temp_new_i32();
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
151
- load_reg_var(s, tmp, reg);
181
+
152
- return tmp;
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
153
-}
183
+ qemu_log_mask(LOG_GUEST_ERROR,
154
-
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
155
/*
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
156
* Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
186
+ value, offset);
157
* This is used for load/store for which use of PC implies (literal),
187
+ return;
158
@@ -XXX,XX +XXX,XX @@ static inline void vfp_store_reg32(TCGv_i32 var, int reg)
188
+ }
159
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
189
+
160
}
190
+ value = value & ~PASSWORD_MASK;
161
191
+
162
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
192
+ switch (offset) {
163
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
193
+ case R_RSTC:
164
{
194
+ s->rstc = value;
165
long off = neon_element_offset(reg, ele, memop);
195
+ if (value & V_RSTC_RESET) {
166
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
167
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
168
}
198
+ } else {
169
}
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
170
200
+ }
171
-static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
201
+ }
172
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
202
+ break;
173
{
203
+ case R_RSTS:
174
long off = neon_element_offset(reg, ele, memop);
204
+ qemu_log_mask(LOG_UNIMP,
175
205
+ "bcm2835_powermgt_write: RSTS\n");
176
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
206
+ s->rsts = value;
177
}
207
+ break;
178
}
208
+ case R_WDOG:
179
209
+ qemu_log_mask(LOG_UNIMP,
180
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
210
+ "bcm2835_powermgt_write: WDOG\n");
181
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
211
+ s->wdog = value;
182
{
212
+ break;
183
long off = neon_element_offset(reg, ele, memop);
213
+
184
214
+ default:
185
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
215
+ qemu_log_mask(LOG_UNIMP,
186
}
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
187
}
217
+ "\n", offset);
188
218
+ break;
189
-static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
219
+ }
190
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
220
+}
191
{
221
+
192
long off = neon_element_offset(reg, ele, memop);
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
193
223
+ .read = bcm2835_powermgt_read,
194
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
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
195
index XXXXXXX..XXXXXXX 100644
284
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/translate-vfp.c.inc
285
--- a/hw/misc/meson.build
197
+++ b/target/arm/translate-vfp.c.inc
286
+++ b/hw/misc/meson.build
198
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
199
* The most usual kind of VFP access check, for everything except
288
'bcm2835_rng.c',
200
* FMXR/FMRX to the always-available special registers.
289
'bcm2835_thermal.c',
201
*/
290
'bcm2835_cprman.c',
202
-static bool vfp_access_check(DisasContext *s)
291
+ 'bcm2835_powermgt.c',
203
+bool vfp_access_check(DisasContext *s)
292
))
204
{
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
205
return full_vfp_access_check(s, false);
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
206
}
207
--
295
--
208
2.20.1
296
2.20.1
209
297
210
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The i.MX25 PDK board has 2 banks for SDRAM, each can
3
Add a test booting and quickly shutdown a raspi2 machine,
4
address up to 256 MiB. So the total RAM usable for this
4
to test the power management model:
5
board is 512M. When we ask for more we get a misleading
6
error message:
7
5
8
$ qemu-system-arm -M imx25-pdk -m 513M
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
9
qemu-system-arm: Invalid RAM size, should be 128 MiB
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
10
44
11
Update the error message to better match the reality:
12
13
$ qemu-system-arm -M imx25-pdk -m 513M
14
qemu-system-arm: RAM size more than 512 MiB is not supported
15
16
Fixes: bf350daae02 ("arm/imx25_pdk: drop RAM size fixup")
17
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
19
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
20
Message-id: 20210407225608.1882855-1-f4bug@amsat.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
49
---
23
hw/arm/imx25_pdk.c | 5 ++---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
24
1 file changed, 2 insertions(+), 3 deletions(-)
51
1 file changed, 43 insertions(+)
25
52
26
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
27
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/imx25_pdk.c
55
--- a/tests/acceptance/boot_linux_console.py
29
+++ b/hw/arm/imx25_pdk.c
56
+++ b/tests/acceptance/boot_linux_console.py
30
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info imx25_pdk_binfo;
57
@@ -XXX,XX +XXX,XX @@
31
58
from avocado import skip
32
static void imx25_pdk_init(MachineState *machine)
59
from avocado import skipUnless
33
{
60
from avocado_qemu import Test
34
- MachineClass *mc = MACHINE_GET_CLASS(machine);
61
+from avocado_qemu import exec_command
35
IMX25PDK *s = g_new0(IMX25PDK, 1);
62
from avocado_qemu import exec_command_and_wait_for_pattern
36
unsigned int ram_size;
63
from avocado_qemu import interrupt_interactive_console_until_pattern
37
unsigned int alias_offset;
64
from avocado_qemu import wait_for_console_pattern
38
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_init(MachineState *machine)
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
39
66
"""
40
/* We need to initialize our memory */
67
self.do_test_arm_raspi2(0)
41
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
68
42
- char *sz = size_to_str(mc->default_ram_size);
69
+ def test_arm_raspi2_initrd(self):
43
- error_report("Invalid RAM size, should be %s", sz);
70
+ """
44
+ char *sz = size_to_str(FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
71
+ :avocado: tags=arch:arm
45
+ error_report("RAM size more than %s is not supported", sz);
72
+ :avocado: tags=machine:raspi2
46
g_free(sz);
73
+ """
47
exit(EXIT_FAILURE);
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
48
}
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
81
+
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
84
+ 'arm/rootfs-armv7a.cpio.gz')
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
89
+
90
+ self.vm.set_console()
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
93
+ 'panic=-1 noreboot ' +
94
+ 'dwc_otg.fiq_fsm_enable=0')
95
+ self.vm.add_args('-kernel', kernel_path,
96
+ '-dtb', dtb_path,
97
+ '-initrd', initrd_path,
98
+ '-append', kernel_command_line,
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
49
--
114
--
50
2.20.1
115
2.20.1
51
116
52
117
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
A trailing _ makes all the difference to the rendered link.
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: Alex Bennée <alex.bennee@linaro.org>
7
To avoid this, we check to see what NaN mode we're running in before we call
6
Message-id: 20210428131316.31390-1-alex.bennee@linaro.org
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
docs/system/arm/sbsa.rst | 2 +-
16
target/arm/helper-a64.c | 12 +++++++++---
11
1 file changed, 1 insertion(+), 1 deletion(-)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
12
19
13
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/sbsa.rst
22
--- a/target/arm/helper-a64.c
16
+++ b/docs/system/arm/sbsa.rst
23
+++ b/target/arm/helper-a64.c
17
@@ -XXX,XX +XXX,XX @@ Arm Server Base System Architecture Reference board (``sbsa-ref``)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
18
While the `virt` board is a generic board platform that doesn't match
25
float16 nan = a;
19
any real hardware the `sbsa-ref` board intends to look like real
26
if (float16_is_signaling_nan(a, fpst)) {
20
hardware. The `Server Base System Architecture
27
float_raise(float_flag_invalid, fpst);
21
-<https://developer.arm.com/documentation/den0029/latest>` defines a
28
- nan = float16_silence_nan(a, fpst);
22
+<https://developer.arm.com/documentation/den0029/latest>`_ defines a
29
+ if (!fpst->default_nan_mode) {
23
minimum base line of hardware support and importantly how the firmware
30
+ nan = float16_silence_nan(a, fpst);
24
reports that to any operating system. It is a static system that
31
+ }
25
reports a very minimal DT to the firmware for non-discoverable
32
}
33
if (fpst->default_nan_mode) {
34
nan = float16_default_nan(fpst);
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
26
--
127
--
27
2.20.1
128
2.20.1
28
129
29
130
diff view generated by jsdifflib
Deleted patch
1
In tlbi_aa64_vae2is_write() the calculation
2
bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
3
pageaddr)
4
1
5
has the two arms of the ?: expression reversed. Fix the bug.
6
7
Fixes: b6ad6062f1e5
8
Reported-by: Rebecca Cran <rebecca@nuviainc.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
12
Reviewed-by: Rebecca Cran <rebecca@nuviainc.com>
13
Message-id: 20210420123106.10861-1-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
uint64_t pageaddr = sextract64(value << 12, 0, 56);
24
bool secure = arm_is_secure_below_el3(env);
25
int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
26
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
27
+ int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
28
pageaddr);
29
30
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
Make the remaining functions which are needed by translate-vfp.c.inc
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
global.
3
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
10
[PMM: tweaked commit message]
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-8-peter.maydell@linaro.org
8
---
12
---
9
target/arm/translate-a32.h | 18 ++++++++++++++++++
13
hw/gpio/gpio_pwr.c | 2 +-
10
target/arm/translate.c | 25 ++++++++-----------------
14
1 file changed, 1 insertion(+), 1 deletion(-)
11
2 files changed, 26 insertions(+), 17 deletions(-)
12
15
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
18
--- a/hw/gpio/gpio_pwr.c
16
+++ b/target/arm/translate-a32.h
19
+++ b/hw/gpio/gpio_pwr.c
17
@@ -XXX,XX +XXX,XX @@ void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
18
void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
19
void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
20
void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
21
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
22
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
23
+void gen_set_condexec(DisasContext *s);
24
+void gen_set_pc_im(DisasContext *s, target_ulong val);
25
+void gen_lookup_tb(DisasContext *s);
26
+long vfp_reg_offset(bool dp, unsigned reg);
27
+long neon_full_reg_offset(unsigned reg);
28
29
static inline TCGv_i32 load_cpu_offset(int offset)
30
{
22
{
31
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
23
if (level) {
32
return tmp;
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
33
}
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
34
35
+void store_reg(DisasContext *s, int reg, TCGv_i32 var);
36
+
37
void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
38
TCGv_i32 a32, int index, MemOp opc);
39
void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
40
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
41
#undef DO_GEN_LD
42
#undef DO_GEN_ST
43
44
+#if defined(CONFIG_USER_ONLY)
45
+#define IS_USER(s) 1
46
+#else
47
+#define IS_USER(s) (s->user)
48
+#endif
49
+
50
+/* Set NZCV flags from the high 4 bits of var. */
51
+#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
52
+
53
#endif
54
diff --git a/target/arm/translate.c b/target/arm/translate.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate.c
57
+++ b/target/arm/translate.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "translate.h"
60
#include "translate-a32.h"
61
62
-#if defined(CONFIG_USER_ONLY)
63
-#define IS_USER(s) 1
64
-#else
65
-#define IS_USER(s) (s->user)
66
-#endif
67
-
68
/* These are TCG temporaries used only by the legacy iwMMXt decoder */
69
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
70
/* These are TCG globals which alias CPUARMState fields */
71
@@ -XXX,XX +XXX,XX @@ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
72
* This is used for load/store for which use of PC implies (literal),
73
* or ADD that implies ADR.
74
*/
75
-static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
76
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
77
{
78
TCGv_i32 tmp = tcg_temp_new_i32();
79
80
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
81
82
/* Set a CPU register. The source must be a temporary and will be
83
marked as dead. */
84
-static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
85
+void store_reg(DisasContext *s, int reg, TCGv_i32 var)
86
{
87
if (reg == 15) {
88
/* In Thumb mode, we must ignore bit 0.
89
@@ -XXX,XX +XXX,XX @@ static void store_sp_checked(DisasContext *s, TCGv_i32 var)
90
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
91
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
92
93
-
94
-static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
95
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
96
{
97
TCGv_i32 tmp_mask = tcg_const_i32(mask);
98
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
99
tcg_temp_free_i32(tmp_mask);
100
}
101
-/* Set NZCV flags from the high 4 bits of var. */
102
-#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
103
104
static void gen_exception_internal(int excp)
105
{
106
@@ -XXX,XX +XXX,XX @@ void arm_gen_test_cc(int cc, TCGLabel *label)
107
arm_free_cc(&cmp);
108
}
109
110
-static inline void gen_set_condexec(DisasContext *s)
111
+void gen_set_condexec(DisasContext *s)
112
{
113
if (s->condexec_mask) {
114
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
115
@@ -XXX,XX +XXX,XX @@ static inline void gen_set_condexec(DisasContext *s)
116
}
26
}
117
}
27
}
118
28
119
-static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
120
+void gen_set_pc_im(DisasContext *s, target_ulong val)
121
{
122
tcg_gen_movi_i32(cpu_R[15], val);
123
}
124
@@ -XXX,XX +XXX,XX @@ static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
125
}
126
127
/* Force a TB lookup after an instruction that changes the CPU state. */
128
-static inline void gen_lookup_tb(DisasContext *s)
129
+void gen_lookup_tb(DisasContext *s)
130
{
131
tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
132
s->base.is_jmp = DISAS_EXIT;
133
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
134
/*
135
* Return the offset of a "full" NEON Dreg.
136
*/
137
-static long neon_full_reg_offset(unsigned reg)
138
+long neon_full_reg_offset(unsigned reg)
139
{
140
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
141
}
142
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp memop)
143
}
144
145
/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
146
-static long vfp_reg_offset(bool dp, unsigned reg)
147
+long vfp_reg_offset(bool dp, unsigned reg)
148
{
149
if (dp) {
150
return neon_element_offset(reg, 0, MO_64);
151
--
29
--
152
2.20.1
30
2.20.1
153
31
154
32
diff view generated by jsdifflib
1
On some boards, SCC config register CFG0 bit 0 controls whether
1
In do_ldst(), the calculation of the offset needs to be based on the
2
parts of the board memory map are remapped. Support this with:
2
size of the memory access, not the size of the elements in the
3
* a device property scc-cfg0 so the board can specify the
3
vector. This meant we were getting it wrong for the widening and
4
initial value of the CFG0 register
4
narrowing variants of the various VLDR and VSTR insns.
5
* an outbound GPIO line which tracks bit 0 and which the board
6
can wire up to provide the remapping
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
11
Message-id: 20210504120912.23094-3-peter.maydell@linaro.org
12
---
9
---
13
include/hw/misc/mps2-scc.h | 9 +++++++++
10
target/arm/translate-mve.c | 17 +++++++++--------
14
hw/misc/mps2-scc.c | 13 ++++++++++---
11
1 file changed, 9 insertions(+), 8 deletions(-)
15
2 files changed, 19 insertions(+), 3 deletions(-)
16
12
17
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/mps2-scc.h
15
--- a/target/arm/translate-mve.c
20
+++ b/include/hw/misc/mps2-scc.h
16
+++ b/target/arm/translate-mve.c
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
22
* + QOM property "scc-cfg4": value of the read-only CFG4 register
18
}
23
* + QOM property "scc-aid": value of the read-only SCC_AID register
24
* + QOM property "scc-id": value of the read-only SCC_ID register
25
+ * + QOM property "scc-cfg0": reset value of the CFG0 register
26
* + QOM property array "oscclk": reset values of the OSCCLK registers
27
* (which are accessed via the SYS_CFG channel provided by this device)
28
+ * + named GPIO output "remap": this tracks the value of CFG0 register
29
+ * bit 0. Boards where this bit controls memory remapping should
30
+ * connect this GPIO line to a function performing that mapping.
31
+ * Boards where bit 0 has no special function should leave the GPIO
32
+ * output disconnected.
33
*/
34
#ifndef MPS2_SCC_H
35
#define MPS2_SCC_H
36
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
37
uint32_t num_oscclk;
38
uint32_t *oscclk;
39
uint32_t *oscclk_reset;
40
+ uint32_t cfg0_reset;
41
+
42
+ qemu_irq remap;
43
};
44
45
#endif
46
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/misc/mps2-scc.c
49
+++ b/hw/misc/mps2-scc.c
50
@@ -XXX,XX +XXX,XX @@
51
#include "qemu/bitops.h"
52
#include "trace.h"
53
#include "hw/sysbus.h"
54
+#include "hw/irq.h"
55
#include "migration/vmstate.h"
56
#include "hw/registerfields.h"
57
#include "hw/misc/mps2-scc.h"
58
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
59
switch (offset) {
60
case A_CFG0:
61
/*
62
- * TODO on some boards bit 0 controls RAM remapping;
63
- * on others bit 1 is CPU_WAIT.
64
+ * On some boards bit 0 controls board-specific remapping;
65
+ * we always reflect bit 0 in the 'remap' GPIO output line,
66
+ * and let the board wire it up or not as it chooses.
67
+ * TODO on some boards bit 1 is CPU_WAIT.
68
*/
69
s->cfg0 = value;
70
+ qemu_set_irq(s->remap, s->cfg0 & 1);
71
break;
72
case A_CFG1:
73
s->cfg1 = value;
74
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
75
int i;
76
77
trace_mps2_scc_reset();
78
- s->cfg0 = 0;
79
+ s->cfg0 = s->cfg0_reset;
80
s->cfg1 = 0;
81
s->cfg2 = 0;
82
s->cfg5 = 0;
83
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_init(Object *obj)
84
85
memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
86
sysbus_init_mmio(sbd, &s->iomem);
87
+ qdev_init_gpio_out_named(DEVICE(obj), &s->remap, "remap", 1);
88
}
19
}
89
20
90
static void mps2_scc_realize(DeviceState *dev, Error **errp)
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
91
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
92
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
23
+ unsigned msize)
93
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
24
{
94
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
25
TCGv_i32 addr;
95
+ /* Reset value for CFG0 register */
26
uint32_t offset;
96
+ DEFINE_PROP_UINT32("scc-cfg0", MPS2SCC, cfg0_reset, 0),
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
97
/*
28
return true;
98
* These are the initial settings for the source clocks on the board.
29
}
99
* In hardware they can be configured via a config file read by the
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);
42
}
43
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
47
{ \
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
50
{ NULL, gen_helper_mve_##ULD }, \
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
54
}
55
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
62
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
64
{
100
--
65
--
101
2.20.1
66
2.20.1
102
67
103
68
diff view generated by jsdifflib
1
Make dis-asm.h handle being included outside an 'extern "C"' block;
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
this allows us to remove the 'extern "C"' blocks that our two C++
2
insns had some bugs:
3
files that include it are using.
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
4
9
10
In particular, fixing the second of these allows us to recast
11
the implementation to avoid 128-bit arithmetic entirely.
12
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
7
---
20
---
8
include/disas/dis-asm.h | 12 ++++++++++--
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
9
disas/arm-a64.cc | 2 --
22
1 file changed, 21 insertions(+), 17 deletions(-)
10
disas/nanomips.cpp | 2 --
11
3 files changed, 10 insertions(+), 6 deletions(-)
12
23
13
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/include/disas/dis-asm.h
26
--- a/target/arm/mve_helper.c
16
+++ b/include/disas/dis-asm.h
27
+++ b/target/arm/mve_helper.c
17
@@ -XXX,XX +XXX,XX @@
18
#ifndef DISAS_DIS_ASM_H
19
#define DISAS_DIS_ASM_H
20
21
+#include "qemu/bswap.h"
22
+
23
+#ifdef __cplusplus
24
+extern "C" {
25
+#endif
26
+
27
typedef void *PTR;
28
typedef uint64_t bfd_vma;
29
typedef int64_t bfd_signed_vma;
30
@@ -XXX,XX +XXX,XX @@ bool cap_disas_plugin(disassemble_info *info, uint64_t pc, size_t size);
31
32
/* from libbfd */
33
34
-#include "qemu/bswap.h"
35
-
36
static inline bfd_vma bfd_getl64(const bfd_byte *addr)
37
{
38
return ldq_le_p(addr);
39
@@ -XXX,XX +XXX,XX @@ static inline bfd_vma bfd_getb16(const bfd_byte *addr)
40
41
typedef bool bfd_boolean;
42
43
+#ifdef __cplusplus
44
+}
45
+#endif
46
+
47
#endif /* DISAS_DIS_ASM_H */
48
diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc
49
index XXXXXXX..XXXXXXX 100644
50
--- a/disas/arm-a64.cc
51
+++ b/disas/arm-a64.cc
52
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
53
*/
29
*/
54
30
55
#include "qemu/osdep.h"
31
#include "qemu/osdep.h"
56
-extern "C" {
32
-#include "qemu/int128.h"
57
#include "disas/dis-asm.h"
33
#include "cpu.h"
58
-}
34
#include "internals.h"
59
35
#include "vec_internal.h"
60
#include "vixl/a64/disasm-a64.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
61
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
62
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
38
63
index XXXXXXX..XXXXXXX 100644
39
/*
64
--- a/disas/nanomips.cpp
40
- * Rounding multiply add long dual accumulate high: we must keep
65
+++ b/disas/nanomips.cpp
41
- * a 72-bit internal accumulator value and return the top 64 bits.
66
@@ -XXX,XX +XXX,XX @@
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
67
*/
47
*/
68
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
69
#include "qemu/osdep.h"
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
70
-extern "C" {
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
71
#include "disas/dis-asm.h"
51
void *vm, uint64_t a) \
72
-}
52
{ \
73
53
uint16_t mask = mve_element_mask(env); \
74
#include <cstring>
54
unsigned e; \
75
#include <stdexcept>
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
82
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
87
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
76
--
98
--
77
2.20.1
99
2.20.1
78
100
79
101
diff view generated by jsdifflib
1
Switch translate-neon.c.inc from being #included into translate.c
1
The function asimd_imm_const() in translate-neon.c is an
2
to being its own compilation unit.
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.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-14-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate-a32.h | 3 +++
10
target/arm/translate.h | 16 ++++++++++
10
.../arm/{translate-neon.c.inc => translate-neon.c} | 12 +++++++-----
11
target/arm/translate-neon.c | 63 -------------------------------------
11
target/arm/translate.c | 3 ---
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
12
target/arm/meson.build | 7 ++++---
13
3 files changed, 73 insertions(+), 63 deletions(-)
13
4 files changed, 14 insertions(+), 11 deletions(-)
14
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
15
14
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
17
--- a/target/arm/translate.h
19
+++ b/target/arm/translate-a32.h
18
+++ b/target/arm/translate.h
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
21
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
20
return opc | s->be_data;
22
bool disas_vfp(DisasContext *s, uint32_t insn);
21
}
23
bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
22
24
+bool disas_neon_dp(DisasContext *s, uint32_t insn);
23
+/**
25
+bool disas_neon_ls(DisasContext *s, uint32_t insn);
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
26
+bool disas_neon_shared(DisasContext *s, uint32_t insn);
25
+ *
27
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
28
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
29
void arm_gen_condlabel(DisasContext *s);
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c
29
+ *
31
similarity index 99%
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
32
rename from target/arm/translate-neon.c.inc
31
+ * callers must catch this.
33
rename to target/arm/translate-neon.c
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
34
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.c.inc
42
--- a/target/arm/translate-neon.c
36
+++ b/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
37
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
38
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
39
*/
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
40
47
41
-/*
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
42
- * This file is intended to be included from translate.c; it uses
49
-{
43
- * some macros and definitions provided by that file.
50
- /*
44
- * It might be possible to convert it to a standalone .c file eventually.
51
- * Expand the encoded constant.
45
- */
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
46
+#include "qemu/osdep.h"
53
- * We choose to not special-case this and will behave as if a
47
+#include "tcg/tcg-op.h"
54
- * valid constant encoding of 0 had been given.
48
+#include "tcg/tcg-op-gvec.h"
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
49
+#include "exec/exec-all.h"
56
- */
50
+#include "exec/gen-icount.h"
57
- switch (cmode) {
51
+#include "translate.h"
58
- case 0: case 1:
52
+#include "translate-a32.h"
59
- /* no-op */
53
60
- break;
54
static inline int plus1(DisasContext *s, int x)
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)
55
{
113
{
56
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
57
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.c
116
--- a/target/arm/translate.c
59
+++ b/target/arm/translate.c
117
+++ b/target/arm/translate.c
60
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
61
119
a64_translate_init();
62
#define ARM_CP_RW_BIT (1 << 20)
120
}
63
121
64
-/* Include the Neon decoder */
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
65
-#include "translate-neon.c.inc"
123
+{
66
-
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
67
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
68
{
181
{
69
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
70
diff --git a/target/arm/meson.build b/target/arm/meson.build
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/meson.build
73
+++ b/target/arm/meson.build
74
@@ -XXX,XX +XXX,XX @@
75
gen = [
76
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
77
- decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
78
- decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
79
- decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
80
+ decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
81
+ decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
82
+ decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
83
decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
84
decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
85
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
86
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
87
'tlb_helper.c',
88
'translate.c',
89
'translate-m-nocp.c',
90
+ 'translate-neon.c',
91
'translate-vfp.c',
92
'vec_helper.c',
93
'vfp_helper.c',
94
--
182
--
95
2.20.1
183
2.20.1
96
184
97
185
diff view generated by jsdifflib
1
The unallocated_encoding() function is the same in both
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
translate-a64.c and translate.c; make the translate.c function global
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
and drop the translate-a64.c version. To do this we need to also
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
share gen_exception_insn(), which currently exists in two slightly
4
reimplementing it all.
5
different versions for A32 and A64: merge those into a single
6
function that can work for both.
7
8
This will be useful for splitting up translate.c, which will require
9
unallocated_encoding() to no longer be file-local. It's also
10
hopefully less confusing to have only one version of the function
11
rather than two.
12
5
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210430132740.10391-3-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
16
---
9
---
17
target/arm/translate-a64.h | 2 --
10
target/arm/translate.h | 3 +-
18
target/arm/translate.h | 3 +++
11
target/arm/translate-a64.c | 86 ++++----------------------------------
19
target/arm/translate-a64.c | 15 ---------------
12
target/arm/translate.c | 17 +++++++-
20
target/arm/translate.c | 14 +++++++++-----
13
3 files changed, 24 insertions(+), 82 deletions(-)
21
4 files changed, 12 insertions(+), 22 deletions(-)
22
14
23
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.h
26
+++ b/target/arm/translate-a64.h
27
@@ -XXX,XX +XXX,XX @@
28
#ifndef TARGET_ARM_TRANSLATE_A64_H
29
#define TARGET_ARM_TRANSLATE_A64_H
30
31
-void unallocated_encoding(DisasContext *s);
32
-
33
#define unsupported_encoding(s, insn) \
34
do { \
35
qemu_log_mask(LOG_UNIMP, \
36
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
37
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
39
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
40
@@ -XXX,XX +XXX,XX @@ void arm_free_cc(DisasCompare *cmp);
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
41
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
20
* VMVN and VBIC (when cmode < 14 && op == 1).
42
void arm_gen_test_cc(int cc, TCGLabel *label);
21
*
43
MemOp pow2_align(unsigned i);
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
44
+void unallocated_encoding(DisasContext *s);
23
- * callers must catch this.
45
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
24
+ * callers must catch this; we return the 64-bit constant value defined
46
+ uint32_t syn, uint32_t target_el);
25
+ * for AArch64.
47
26
*
48
/* Return state of Alternate Half-precision flag, caller frees result */
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
49
static inline TCGv_i32 get_ahp_flag(void)
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
55
s->base.is_jmp = DISAS_NORETURN;
34
{
56
}
35
int rd = extract32(insn, 0, 5);
57
36
int cmode = extract32(insn, 12, 4);
58
-static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
37
- int cmode_3_1 = extract32(cmode, 1, 3);
59
- uint32_t syndrome, uint32_t target_el)
38
- int cmode_0 = extract32(cmode, 0, 1);
60
-{
39
int o2 = extract32(insn, 11, 1);
61
- gen_a64_set_pc_im(pc);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
62
- gen_exception(excp, syndrome, target_el);
41
bool is_neg = extract32(insn, 29, 1);
63
- s->base.is_jmp = DISAS_NORETURN;
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
64
-}
43
return;
44
}
45
46
- /* See AdvSIMDExpandImm() in ARM ARM */
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
65
-
120
-
66
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
121
- if (cmode_3_1 != 7 && is_neg) {
67
{
122
- imm = ~imm;
68
TCGv_i32 tcg_syn;
123
+ if (cmode == 15 && o2 && !is_neg) {
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
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);
70
}
130
}
71
}
131
72
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
73
-void unallocated_encoding(DisasContext *s)
74
-{
75
- /* Unallocated and reserved encodings are uncategorized */
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
77
- default_exception_el(s));
78
-}
79
-
80
static void init_tmp_a64_array(DisasContext *s)
81
{
82
#ifdef CONFIG_DEBUG_TCG
83
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
84
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/translate.c
135
--- a/target/arm/translate.c
86
+++ b/target/arm/translate.c
136
+++ b/target/arm/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
88
s->base.is_jmp = DISAS_NORETURN;
138
case 14:
89
}
139
if (op) {
90
140
/*
91
-static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
141
- * This is the only case where the top and bottom 32 bits
92
- int syn, uint32_t target_el)
142
- * of the encoded constant differ.
93
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
143
+ * This and cmode == 15 op == 1 are the only cases where
94
+ uint32_t syn, uint32_t target_el)
144
+ * the top and bottom 32 bits of the encoded constant differ.
95
{
145
*/
96
- gen_set_condexec(s);
146
uint64_t imm64 = 0;
97
- gen_set_pc_im(s, pc);
147
int n;
98
+ if (s->aarch64) {
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
99
+ gen_a64_set_pc_im(pc);
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
100
+ } else {
150
break;
101
+ gen_set_condexec(s);
151
case 15:
102
+ gen_set_pc_im(s, pc);
152
+ if (op) {
103
+ }
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
104
gen_exception(excp, syn, target_el);
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
105
s->base.is_jmp = DISAS_NORETURN;
155
+ if (imm & 0x80) {
106
}
156
+ imm64 |= 0x8000000000000000ULL;
107
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
157
+ }
108
s->base.is_jmp = DISAS_NORETURN;
158
+ if (imm & 0x40) {
109
}
159
+ imm64 |= 0x3fc0000000000000ULL;
110
160
+ } else {
111
-static void unallocated_encoding(DisasContext *s)
161
+ imm64 |= 0x4000000000000000ULL;
112
+void unallocated_encoding(DisasContext *s)
162
+ }
113
{
163
+ return imm64;
114
/* Unallocated and reserved encodings are uncategorized */
164
+ }
115
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
116
--
168
--
117
2.20.1
169
2.20.1
118
170
119
171
diff view generated by jsdifflib
1
The omap_mmc_reset() function resets its SD card via
1
Use dup_const() instead of bitfield_replicate() in
2
device_legacy_reset(). We know that the SD card does not have a qbus
2
disas_simd_mod_imm().
3
of its own, so the new device_cold_reset() function (which resets
3
4
both the device and its child buses) is equivalent here to
4
(We can't replace the other use of bitfield_replicate() in this file,
5
device_legacy_reset() and we can just switch to the new API.
5
in logic_imm_decode_wmask(), because that location needs to handle 2
6
and 4 bit elements, which dup_const() cannot.)
6
7
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210430222348.8514-1-peter.maydell@linaro.org
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
10
---
11
---
11
hw/sd/omap_mmc.c | 2 +-
12
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
14
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/sd/omap_mmc.c
17
--- a/target/arm/translate-a64.c
17
+++ b/hw/sd/omap_mmc.c
18
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
19
* into any bus, and we must reset it manually. When omap_mmc is
20
/* FMOV (vector, immediate) - half-precision */
20
* QOMified this must move into the QOM reset function.
21
imm = vfp_expand_imm(MO_16, abcdefgh);
21
*/
22
/* now duplicate across the lanes */
22
- device_legacy_reset(DEVICE(host->card));
23
- imm = bitfield_replicate(imm, 16);
23
+ device_cold_reset(DEVICE(host->card));
24
+ imm = dup_const(MO_16, imm);
24
}
25
} else {
25
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
26
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
27
}
27
--
28
--
28
2.20.1
29
2.20.1
29
30
30
31
diff view generated by jsdifflib
1
The MPS2 SCC device doesn't have any documentation of its properties;
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
add a "QEMU interface" format comment describing them.
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.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210504120912.23094-2-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
7
---
9
---
8
include/hw/misc/mps2-scc.h | 12 ++++++++++++
10
target/arm/helper-mve.h | 4 +++
9
1 file changed, 12 insertions(+)
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(+)
10
15
11
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/misc/mps2-scc.h
18
--- a/target/arm/helper-mve.h
14
+++ b/include/hw/misc/mps2-scc.h
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
31
+++ b/target/arm/mve.decode
15
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
16
* (at your option) any later version.
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
17
*/
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)
18
78
19
+/*
79
+/*
20
+ * This is a model of the Serial Communication Controller (SCC)
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
21
+ * block found in most MPS FPGA images.
81
+ * All these insns work at 64-bit widths.
22
+ *
23
+ * QEMU interface:
24
+ * + sysbus MMIO region 0: the register bank
25
+ * + QOM property "scc-cfg4": value of the read-only CFG4 register
26
+ * + QOM property "scc-aid": value of the read-only SCC_AID register
27
+ * + QOM property "scc-id": value of the read-only SCC_ID register
28
+ * + QOM property array "oscclk": reset values of the OSCCLK registers
29
+ * (which are accessed via the SYS_CFG channel provided by this device)
30
+ */
82
+ */
31
#ifndef MPS2_SCC_H
83
+#define DO_1OP_IMM(OP, FN) \
32
#define MPS2_SCC_H
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
33
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
94
+
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
121
}
122
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
124
+{
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
127
+
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
34
--
171
--
35
2.20.1
172
2.20.1
36
173
37
174
diff view generated by jsdifflib
1
Make the remaining functions needed by the translate-neon code
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
global.
2
and VQSHLU.
3
4
The size-and-immediate encoding here is the same as Neon, and we
5
handle it the same way neon-dp.decode does.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-13-peter.maydell@linaro.org
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
8
---
10
---
9
target/arm/translate-a32.h | 8 ++++++++
11
target/arm/helper-mve.h | 16 +++++++++++
10
target/arm/translate.c | 10 ++--------
12
target/arm/mve.decode | 23 +++++++++++++++
11
2 files changed, 10 insertions(+), 8 deletions(-)
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
12
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
15
4 files changed, 147 insertions(+)
14
index XXXXXXX..XXXXXXX 100644
16
15
--- a/target/arm/translate-a32.h
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
+++ b/target/arm/translate-a32.h
18
index XXXXXXX..XXXXXXX 100644
17
@@ -XXX,XX +XXX,XX @@ void gen_set_pc_im(DisasContext *s, target_ulong val);
19
--- a/target/arm/helper-mve.h
18
void gen_lookup_tb(DisasContext *s);
20
+++ b/target/arm/helper-mve.h
19
long vfp_reg_offset(bool dp, unsigned reg);
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
long neon_full_reg_offset(unsigned reg);
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
21
+long neon_element_offset(int reg, int element, MemOp memop);
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var);
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
23
25
+
24
static inline TCGv_i32 load_cpu_offset(int offset)
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
{
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
/* Set NZCV flags from the high 4 bits of var. */
29
+
28
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+/* Swap low and high halfwords. */
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+static inline void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
33
+
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
32
+{
177
+{
33
+ tcg_gen_rotri_i32(dest, var, 16);
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;
34
+}
206
+}
35
+
207
+
36
#endif
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
37
diff --git a/target/arm/translate.c b/target/arm/translate.c
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
38
index XXXXXXX..XXXXXXX 100644
210
+ { \
39
--- a/target/arm/translate.c
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
40
+++ b/target/arm/translate.c
212
+ gen_helper_mve_##FN##b, \
41
@@ -XXX,XX +XXX,XX @@ static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
213
+ gen_helper_mve_##FN##h, \
42
}
214
+ gen_helper_mve_##FN##w, \
43
215
+ NULL, \
44
/* Byteswap each halfword. */
216
+ }; \
45
-static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
46
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
218
+ }
47
{
219
+
48
TCGv_i32 tmp = tcg_temp_new_i32();
220
+DO_2SHIFT(VSHLI, vshli_u, false)
49
TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
50
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
51
tcg_gen_ext16s_i32(dest, var);
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
52
}
53
54
-/* Swap low and high halfwords. */
55
-static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
56
-{
57
- tcg_gen_rotri_i32(dest, var, 16);
58
-}
59
-
60
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
61
tmp = (t0 ^ t1) & 0x8000;
62
t0 &= ~0x8000;
63
@@ -XXX,XX +XXX,XX @@ long neon_full_reg_offset(unsigned reg)
64
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
65
* where 0 is the least significant end of the register.
66
*/
67
-static long neon_element_offset(int reg, int element, MemOp memop)
68
+long neon_element_offset(int reg, int element, MemOp memop)
69
{
70
int element_size = 1 << (memop & MO_SIZE);
71
int ofs = element * element_size;
72
--
224
--
73
2.20.1
225
2.20.1
74
226
75
227
diff view generated by jsdifflib
1
Some of the constant expanders defined in translate.c are generically
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
useful and will be used by the separate C files for VFP and Neon once
2
VRSHRI. As with Neon, we implement these by using helper functions
3
they are created; move the expander definitions to translate.h.
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-2-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate.h | 24 ++++++++++++++++++++++++
10
target/arm/helper-mve.h | 12 ++++++++++++
11
target/arm/translate.c | 24 ------------------------
11
target/arm/translate.h | 20 ++++++++++++++++++++
12
2 files changed, 24 insertions(+), 24 deletions(-)
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
13
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
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_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
26
+DEF_HELPER_FLAGS_4(mve_vshli_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)
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
47
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
48
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
19
extern TCGv_i64 cpu_exclusive_addr;
50
return x * 2 + 1;
20
extern TCGv_i64 cpu_exclusive_val;
51
}
21
52
22
+/*
53
+static inline int rsub_64(DisasContext *s, int x)
23
+ * Constant expanders for the decoders.
24
+ */
25
+
26
+static inline int negate(DisasContext *s, int x)
27
+{
54
+{
28
+ return -x;
55
+ return 64 - x;
29
+}
56
+}
30
+
57
+
31
+static inline int plus_2(DisasContext *s, int x)
58
+static inline int rsub_32(DisasContext *s, int x)
32
+{
59
+{
33
+ return x + 2;
60
+ return 32 - x;
34
+}
61
+}
35
+
62
+
36
+static inline int times_2(DisasContext *s, int x)
63
+static inline int rsub_16(DisasContext *s, int x)
37
+{
64
+{
38
+ return x * 2;
65
+ return 16 - x;
39
+}
66
+}
40
+
67
+
41
+static inline int times_4(DisasContext *s, int x)
68
+static inline int rsub_8(DisasContext *s, int x)
42
+{
69
+{
43
+ return x * 4;
70
+ return 8 - x;
44
+}
71
+}
45
+
72
+
46
static inline int arm_dc_feature(DisasContext *dc, int feature)
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
47
{
74
{
48
return (dc->features & (1ULL << feature)) != 0;
75
return (dc->features & (1ULL << feature)) != 0;
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
50
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
78
--- a/target/arm/mve.decode
52
+++ b/target/arm/translate.c
79
+++ b/target/arm/mve.decode
53
@@ -XXX,XX +XXX,XX @@ static void arm_gen_condlabel(DisasContext *s)
80
@@ -XXX,XX +XXX,XX @@
54
}
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
88
+
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
90
+ size=0 shift=%rshift_i3
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
92
+ size=1 shift=%rshift_i4
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
94
+ size=2 shift=%rshift_i5
95
+
96
# Vector loads and stores
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
55
}
163
}
56
164
57
-/*
165
-static inline int rsub_64(DisasContext *s, int x)
58
- * Constant expanders for the decoders.
59
- */
60
-
61
-static int negate(DisasContext *s, int x)
62
-{
166
-{
63
- return -x;
167
- return 64 - x;
64
-}
168
-}
65
-
169
-
66
-static int plus_2(DisasContext *s, int x)
170
-static inline int rsub_32(DisasContext *s, int x)
67
-{
171
-{
68
- return x + 2;
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
69
-}
181
-}
70
-
182
-
71
-static int times_2(DisasContext *s, int x)
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
72
-{
184
{
73
- return x * 2;
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
74
-}
75
-
76
-static int times_4(DisasContext *s, int x)
77
-{
78
- return x * 4;
79
-}
80
-
81
/* Flags for the disas_set_da_iss info argument:
82
* lower bits hold the Rt register number, higher bits are flags.
83
*/
84
--
186
--
85
2.20.1
187
2.20.1
86
188
87
189
diff view generated by jsdifflib
1
Move the various gen_aa32* functions and macros out of translate.c
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
and into translate-a32.h.
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-6-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate-a32.h | 53 ++++++++++++++++++++++++++++++++++++++
10
target/arm/helper-mve.h | 9 +++++++
10
target/arm/translate.c | 51 ++++++++++++------------------------
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
11
2 files changed, 69 insertions(+), 35 deletions(-)
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
12
15
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
18
--- a/target/arm/helper-mve.h
16
+++ b/target/arm/translate-a32.h
19
+++ b/target/arm/helper-mve.h
17
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
18
return tmp;
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
}
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
22
+ TCGv_i32 a32, int index, MemOp opc);
23
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
24
+ TCGv_i32 a32, int index, MemOp opc);
25
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
26
+ TCGv_i32 a32, int index, MemOp opc);
27
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
28
+ TCGv_i32 a32, int index, MemOp opc);
29
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
30
+ int index, MemOp opc);
31
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
32
+ int index, MemOp opc);
33
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
34
+ int index, MemOp opc);
35
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
36
+ int index, MemOp opc);
37
+
24
+
38
+#define DO_GEN_LD(SUFF, OPC) \
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+ TCGv_i32 a32, int index) \
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
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
60
+{
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
67
+}
68
+
69
+{
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
72
+
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
74
+}
75
+
76
+{
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
81
+}
82
+
83
+{
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
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
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
41
+ { \
128
+ { \
42
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
43
+ }
139
+ }
44
+
140
+
45
+#define DO_GEN_ST(SUFF, OPC) \
141
+#define DO_VSHLL_ALL(OP, TOP) \
46
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
47
+ TCGv_i32 a32, int index) \
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
48
+ { \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
49
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
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); \
50
+ }
166
+ }
51
+
167
+
52
+static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
168
+DO_VSHLL(VSHLL_BS, vshllbs)
53
+ TCGv_i32 a32, int index)
169
+DO_VSHLL(VSHLL_BU, vshllbu)
54
+{
170
+DO_VSHLL(VSHLL_TS, vshllts)
55
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
171
+DO_VSHLL(VSHLL_TU, vshlltu)
56
+}
57
+
58
+static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
59
+ TCGv_i32 a32, int index)
60
+{
61
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
62
+}
63
+
64
+DO_GEN_LD(8u, MO_UB)
65
+DO_GEN_LD(16u, MO_UW)
66
+DO_GEN_LD(32u, MO_UL)
67
+DO_GEN_ST(8, MO_UB)
68
+DO_GEN_ST(16, MO_UW)
69
+DO_GEN_ST(32, MO_UL)
70
+
71
+#undef DO_GEN_LD
72
+#undef DO_GEN_ST
73
+
74
#endif
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
80
* Internal routines are used for NEON cases where the endianness
81
* and/or alignment has already been taken into account and manipulated.
82
*/
83
-static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
84
- TCGv_i32 a32, int index, MemOp opc)
85
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
86
+ TCGv_i32 a32, int index, MemOp opc)
87
{
88
TCGv addr = gen_aa32_addr(s, a32, opc);
89
tcg_gen_qemu_ld_i32(val, addr, index, opc);
90
tcg_temp_free(addr);
91
}
92
93
-static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
94
- TCGv_i32 a32, int index, MemOp opc)
95
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
96
+ TCGv_i32 a32, int index, MemOp opc)
97
{
98
TCGv addr = gen_aa32_addr(s, a32, opc);
99
tcg_gen_qemu_st_i32(val, addr, index, opc);
100
tcg_temp_free(addr);
101
}
102
103
-static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
104
- TCGv_i32 a32, int index, MemOp opc)
105
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
106
+ TCGv_i32 a32, int index, MemOp opc)
107
{
108
TCGv addr = gen_aa32_addr(s, a32, opc);
109
110
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
111
tcg_temp_free(addr);
112
}
113
114
-static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
115
- TCGv_i32 a32, int index, MemOp opc)
116
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
117
+ TCGv_i32 a32, int index, MemOp opc)
118
{
119
TCGv addr = gen_aa32_addr(s, a32, opc);
120
121
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
122
tcg_temp_free(addr);
123
}
124
125
-static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
126
- int index, MemOp opc)
127
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
128
+ int index, MemOp opc)
129
{
130
gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
131
}
132
133
-static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
134
- int index, MemOp opc)
135
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
136
+ int index, MemOp opc)
137
{
138
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
139
}
140
141
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
142
- int index, MemOp opc)
143
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
144
+ int index, MemOp opc)
145
{
146
gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
147
}
148
149
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
150
- int index, MemOp opc)
151
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
152
+ int index, MemOp opc)
153
{
154
gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
155
}
156
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
157
gen_aa32_st_i32(s, val, a32, index, OPC); \
158
}
159
160
-static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
161
- TCGv_i32 a32, int index)
162
-{
163
- gen_aa32_ld_i64(s, val, a32, index, MO_Q);
164
-}
165
-
166
-static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
167
- TCGv_i32 a32, int index)
168
-{
169
- gen_aa32_st_i64(s, val, a32, index, MO_Q);
170
-}
171
-
172
-DO_GEN_LD(8u, MO_UB)
173
-DO_GEN_LD(16u, MO_UW)
174
-DO_GEN_LD(32u, MO_UL)
175
-DO_GEN_ST(8, MO_UB)
176
-DO_GEN_ST(16, MO_UW)
177
-DO_GEN_ST(32, MO_UL)
178
-
179
static inline void gen_hvc(DisasContext *s, int imm16)
180
{
181
/* The pre HVC helper handles cases when HVC gets trapped
182
--
172
--
183
2.20.1
173
2.20.1
184
174
185
175
diff view generated by jsdifflib
1
Make bswap.h handle being included outside an 'extern "C"' block:
1
Implement the MVE VSRI and VSLI insns, which perform a
2
all system headers are included first, then all declarations are
2
shift-and-insert operation.
3
put inside an 'extern "C"' block.
4
5
This requires a little rearrangement as currently we have an ifdef
6
ladder that has some system includes and some local declarations
7
or definitions, and we need to separate those out.
8
9
We want to do this because dis-asm.h includes bswap.h, dis-asm.h
10
may need to be included from C++ files, and system headers should
11
not be included within 'extern "C"' blocks.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
15
---
7
---
16
include/qemu/bswap.h | 26 ++++++++++++++++++++++----
8
target/arm/helper-mve.h | 8 ++++++++
17
1 file changed, 22 insertions(+), 4 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(+)
18
13
19
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qemu/bswap.h
16
--- a/target/arm/helper-mve.h
22
+++ b/include/qemu/bswap.h
17
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
#ifndef BSWAP_H
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
#define BSWAP_H
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
-#include "fpu/softfloat-types.h"
28
-
29
#ifdef CONFIG_MACHINE_BSWAP_H
30
# include <sys/endian.h>
31
# include <machine/bswap.h>
32
@@ -XXX,XX +XXX,XX @@
33
# include <endian.h>
34
#elif defined(CONFIG_BYTESWAP_H)
35
# include <byteswap.h>
36
+#define BSWAP_FROM_BYTESWAP
37
+# else
38
+#define BSWAP_FROM_FALLBACKS
39
+#endif /* ! CONFIG_MACHINE_BSWAP_H */
40
41
+#ifdef __cplusplus
42
+extern "C" {
43
+#endif
44
+
22
+
45
+#include "fpu/softfloat-types.h"
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+
26
+
47
+#ifdef BSWAP_FROM_BYTESWAP
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
static inline uint16_t bswap16(uint16_t x)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
{
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
return bswap_16(x);
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
31
index XXXXXXX..XXXXXXX 100644
52
{
32
--- a/target/arm/mve.decode
53
return bswap_64(x);
33
+++ b/target/arm/mve.decode
54
}
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
55
-# else
35
56
+#endif
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
57
+
38
+
58
+#ifdef BSWAP_FROM_FALLBACKS
39
+# Shift-and-insert
59
static inline uint16_t bswap16(uint16_t x)
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
60
{
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
61
return (((x & 0x00ff) << 8) |
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
62
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
63
((x & 0x00ff000000000000ULL) >> 40) |
64
((x & 0xff00000000000000ULL) >> 56));
65
}
66
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
67
+#endif
68
+
43
+
69
+#undef BSWAP_FROM_BYTESWAP
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
70
+#undef BSWAP_FROM_FALLBACKS
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
71
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
72
static inline void bswap16s(uint16_t *s)
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
73
{
48
index XXXXXXX..XXXXXXX 100644
74
@@ -XXX,XX +XXX,XX @@ DO_STN_LDN_P(be)
49
--- a/target/arm/mve_helper.c
75
#undef le_bswaps
50
+++ b/target/arm/mve_helper.c
76
#undef be_bswaps
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
77
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
78
+#ifdef __cplusplus
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
79
+}
54
80
+#endif
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
+ }
81
+
84
+
82
#endif /* BSWAP_H */
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
83
--
114
--
84
2.20.1
115
2.20.1
85
116
86
117
diff view generated by jsdifflib
1
The AN524 FPGA image supports two memory maps, which differ in where
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
the QSPI and BRAM are. In the default map, the BRAM is at
3
0x0000_0000, and the QSPI at 0x2800_0000. In the second map, they
4
are the other way around.
5
2
6
In hardware, the initial mapping can be selected by the user by
3
do_urshr() is borrowed from sve_helper.c.
7
writing either "REMAP: BRAM" (the default) or "REMAP: QSPI" in the
8
board configuration file. The board config file is acted on by the
9
"Motherboard Configuration Controller", which is an entirely separate
10
microcontroller on the dev board but outside the FPGA.
11
12
The guest can also dynamically change the mapping via the SCC
13
CFG_REG0 register.
14
15
Implement this functionality for QEMU, using a machine property
16
"remap" with valid values "BRAM" and "QSPI" to allow the user to set
17
the initial mapping, in the same way they can on the FPGA, and
18
wiring up the bit from the SCC register to also switch the mapping.
19
4
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
23
Message-id: 20210504120912.23094-4-peter.maydell@linaro.org
24
---
8
---
25
docs/system/arm/mps2.rst | 10 ++++
9
target/arm/helper-mve.h | 10 ++++++++++
26
hw/arm/mps2-tz.c | 108 ++++++++++++++++++++++++++++++++++++++-
10
target/arm/mve.decode | 11 +++++++++++
27
2 files changed, 117 insertions(+), 1 deletion(-)
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
28
14
29
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/mps2.rst
17
--- a/target/arm/helper-mve.h
32
+++ b/docs/system/arm/mps2.rst
18
+++ b/target/arm/helper-mve.h
33
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
flash, but only as simple ROM, so attempting to rewrite the flash
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
from the guest will fail
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
- QEMU does not model the USB controller in MPS3 boards
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
23
+
38
+Machine-specific options
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+""""""""""""""""""""""""
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+
28
+
41
+The following machine-specific options are supported:
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
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
42
+
41
+
43
+remap
42
+# Narrowing shifts (which only support b and h sizes)
44
+ Supported for ``mps3-an524`` only.
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
45
+ Set ``BRAM``/``QSPI`` to select the initial memory mapping. The
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
46
+ default is ``BRAM``.
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
47
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
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
48
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/mps2-tz.c
54
--- a/target/arm/mve_helper.c
50
+++ b/hw/arm/mps2-tz.c
55
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
52
#include "hw/boards.h"
57
53
#include "exec/address-spaces.h"
58
DO_VSHLL_ALL(vshllb, false)
54
#include "sysemu/sysemu.h"
59
DO_VSHLL_ALL(vshllt, true)
55
+#include "sysemu/reset.h"
56
#include "hw/misc/unimp.h"
57
#include "hw/char/cmsdk-apb-uart.h"
58
#include "hw/timer/cmsdk-apb-timer.h"
59
@@ -XXX,XX +XXX,XX @@
60
#include "hw/core/split-irq.h"
61
#include "hw/qdev-clock.h"
62
#include "qom/object.h"
63
+#include "hw/irq.h"
64
65
#define MPS2TZ_NUMIRQ_MAX 96
66
#define MPS2TZ_RAM_MAX 5
67
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
68
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
69
Clock *sysclk;
70
Clock *s32kclk;
71
+
60
+
72
+ bool remap;
73
+ qemu_irq remap_irq;
74
};
75
76
#define TYPE_MPS2TZ_MACHINE "mps2tz"
77
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
78
},
79
};
80
81
+/*
61
+/*
82
+ * Note that the addresses and MPC numbering here should match up
62
+ * Narrowing right shifts, taking a double sized input, shifting it
83
+ * with those used in remap_memory(), which can swap the BRAM and QSPI.
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.
84
+ */
65
+ */
85
static const RAMInfo an524_raminfo[] = { {
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
86
.name = "bram",
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
87
.base = 0x00000000,
68
+ void *vm, uint32_t shift) \
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
69
+ { \
89
70
+ LTYPE *m = vm; \
90
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
71
+ TYPE *d = vd; \
91
sccdev = DEVICE(scc);
72
+ uint16_t mask = mve_element_mask(env); \
92
+ qdev_prop_set_uint32(sccdev, "scc-cfg0", mms->remap ? 1 : 0);
73
+ unsigned le; \
93
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
94
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
95
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
96
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
77
+ } \
97
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
78
+ mve_advance_vpt(env); \
98
}
99
100
+static hwaddr boot_mem_base(MPS2TZMachineState *mms)
101
+{
102
+ /*
103
+ * Return the canonical address of the block which will be mapped
104
+ * at address 0x0 (i.e. where the vector table is).
105
+ * This is usually 0, but if the AN524 alternate memory map is
106
+ * enabled it will be the base address of the QSPI block.
107
+ */
108
+ return mms->remap ? 0x28000000 : 0;
109
+}
110
+
111
+static void remap_memory(MPS2TZMachineState *mms, int map)
112
+{
113
+ /*
114
+ * Remap the memory for the AN524. 'map' is the value of
115
+ * SCC CFG_REG0 bit 0, i.e. 0 for the default map and 1
116
+ * for the "option 1" mapping where QSPI is at address 0.
117
+ *
118
+ * Effectively we need to swap around the "upstream" ends of
119
+ * MPC 0 and MPC 1.
120
+ */
121
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
122
+ int i;
123
+
124
+ if (mmc->fpga_type != FPGA_AN524) {
125
+ return;
126
+ }
79
+ }
127
+
80
+
128
+ memory_region_transaction_begin();
81
+#define DO_VSHRN_ALL(OP, FN) \
129
+ for (i = 0; i < 2; i++) {
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
130
+ TZMPC *mpc = &mms->mpc[i];
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
131
+ MemoryRegion *upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
132
+ hwaddr addr = (i ^ map) ? 0x28000000 : 0;
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
133
+
86
+
134
+ memory_region_set_address(upstream, addr);
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
135
+ }
136
+ memory_region_transaction_commit();
137
+}
138
+
139
+static void remap_irq_fn(void *opaque, int n, int level)
140
+{
88
+{
141
+ MPS2TZMachineState *mms = opaque;
89
+ if (likely(sh < 64)) {
142
+
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
143
+ remap_memory(mms, level);
91
+ } else if (sh == 64) {
144
+}
92
+ return x >> 63;
145
+
146
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
147
const char *name, hwaddr size,
148
const int *irqs)
149
@@ -XXX,XX +XXX,XX @@ static uint32_t boot_ram_size(MPS2TZMachineState *mms)
150
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
151
152
for (p = mmc->raminfo; p->name; p++) {
153
- if (p->base == 0) {
154
+ if (p->base == boot_mem_base(mms)) {
155
return p->size;
156
}
157
}
158
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
159
160
create_non_mpc_ram(mms);
161
162
+ if (mmc->fpga_type == FPGA_AN524) {
163
+ /*
164
+ * Connect the line from the SCC so that we can remap when the
165
+ * guest updates that register.
166
+ */
167
+ mms->remap_irq = qemu_allocate_irq(remap_irq_fn, mms, 0);
168
+ qdev_connect_gpio_out_named(DEVICE(&mms->scc), "remap", 0,
169
+ mms->remap_irq);
170
+ }
171
+
172
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
173
boot_ram_size(mms));
174
}
175
@@ -XXX,XX +XXX,XX @@ static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
176
*iregion = region;
177
}
178
179
+static char *mps2_get_remap(Object *obj, Error **errp)
180
+{
181
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
182
+ const char *val = mms->remap ? "QSPI" : "BRAM";
183
+ return g_strdup(val);
184
+}
185
+
186
+static void mps2_set_remap(Object *obj, const char *value, Error **errp)
187
+{
188
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
189
+
190
+ if (!strcmp(value, "BRAM")) {
191
+ mms->remap = false;
192
+ } else if (!strcmp(value, "QSPI")) {
193
+ mms->remap = true;
194
+ } else {
93
+ } else {
195
+ error_setg(errp, "Invalid remap value");
94
+ return 0;
196
+ error_append_hint(errp, "Valid values are BRAM and QSPI.\n");
197
+ }
95
+ }
198
+}
96
+}
199
+
97
+
200
+static void mps2_machine_reset(MachineState *machine)
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
201
+{
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
202
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
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_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
203
+
108
+
204
+ /*
109
+#define DO_2SHIFT_N(INSN, FN) \
205
+ * Set the initial memory mapping before triggering the reset of
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
206
+ * the rest of the system, so that the guest image loader and CPU
111
+ { \
207
+ * reset see the correct mapping.
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
208
+ */
113
+ gen_helper_mve_##FN##b, \
209
+ remap_memory(mms, mms->remap);
114
+ gen_helper_mve_##FN##h, \
210
+ qemu_devices_reset();
115
+ }; \
211
+}
116
+ return do_2shift(s, a, fns[a->size], false); \
117
+ }
212
+
118
+
213
static void mps2tz_class_init(ObjectClass *oc, void *data)
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
214
{
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
215
MachineClass *mc = MACHINE_CLASS(oc);
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
216
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
217
218
mc->init = mps2tz_common_init;
219
+ mc->reset = mps2_machine_reset;
220
iic->check = mps2_tz_idau_check;
221
}
222
223
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
224
mmc->raminfo = an524_raminfo;
225
mmc->armsse_type = TYPE_SSE200;
226
mps2tz_set_default_ram_info(mmc);
227
+
228
+ object_class_property_add_str(oc, "remap", mps2_get_remap, mps2_set_remap);
229
+ object_class_property_set_description(oc, "remap",
230
+ "Set memory mapping. Valid values "
231
+ "are BRAM (default) and QSPI.");
232
}
233
234
static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
235
--
123
--
236
2.20.1
124
2.20.1
237
125
238
126
diff view generated by jsdifflib
1
The function vfp_reg_ptr() is used only in translate-neon.c.inc;
1
Implement the MVE saturating shift-right-and-narrow insns
2
move it there.
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
4
do_srshr() is borrowed from sve_helper.c.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-10-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate.c | 7 -------
10
target/arm/helper-mve.h | 30 +++++++++++
10
target/arm/translate-neon.c.inc | 7 +++++++
11
target/arm/mve.decode | 28 ++++++++++
11
2 files changed, 7 insertions(+), 7 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
12
13
target/arm/translate-mve.c | 12 +++++
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
4 files changed, 174 insertions(+)
14
index XXXXXXX..XXXXXXX 100644
15
15
--- a/target/arm/translate.c
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
+++ b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
17
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
18
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
57
+++ b/target/arm/mve.decode
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
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)
18
}
95
}
19
}
96
}
20
97
21
-static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
22
-{
23
- TCGv_ptr ret = tcg_temp_new_ptr();
24
- tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
25
- return ret;
26
-}
27
-
28
#define ARM_CP_RW_BIT (1 << 20)
29
30
/* Include the Neon decoder */
31
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-neon.c.inc
34
+++ b/target/arm/translate-neon.c.inc
35
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
36
#include "decode-neon-ls.c.inc"
37
#include "decode-neon-shared.c.inc"
38
39
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
40
+{
99
+{
41
+ TCGv_ptr ret = tcg_temp_new_ptr();
100
+ if (likely(sh < 64)) {
42
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
43
+ return ret;
102
+ } else {
103
+ /* Rounding the sign bit always produces 0. */
104
+ return 0;
105
+ }
44
+}
106
+}
45
+
107
+
46
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
108
DO_VSHRN_ALL(vshrn, DO_SHR)
47
{
109
DO_VSHRN_ALL(vrshrn, do_urshr)
48
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
113
+{
114
+ if (val > max) {
115
+ *satp = true;
116
+ return max;
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
122
+ }
123
+}
124
+
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)
49
--
224
--
50
2.20.1
225
2.20.1
51
226
52
227
diff view generated by jsdifflib
1
Both os-win32.h and os-posix.h include system header files. Instead
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
of having osdep.h include them inside its 'extern "C"' block, make
2
entire vector with carry in bits provided from a general purpose
3
these headers handle that themselves, so that we don't include the
3
register and carry out bits written back to that register.
4
system headers inside 'extern "C"'.
5
6
This doesn't fix any current problems, but it's conceptually the
7
right way to handle system headers.
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
11
---
8
---
12
include/qemu/osdep.h | 8 ++++----
9
target/arm/helper-mve.h | 2 ++
13
include/sysemu/os-posix.h | 8 ++++++++
10
target/arm/mve.decode | 2 ++
14
include/sysemu/os-win32.h | 8 ++++++++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
15
3 files changed, 20 insertions(+), 4 deletions(-)
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
16
14
17
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/osdep.h
17
--- a/target/arm/helper-mve.h
20
+++ b/include/qemu/osdep.h
18
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ QEMU_EXTERN_C int daemon(int, int);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
*/
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
#include "glib-compat.h"
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
-#ifdef __cplusplus
26
-extern "C" {
27
-#endif
28
-
29
#ifdef _WIN32
30
#include "sysemu/os-win32.h"
31
#endif
32
@@ -XXX,XX +XXX,XX @@ extern "C" {
33
#include "sysemu/os-posix.h"
34
#endif
35
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
23
+
40
#include "qemu/typedefs.h"
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
41
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
/*
43
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
44
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
45
--- a/include/sysemu/os-posix.h
27
--- a/target/arm/mve.decode
46
+++ b/include/sysemu/os-posix.h
28
+++ b/target/arm/mve.decode
47
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
48
#include <sys/sysmacros.h>
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
49
#endif
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
50
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
51
+#ifdef __cplusplus
52
+extern "C" {
53
+#endif
54
+
33
+
55
void os_set_line_buffering(void);
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
56
void os_set_proc_name(const char *s);
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
57
void os_setup_signal_handling(void);
36
index XXXXXXX..XXXXXXX 100644
58
@@ -XXX,XX +XXX,XX @@ static inline void qemu_funlockfile(FILE *f)
37
--- a/target/arm/mve_helper.c
59
funlockfile(f);
38
+++ b/target/arm/mve_helper.c
60
}
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
61
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
62
+#ifdef __cplusplus
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;
63
+}
80
+}
64
+#endif
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)
65
+
89
+
66
#endif
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
67
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
91
+{
68
index XXXXXXX..XXXXXXX 100644
92
+ /*
69
--- a/include/sysemu/os-win32.h
93
+ * Whole Vector Left Shift with Carry. The carry is taken
70
+++ b/include/sysemu/os-win32.h
94
+ * from a general purpose register and written back there.
71
@@ -XXX,XX +XXX,XX @@
95
+ * An imm of 0 means "shift by 32".
72
#include <windows.h>
96
+ */
73
#include <ws2tcpip.h>
97
+ TCGv_ptr qd;
74
98
+ TCGv_i32 rdm;
75
+#ifdef __cplusplus
76
+extern "C" {
77
+#endif
78
+
99
+
79
#if defined(_WIN64)
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
80
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
101
+ return false;
81
* If this parameter is NULL, longjump does no stack unwinding.
102
+ }
82
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
103
+ if (a->rdm == 13 || a->rdm == 15) {
83
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
84
struct sockaddr *addr, socklen_t *addrlen);
105
+ return false;
85
106
+ }
86
+#ifdef __cplusplus
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
109
+ }
110
+
111
+ qd = mve_qreg_ptr(a->qd);
112
+ rdm = load_reg(s, a->rdm);
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
114
+ store_reg(s, a->rdm, rdm);
115
+ tcg_temp_free_ptr(qd);
116
+ mve_update_eci(s);
117
+ return true;
87
+}
118
+}
88
+#endif
89
+
90
#endif
91
--
119
--
92
2.20.1
120
2.20.1
93
121
94
122
diff view generated by jsdifflib
1
Currently the trans functions for m-nocp.decode all live in
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
translate-vfp.inc.c; move them out into their own translation unit,
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
translate-m-nocp.c.
3
stored in a pair of general-purpose registers.
4
5
The trans_* functions here are pure code motion with no changes.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210430132740.10391-5-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
10
---
8
---
11
target/arm/translate-a32.h | 3 +
9
target/arm/helper-mve.h | 3 ++
12
target/arm/translate-m-nocp.c | 221 +++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 6 +++-
13
target/arm/translate.c | 1 -
11
target/arm/mve_helper.c | 19 ++++++++++++
14
target/arm/translate-vfp.c.inc | 196 -----------------------------
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
15
target/arm/meson.build | 3 +-
13
4 files changed, 90 insertions(+), 1 deletion(-)
16
5 files changed, 226 insertions(+), 198 deletions(-)
17
create mode 100644 target/arm/translate-m-nocp.c
18
14
19
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a32.h
17
--- a/target/arm/helper-mve.h
22
+++ b/target/arm/translate-a32.h
18
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
#ifndef TARGET_ARM_TRANSLATE_A64_H
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
25
#define TARGET_ARM_TRANSLATE_A64_H
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
22
27
+/* Prototypes for autogenerated disassembler functions */
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
28
+bool disas_m_nocp(DisasContext *dc, uint32_t insn);
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
29
+
25
+
30
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
31
void arm_gen_condlabel(DisasContext *s);
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
32
bool vfp_access_check(DisasContext *s);
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
33
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
new file mode 100644
30
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX
31
--- a/target/arm/mve.decode
36
--- /dev/null
32
+++ b/target/arm/mve.decode
37
+++ b/target/arm/translate-m-nocp.c
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
38
@@ -XXX,XX +XXX,XX @@
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
39
+/*
35
40
+ * ARM translation: M-profile NOCP special-case instructions
36
# Vector add across vector
41
+ *
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
42
+ * Copyright (c) 2020 Linaro, Ltd.
38
+{
43
+ *
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
44
+ * This library is free software; you can redistribute it and/or
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
45
+ * modify it under the terms of the GNU Lesser General Public
41
+ rdahi=%rdahi rdalo=%rdalo
46
+ * License as published by the Free Software Foundation; either
42
+}
47
+ * version 2.1 of the License, or (at your option) any later version.
43
48
+ *
44
# Predicate operations
49
+ * This library is distributed in the hope that it will be useful,
45
%mask_22_13 22:1 13:3
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47
index XXXXXXX..XXXXXXX 100644
52
+ * Lesser General Public License for more details.
48
--- a/target/arm/mve_helper.c
53
+ *
49
+++ b/target/arm/mve_helper.c
54
+ * You should have received a copy of the GNU Lesser General Public
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
55
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
51
DO_VADDV(vaddvuh, 2, uint16_t)
56
+ */
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
57
+
69
+
58
+#include "qemu/osdep.h"
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
59
+#include "tcg/tcg-op.h"
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
60
+#include "translate.h"
61
+#include "translate-a32.h"
62
+
72
+
63
+#include "decode-m-nocp.c.inc"
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
82
}
83
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
85
+{
86
+ /*
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
88
+ * elements of the vector into a 64-bit result stored in
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
64
+
95
+
65
+/*
96
+ if (!dc_isar_feature(aa32_mve, s)) {
66
+ * Decode VLLDM and VLSTM are nonstandard because:
67
+ * * if there is no FPU then these insns must NOP in
68
+ * Secure state and UNDEF in Nonsecure state
69
+ * * if there is an FPU then these insns do not have
70
+ * the usual behaviour that vfp_access_check() provides of
71
+ * being controlled by CPACR/NSACR enable bits or the
72
+ * lazy-stacking logic.
73
+ */
74
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
75
+{
76
+ TCGv_i32 fptr;
77
+
78
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
79
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
80
+ return false;
97
+ return false;
81
+ }
98
+ }
82
+
83
+ if (a->op) {
84
+ /*
85
+ * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
86
+ * to take the IMPDEF option to make memory accesses to the stack
87
+ * slots that correspond to the D16-D31 registers (discarding
88
+ * read data and writing UNKNOWN values), so for us the T2
89
+ * encoding behaves identically to the T1 encoding.
90
+ */
91
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
92
+ return false;
93
+ }
94
+ } else {
95
+ /*
96
+ * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
97
+ * This is currently architecturally impossible, but we add the
98
+ * check to stay in line with the pseudocode. Note that we must
99
+ * emit code for the UNDEF so it takes precedence over the NOCP.
100
+ */
101
+ if (dc_isar_feature(aa32_simd_r32, s)) {
102
+ unallocated_encoding(s);
103
+ return true;
104
+ }
105
+ }
106
+
107
+ /*
99
+ /*
108
+ * If not secure, UNDEF. We must emit code for this
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
109
+ * rather than returning false so that this takes
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
110
+ * precedence over the m-nocp.decode NOCP fallback.
111
+ */
102
+ */
112
+ if (!s->v8m_secure) {
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
113
+ unallocated_encoding(s);
114
+ return true;
115
+ }
116
+ /* If no fpu, NOP. */
117
+ if (!dc_isar_feature(aa32_vfp, s)) {
118
+ return true;
119
+ }
120
+
121
+ fptr = load_reg(s, a->rn);
122
+ if (a->l) {
123
+ gen_helper_v7m_vlldm(cpu_env, fptr);
124
+ } else {
125
+ gen_helper_v7m_vlstm(cpu_env, fptr);
126
+ }
127
+ tcg_temp_free_i32(fptr);
128
+
129
+ /* End the TB, because we have updated FP control bits */
130
+ s->base.is_jmp = DISAS_UPDATE_EXIT;
131
+ return true;
132
+}
133
+
134
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
135
+{
136
+ int btmreg, topreg;
137
+ TCGv_i64 zero;
138
+ TCGv_i32 aspen, sfpa;
139
+
140
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
141
+ /* Before v8.1M, fall through in decode to NOCP check */
142
+ return false;
104
+ return false;
143
+ }
105
+ }
144
+
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
145
+ /* Explicitly UNDEF because this takes precedence over NOCP */
146
+ if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
147
+ unallocated_encoding(s);
148
+ return true;
149
+ }
150
+
151
+ if (!dc_isar_feature(aa32_vfp_simd, s)) {
152
+ /* NOP if we have neither FP nor MVE */
153
+ return true;
107
+ return true;
154
+ }
108
+ }
155
+
109
+
156
+ /*
110
+ /*
157
+ * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
111
+ * This insn is subject to beat-wise execution. Partial execution
158
+ * active floating point context so we must NOP (without doing
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
159
+ * any lazy state preservation or the NOCP check).
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
160
+ */
114
+ */
161
+ aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
115
+ if (a->a || mve_skip_first_beat(s)) {
162
+ sfpa = load_cpu_field(v7m.control[M_REG_S]);
116
+ /* Accumulate input from RdaHi:RdaLo */
163
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
117
+ rda = tcg_temp_new_i64();
164
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
118
+ rdalo = load_reg(s, a->rdalo);
165
+ tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
119
+ rdahi = load_reg(s, a->rdahi);
166
+ tcg_gen_or_i32(sfpa, sfpa, aspen);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
167
+ arm_gen_condlabel(s);
121
+ tcg_temp_free_i32(rdalo);
168
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
122
+ tcg_temp_free_i32(rdahi);
169
+
123
+ } else {
170
+ if (s->fp_excp_el != 0) {
124
+ /* Accumulate starting at zero */
171
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
125
+ rda = tcg_const_i64(0);
172
+ syn_uncategorized(), s->fp_excp_el);
173
+ return true;
174
+ }
126
+ }
175
+
127
+
176
+ topreg = a->vd + a->imm - 1;
128
+ qm = mve_qreg_ptr(a->qm);
177
+ btmreg = a->vd;
129
+ if (a->u) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
178
+
135
+
179
+ /* Convert to Sreg numbers if the insn specified in Dregs */
136
+ rdalo = tcg_temp_new_i32();
180
+ if (a->size == 3) {
137
+ rdahi = tcg_temp_new_i32();
181
+ topreg = topreg * 2 + 1;
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
182
+ btmreg *= 2;
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
183
+ }
140
+ store_reg(s, a->rdalo, rdalo);
184
+
141
+ store_reg(s, a->rdahi, rdahi);
185
+ if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
142
+ tcg_temp_free_i64(rda);
186
+ /* UNPREDICTABLE: we choose to undef */
143
+ mve_update_eci(s);
187
+ unallocated_encoding(s);
188
+ return true;
189
+ }
190
+
191
+ /* Silently ignore requests to clear D16-D31 if they don't exist */
192
+ if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
193
+ topreg = 31;
194
+ }
195
+
196
+ if (!vfp_access_check(s)) {
197
+ return true;
198
+ }
199
+
200
+ /* Zero the Sregs from btmreg to topreg inclusive. */
201
+ zero = tcg_const_i64(0);
202
+ if (btmreg & 1) {
203
+ write_neon_element64(zero, btmreg >> 1, 1, MO_32);
204
+ btmreg++;
205
+ }
206
+ for (; btmreg + 1 <= topreg; btmreg += 2) {
207
+ write_neon_element64(zero, btmreg >> 1, 0, MO_64);
208
+ }
209
+ if (btmreg == topreg) {
210
+ write_neon_element64(zero, btmreg >> 1, 0, MO_32);
211
+ btmreg++;
212
+ }
213
+ assert(btmreg == topreg + 1);
214
+ /* TODO: when MVE is implemented, zero VPR here */
215
+ return true;
144
+ return true;
216
+}
145
+}
217
+
146
+
218
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
219
+{
220
+ /*
221
+ * Handle M-profile early check for disabled coprocessor:
222
+ * all we need to do here is emit the NOCP exception if
223
+ * the coprocessor is disabled. Otherwise we return false
224
+ * and the real VFP/etc decode will handle the insn.
225
+ */
226
+ assert(arm_dc_feature(s, ARM_FEATURE_M));
227
+
228
+ if (a->cp == 11) {
229
+ a->cp = 10;
230
+ }
231
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
232
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
233
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
234
+ a->cp = 10;
235
+ }
236
+
237
+ if (a->cp != 10) {
238
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
239
+ syn_uncategorized(), default_exception_el(s));
240
+ return true;
241
+ }
242
+
243
+ if (s->fp_excp_el != 0) {
244
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
245
+ syn_uncategorized(), s->fp_excp_el);
246
+ return true;
247
+ }
248
+
249
+ return false;
250
+}
251
+
252
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
253
+{
254
+ /* This range needs a coprocessor check for v8.1M and later only */
255
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
256
+ return false;
257
+ }
258
+ return trans_NOCP(s, a);
259
+}
260
diff --git a/target/arm/translate.c b/target/arm/translate.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/target/arm/translate.c
263
+++ b/target/arm/translate.c
264
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
265
#define ARM_CP_RW_BIT (1 << 20)
266
267
/* Include the VFP and Neon decoders */
268
-#include "decode-m-nocp.c.inc"
269
#include "translate-vfp.c.inc"
270
#include "translate-neon.c.inc"
271
272
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
273
index XXXXXXX..XXXXXXX 100644
274
--- a/target/arm/translate-vfp.c.inc
275
+++ b/target/arm/translate-vfp.c.inc
276
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
277
return true;
278
}
279
280
-/*
281
- * Decode VLLDM and VLSTM are nonstandard because:
282
- * * if there is no FPU then these insns must NOP in
283
- * Secure state and UNDEF in Nonsecure state
284
- * * if there is an FPU then these insns do not have
285
- * the usual behaviour that vfp_access_check() provides of
286
- * being controlled by CPACR/NSACR enable bits or the
287
- * lazy-stacking logic.
288
- */
289
-static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
290
-{
291
- TCGv_i32 fptr;
292
-
293
- if (!arm_dc_feature(s, ARM_FEATURE_M) ||
294
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
295
- return false;
296
- }
297
-
298
- if (a->op) {
299
- /*
300
- * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
301
- * to take the IMPDEF option to make memory accesses to the stack
302
- * slots that correspond to the D16-D31 registers (discarding
303
- * read data and writing UNKNOWN values), so for us the T2
304
- * encoding behaves identically to the T1 encoding.
305
- */
306
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
307
- return false;
308
- }
309
- } else {
310
- /*
311
- * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
312
- * This is currently architecturally impossible, but we add the
313
- * check to stay in line with the pseudocode. Note that we must
314
- * emit code for the UNDEF so it takes precedence over the NOCP.
315
- */
316
- if (dc_isar_feature(aa32_simd_r32, s)) {
317
- unallocated_encoding(s);
318
- return true;
319
- }
320
- }
321
-
322
- /*
323
- * If not secure, UNDEF. We must emit code for this
324
- * rather than returning false so that this takes
325
- * precedence over the m-nocp.decode NOCP fallback.
326
- */
327
- if (!s->v8m_secure) {
328
- unallocated_encoding(s);
329
- return true;
330
- }
331
- /* If no fpu, NOP. */
332
- if (!dc_isar_feature(aa32_vfp, s)) {
333
- return true;
334
- }
335
-
336
- fptr = load_reg(s, a->rn);
337
- if (a->l) {
338
- gen_helper_v7m_vlldm(cpu_env, fptr);
339
- } else {
340
- gen_helper_v7m_vlstm(cpu_env, fptr);
341
- }
342
- tcg_temp_free_i32(fptr);
343
-
344
- /* End the TB, because we have updated FP control bits */
345
- s->base.is_jmp = DISAS_UPDATE_EXIT;
346
- return true;
347
-}
348
-
349
-static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
350
-{
351
- int btmreg, topreg;
352
- TCGv_i64 zero;
353
- TCGv_i32 aspen, sfpa;
354
-
355
- if (!dc_isar_feature(aa32_m_sec_state, s)) {
356
- /* Before v8.1M, fall through in decode to NOCP check */
357
- return false;
358
- }
359
-
360
- /* Explicitly UNDEF because this takes precedence over NOCP */
361
- if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
362
- unallocated_encoding(s);
363
- return true;
364
- }
365
-
366
- if (!dc_isar_feature(aa32_vfp_simd, s)) {
367
- /* NOP if we have neither FP nor MVE */
368
- return true;
369
- }
370
-
371
- /*
372
- * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
373
- * active floating point context so we must NOP (without doing
374
- * any lazy state preservation or the NOCP check).
375
- */
376
- aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
377
- sfpa = load_cpu_field(v7m.control[M_REG_S]);
378
- tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
379
- tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
380
- tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
381
- tcg_gen_or_i32(sfpa, sfpa, aspen);
382
- arm_gen_condlabel(s);
383
- tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
384
-
385
- if (s->fp_excp_el != 0) {
386
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
387
- syn_uncategorized(), s->fp_excp_el);
388
- return true;
389
- }
390
-
391
- topreg = a->vd + a->imm - 1;
392
- btmreg = a->vd;
393
-
394
- /* Convert to Sreg numbers if the insn specified in Dregs */
395
- if (a->size == 3) {
396
- topreg = topreg * 2 + 1;
397
- btmreg *= 2;
398
- }
399
-
400
- if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
401
- /* UNPREDICTABLE: we choose to undef */
402
- unallocated_encoding(s);
403
- return true;
404
- }
405
-
406
- /* Silently ignore requests to clear D16-D31 if they don't exist */
407
- if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
408
- topreg = 31;
409
- }
410
-
411
- if (!vfp_access_check(s)) {
412
- return true;
413
- }
414
-
415
- /* Zero the Sregs from btmreg to topreg inclusive. */
416
- zero = tcg_const_i64(0);
417
- if (btmreg & 1) {
418
- write_neon_element64(zero, btmreg >> 1, 1, MO_32);
419
- btmreg++;
420
- }
421
- for (; btmreg + 1 <= topreg; btmreg += 2) {
422
- write_neon_element64(zero, btmreg >> 1, 0, MO_64);
423
- }
424
- if (btmreg == topreg) {
425
- write_neon_element64(zero, btmreg >> 1, 0, MO_32);
426
- btmreg++;
427
- }
428
- assert(btmreg == topreg + 1);
429
- /* TODO: when MVE is implemented, zero VPR here */
430
- return true;
431
-}
432
-
433
-static bool trans_NOCP(DisasContext *s, arg_nocp *a)
434
-{
435
- /*
436
- * Handle M-profile early check for disabled coprocessor:
437
- * all we need to do here is emit the NOCP exception if
438
- * the coprocessor is disabled. Otherwise we return false
439
- * and the real VFP/etc decode will handle the insn.
440
- */
441
- assert(arm_dc_feature(s, ARM_FEATURE_M));
442
-
443
- if (a->cp == 11) {
444
- a->cp = 10;
445
- }
446
- if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
447
- (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
448
- /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
449
- a->cp = 10;
450
- }
451
-
452
- if (a->cp != 10) {
453
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
454
- syn_uncategorized(), default_exception_el(s));
455
- return true;
456
- }
457
-
458
- if (s->fp_excp_el != 0) {
459
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
460
- syn_uncategorized(), s->fp_excp_el);
461
- return true;
462
- }
463
-
464
- return false;
465
-}
466
-
467
-static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
468
-{
469
- /* This range needs a coprocessor check for v8.1M and later only */
470
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
471
- return false;
472
- }
473
- return trans_NOCP(s, a);
474
-}
475
-
476
static bool trans_VINS(DisasContext *s, arg_VINS *a)
477
{
148
{
478
TCGv_i32 rd, rm;
149
TCGv_ptr qd;
479
diff --git a/target/arm/meson.build b/target/arm/meson.build
480
index XXXXXXX..XXXXXXX 100644
481
--- a/target/arm/meson.build
482
+++ b/target/arm/meson.build
483
@@ -XXX,XX +XXX,XX @@ gen = [
484
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
485
decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
486
decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
487
- decodetree.process('m-nocp.decode', extra_args: '--static-decode=disas_m_nocp'),
488
+ decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
489
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
490
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
491
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
492
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
493
'op_helper.c',
494
'tlb_helper.c',
495
'translate.c',
496
+ 'translate-m-nocp.c',
497
'vec_helper.c',
498
'vfp_helper.c',
499
'cpu_tcg.c',
500
--
150
--
501
2.20.1
151
2.20.1
502
152
503
153
diff view generated by jsdifflib
1
Move the NeonGenThreeOpEnvFn typedef to translate.h together
1
The MVE extension to v8.1M includes some new shift instructions which
2
with the other similar typedefs.
2
sit entirely within the non-coprocessor part of the encoding space
3
and which operate only on general-purpose registers. They take up
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
3
23
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
7
Message-id: 20210430132740.10391-12-peter.maydell@linaro.org
8
---
27
---
9
target/arm/translate.h | 2 ++
28
target/arm/helper-mve.h | 3 ++
10
target/arm/translate.c | 3 ---
29
target/arm/translate.h | 1 +
11
2 files changed, 2 insertions(+), 3 deletions(-)
30
target/arm/t32.decode | 28 +++++++++++++
12
31
target/arm/mve_helper.c | 10 +++++
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
33
5 files changed, 132 insertions(+)
34
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
38
+++ b/target/arm/helper-mve.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.h
48
--- a/target/arm/translate.h
16
+++ b/target/arm/translate.h
49
+++ b/target/arm/translate.h
17
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
18
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
19
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
20
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
21
+typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
22
+ TCGv_i32, TCGv_i32);
55
23
typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
56
/**
24
typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
57
* arm_tbflags_from_tb:
25
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
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
+}
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
29
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
30
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
31
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
133
return true;
32
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
134
}
33
135
34
-/* Function prototypes for gen_ functions calling Neon helpers. */
136
+/*
35
-typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
137
+ * v8.1M MVE wide-shifts
36
- TCGv_i32, TCGv_i32);
138
+ */
37
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
38
/* initialize TCG globals. */
140
+ WideShiftImmFn *fn)
39
void arm_translate_init(void)
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);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
40
--
229
--
41
2.20.1
230
2.20.1
42
231
43
232
diff view generated by jsdifflib
1
The VFPGenFixPointFn typedef is unused; delete it.
1
Implement the MVE long shifts by register, which perform shifts on a
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
the shift count in another general-purpose register, which might be
4
either positive or negative.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
2
11
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
6
Message-id: 20210430132740.10391-11-peter.maydell@linaro.org
7
---
15
---
8
target/arm/translate.c | 2 --
16
target/arm/helper-mve.h | 6 +++
9
1 file changed, 2 deletions(-)
17
target/arm/translate.h | 1 +
10
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
+}
11
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
12
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
213
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
214
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
16
/* Function prototypes for gen_ functions calling Neon helpers. */
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
217
}
18
TCGv_i32, TCGv_i32);
218
19
-/* Function prototypes for gen_ functions for fix point conversions */
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
20
-typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
220
+{
21
221
+ TCGv_i64 rda;
22
/* initialize TCG globals. */
222
+ TCGv_i32 rdalo, rdahi;
23
void arm_translate_init(void)
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
24
--
291
--
25
2.20.1
292
2.20.1
26
293
27
294
diff view generated by jsdifflib
1
Switch translate-vfp.c.inc from being #included into translate.c
1
Implement the MVE shifts by immediate, which perform shifts
2
to being its own compilation unit.
2
on a single general-purpose register.
3
4
These patterns overlap with the long-shift-by-immediates,
5
so we have to rearrange the grouping a little here.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-9-peter.maydell@linaro.org
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
8
---
10
---
9
target/arm/translate-a32.h | 2 ++
11
target/arm/helper-mve.h | 3 ++
10
target/arm/{translate-vfp.c.inc => translate-vfp.c} | 12 +++++++-----
12
target/arm/translate.h | 1 +
11
target/arm/translate.c | 3 +--
13
target/arm/t32.decode | 31 ++++++++++++++-----
12
target/arm/meson.build | 5 +++--
14
target/arm/mve_helper.c | 10 ++++++
13
4 files changed, 13 insertions(+), 9 deletions(-)
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
14
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (99%)
16
5 files changed, 104 insertions(+), 9 deletions(-)
15
17
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
20
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/translate-a32.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
20
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
21
46
22
/* Prototypes for autogenerated disassembler functions */
47
&mve_shl_ri rdalo rdahi shim
23
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
48
&mve_shl_rr rdalo rdahi rm
24
+bool disas_vfp(DisasContext *s, uint32_t insn);
49
+&mve_sh_ri rda shim
25
+bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
50
26
51
# rdahi: bits [3:1] from insn, bit 0 is 1
27
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
52
# rdalo: bits [3:1] from insn, bit 0 is 0
28
void arm_gen_condlabel(DisasContext *s);
29
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c
30
similarity index 99%
31
rename from target/arm/translate-vfp.c.inc
32
rename to target/arm/translate-vfp.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-vfp.c.inc
35
+++ b/target/arm/translate-vfp.c
36
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@
37
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
38
*/
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
39
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
40
-/*
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
41
- * This file is intended to be included from translate.c; it uses
58
+ &mve_sh_ri shim=%imm5_12_6
42
- * some macros and definitions provided by that file.
59
43
- * It might be possible to convert it to a standalone .c file eventually.
60
{
44
- */
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
45
+#include "qemu/osdep.h"
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
46
+#include "tcg/tcg-op.h"
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
47
+#include "tcg/tcg-op-gvec.h"
64
# handling them as r13 and r15 accesses with the same semantics as A32).
48
+#include "exec/exec-all.h"
65
[
49
+#include "exec/gen-icount.h"
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
50
+#include "translate.h"
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
51
+#include "translate-a32.h"
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
52
69
+ {
53
/* Include the generated VFP decoder */
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
54
#include "decode-vfp.c.inc"
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
56
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate.c
118
--- a/target/arm/translate.c
58
+++ b/target/arm/translate.c
119
+++ b/target/arm/translate.c
59
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
60
121
61
#define ARM_CP_RW_BIT (1 << 20)
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
62
123
{
63
-/* Include the VFP and Neon decoders */
124
- TCGv_i32 t = tcg_temp_new_i32();
64
-#include "translate-vfp.c.inc"
125
+ TCGv_i32 t;
65
+/* Include the Neon decoder */
126
66
#include "translate-neon.c.inc"
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
67
128
+ if (sh == 32) {
68
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
129
+ tcg_gen_movi_i32(d, 0);
69
diff --git a/target/arm/meson.build b/target/arm/meson.build
130
+ return;
70
index XXXXXXX..XXXXXXX 100644
131
+ }
71
--- a/target/arm/meson.build
132
+ t = tcg_temp_new_i32();
72
+++ b/target/arm/meson.build
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
73
@@ -XXX,XX +XXX,XX @@ gen = [
134
tcg_gen_sari_i32(d, a, sh);
74
decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
135
tcg_gen_add_i32(d, d, t);
75
decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
76
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
137
77
- decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
78
- decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
139
{
79
+ decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
140
- TCGv_i32 t = tcg_temp_new_i32();
80
+ decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
141
+ TCGv_i32 t;
81
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
142
82
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
83
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
144
+ if (sh == 32) {
84
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
85
'tlb_helper.c',
146
+ return;
86
'translate.c',
147
+ }
87
'translate-m-nocp.c',
148
+ t = tcg_temp_new_i32();
88
+ 'translate-vfp.c',
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
89
'vec_helper.c',
150
tcg_gen_shri_i32(d, a, sh);
90
'vfp_helper.c',
151
tcg_gen_add_i32(d, d, t);
91
'cpu_tcg.c',
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
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);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
92
--
211
--
93
2.20.1
212
2.20.1
94
213
95
214
diff view generated by jsdifflib
1
The functions vfp_load_reg32(), vfp_load_reg64(), vfp_store_reg32()
1
Implement the MVE shifts by register, which perform
2
and vfp_store_reg64() are used only in translate-vfp.c.inc. Move
2
shifts on a single general-purpose register.
3
them to that file.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-7-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate.c | 20 --------------------
8
target/arm/helper-mve.h | 2 ++
11
target/arm/translate-vfp.c.inc | 20 ++++++++++++++++++++
9
target/arm/translate.h | 1 +
12
2 files changed, 20 insertions(+), 20 deletions(-)
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
13
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
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);
87
}
88
+
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
90
+{
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
92
+}
93
+
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
95
+{
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
100
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
101
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
19
}
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
20
}
104
}
21
105
22
-static inline void vfp_load_reg64(TCGv_i64 var, int reg)
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
23
-{
24
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
25
-}
26
-
27
-static inline void vfp_store_reg64(TCGv_i64 var, int reg)
28
-{
29
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
30
-}
31
-
32
-static inline void vfp_load_reg32(TCGv_i32 var, int reg)
33
-{
34
- tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
35
-}
36
-
37
-static inline void vfp_store_reg32(TCGv_i32 var, int reg)
38
-{
39
- tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
40
-}
41
-
42
void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
43
{
44
long off = neon_element_offset(reg, ele, memop);
45
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-vfp.c.inc
48
+++ b/target/arm/translate-vfp.c.inc
49
@@ -XXX,XX +XXX,XX @@
50
#include "decode-vfp.c.inc"
51
#include "decode-vfp-uncond.c.inc"
52
53
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
54
+{
107
+{
55
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
110
+ return false;
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
56
+}
124
+}
57
+
125
+
58
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
59
+{
127
+{
60
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
61
+}
129
+}
62
+
130
+
63
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
64
+{
132
+{
65
+ tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
66
+}
67
+
68
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
69
+{
70
+ tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
71
+}
134
+}
72
+
135
+
73
/*
136
/*
74
* The imm8 encodes the sign bit, enough bits to represent an exponent in
137
* Multiply and multiply accumulate
75
* the range 01....1xx to 10....0xx, and the most significant 4 bits of
138
*/
76
--
139
--
77
2.20.1
140
2.20.1
78
141
79
142
diff view generated by jsdifflib
Deleted patch
1
The WFI insn is not system-mode only, though it doesn't usually make
2
a huge amount of sense for userspace code to execute it. Currently
3
if you try it in qemu-arm then the helper function will raise an
4
EXCP_HLT exception, which is not covered by the switch in cpu_loop()
5
and results in an abort:
6
1
7
qemu: unhandled CPU exception 0x10001 - aborting
8
R00=00000001 R01=408003e4 R02=408003ec R03=000102ec
9
R04=00010a28 R05=00010158 R06=00087460 R07=00010158
10
R08=00000000 R09=00000000 R10=00085b7c R11=408002a4
11
R12=408002b8 R13=408002a0 R14=0001057c R15=000102f8
12
PSR=60000010 -ZC- A usr32
13
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7fcbfa4f0a12
14
15
Make the WFI helper function return immediately in the usermode
16
emulator. This turns WFI into a NOP, which is OK because:
17
* architecturally "WFI is a NOP" is a permitted implementation
18
* aarch64 Linux kernels use the SCTLR_EL1.nTWI bit to trap
19
userspace WFI and NOP it (though aarch32 kernels currently
20
just let WFI do whatever it would do)
21
22
We could in theory make the translate.c code special case user-mode
23
emulation and NOP the insn entirely rather than making the helper
24
do nothing, but because no real world code will be trying to
25
execute WFI we don't care about efficiency and the helper provides
26
a single place where we can make the change rather than having
27
to touch multiple places in translate.c and translate-a64.c.
28
29
Fixes: https://bugs.launchpad.net/qemu/+bug/1926759
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20210430162212.825-1-peter.maydell@linaro.org
33
---
34
target/arm/op_helper.c | 12 ++++++++++++
35
1 file changed, 12 insertions(+)
36
37
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/op_helper.c
40
+++ b/target/arm/op_helper.c
41
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
42
43
void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
44
{
45
+#ifdef CONFIG_USER_ONLY
46
+ /*
47
+ * WFI in the user-mode emulator is technically permitted but not
48
+ * something any real-world code would do. AArch64 Linux kernels
49
+ * trap it via SCTRL_EL1.nTWI and make it an (expensive) NOP;
50
+ * AArch32 kernels don't trap it so it will delay a bit.
51
+ * For QEMU, make it NOP here, because trying to raise EXCP_HLT
52
+ * would trigger an abort.
53
+ */
54
+ return;
55
+#else
56
CPUState *cs = env_cpu(env);
57
int target_el = check_wfx_trap(env, false);
58
59
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
60
cs->exception_index = EXCP_HLT;
61
cs->halted = 1;
62
cpu_loop_exit(cs);
63
+#endif
64
}
65
66
void HELPER(wfe)(CPUARMState *env)
67
--
68
2.20.1
69
70
diff view generated by jsdifflib