1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
1
The following changes since commit bf4460a8d9a86f6cfe05d7a7f470c48e3a93d8b2:
2
2
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
3
Merge tag 'pull-tcg-20230123' of https://gitlab.com/rth7680/qemu into staging (2023-02-03 09:30:45 +0000)
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-20210702
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230203
8
8
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
9
for you to fetch changes up to bb18151d8bd9bedc497ee9d4e8d81b39a4e5bbf6:
10
10
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
11
target/arm: Enable FEAT_FGT on '-cpu max' (2023-02-03 12:59:24 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* more MVE instructions
15
* Fix physical address resolution for Stage2
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
16
* pl011: refactoring, implement reset method
17
* target/arm: Check NaN mode before silencing NaN
17
* Support GICv3 with hvf acceleration
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
18
* sbsa-ref: remove cortex-a76 from list of supported cpus
19
* hw/arm: Add basic power management to raspi.
19
* Correct syndrome for ATS12NSO* traps at Secure EL1
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
20
* Fix priority of HSTR_EL2 traps vs UNDEFs
21
* Implement FEAT_FGT for '-cpu max'
21
22
22
----------------------------------------------------------------
23
----------------------------------------------------------------
23
Joe Komlodi (1):
24
Alexander Graf (3):
24
target/arm: Check NaN mode before silencing NaN
25
hvf: arm: Add support for GICv3
26
hw/arm/virt: Consolidate GIC finalize logic
27
hw/arm/virt: Make accels in GIC finalize logic explicit
25
28
26
Maxim Uvarov (1):
29
Evgeny Iakovlev (4):
27
hw/gpio/gpio_pwr: use shutdown function for reboot
30
hw/char/pl011: refactor FIFO depth handling code
31
hw/char/pl011: add post_load hook for backwards-compatibility
32
hw/char/pl011: implement a reset method
33
hw/char/pl011: better handling of FIFO flags on LCR reset
28
34
29
Nolan Leake (1):
35
Marcin Juszkiewicz (1):
30
hw/arm: Add basic power management to raspi.
36
sbsa-ref: remove cortex-a76 from list of supported cpus
31
37
32
Patrick Venture (2):
38
Peter Maydell (23):
33
docs/system/arm: Add quanta-q7l1-bmc reference
39
target/arm: Name AT_S1E1RP and AT_S1E1WP cpregs correctly
34
docs/system/arm: Add quanta-gbs-bmc reference
40
target/arm: Correct syndrome for ATS12NSO* at Secure EL1
41
target/arm: Remove CP_ACCESS_TRAP_UNCATEGORIZED_{EL2, EL3}
42
target/arm: Move do_coproc_insn() syndrome calculation earlier
43
target/arm: All UNDEF-at-EL0 traps take priority over HSTR_EL2 traps
44
target/arm: Make HSTR_EL2 traps take priority over UNDEF-at-EL1
45
target/arm: Disable HSTR_EL2 traps if EL2 is not enabled
46
target/arm: Define the FEAT_FGT registers
47
target/arm: Implement FGT trapping infrastructure
48
target/arm: Mark up sysregs for HFGRTR bits 0..11
49
target/arm: Mark up sysregs for HFGRTR bits 12..23
50
target/arm: Mark up sysregs for HFGRTR bits 24..35
51
target/arm: Mark up sysregs for HFGRTR bits 36..63
52
target/arm: Mark up sysregs for HDFGRTR bits 0..11
53
target/arm: Mark up sysregs for HDFGRTR bits 12..63
54
target/arm: Mark up sysregs for HFGITR bits 0..11
55
target/arm: Mark up sysregs for HFGITR bits 12..17
56
target/arm: Mark up sysregs for HFGITR bits 18..47
57
target/arm: Mark up sysregs for HFGITR bits 48..63
58
target/arm: Implement the HFGITR_EL2.ERET trap
59
target/arm: Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 traps
60
target/arm: Implement MDCR_EL2.TDCC and MDCR_EL3.TDCC traps
61
target/arm: Enable FEAT_FGT on '-cpu max'
35
62
36
Peter Maydell (18):
63
Richard Henderson (2):
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
64
hw/arm: Use TYPE_ARM_SMMUV3
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
65
target/arm: Fix physical address resolution for Stage2
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
55
66
56
Philippe Mathieu-Daudé (1):
67
docs/system/arm/emulation.rst | 1 +
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
68
include/hw/arm/virt.h | 15 +-
58
69
include/hw/char/pl011.h | 5 +-
59
docs/system/arm/aspeed.rst | 1 +
70
target/arm/cpregs.h | 484 +++++++++++++++++++++++++++++++++++++++++-
60
docs/system/arm/nuvoton.rst | 5 +-
71
target/arm/cpu.h | 18 ++
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
72
target/arm/internals.h | 20 ++
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
73
target/arm/syndrome.h | 10 +
63
target/arm/helper-mve.h | 108 +++++++
74
target/arm/translate.h | 6 +
64
target/arm/translate.h | 41 +++
75
hw/arm/sbsa-ref.c | 4 +-
65
target/arm/mve.decode | 177 ++++++++++-
76
hw/arm/virt.c | 203 +++++++++---------
66
target/arm/t32.decode | 71 ++++-
77
hw/char/pl011.c | 93 ++++++--
67
hw/arm/bcm2835_peripherals.c | 13 +-
78
hw/intc/arm_gicv3_cpuif.c | 18 +-
68
hw/gpio/gpio_pwr.c | 2 +-
79
target/arm/cpu64.c | 1 +
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
80
target/arm/debug_helper.c | 46 +++-
70
target/arm/helper-a64.c | 12 +-
81
target/arm/helper.c | 245 ++++++++++++++++++++-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
82
target/arm/hvf/hvf.c | 151 +++++++++++++
72
target/arm/translate-a64.c | 86 +-----
83
target/arm/op_helper.c | 58 ++++-
73
target/arm/translate-mve.c | 261 +++++++++++++++-
84
target/arm/ptw.c | 2 +-
74
target/arm/translate-neon.c | 81 -----
85
target/arm/translate-a64.c | 22 +-
75
target/arm/translate.c | 327 +++++++++++++++++++-
86
target/arm/translate.c | 125 +++++++----
76
target/arm/vfp_helper.c | 24 +-
87
target/arm/hvf/trace-events | 2 +
77
hw/misc/meson.build | 1 +
88
21 files changed, 1340 insertions(+), 189 deletions(-)
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
82
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
3
Use the macro instead of two explicit string literals.
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
6
4
7
To avoid this, we check to see what NaN mode we're running in before we call
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
floatxx_silence_nan().
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
8
Message-id: 20230124232059.4017615-1-richard.henderson@linaro.org
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/helper-a64.c | 12 +++++++++---
11
hw/arm/sbsa-ref.c | 3 ++-
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
12
hw/arm/virt.c | 2 +-
18
2 files changed, 27 insertions(+), 9 deletions(-)
13
2 files changed, 3 insertions(+), 2 deletions(-)
19
14
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.c
17
--- a/hw/arm/sbsa-ref.c
23
+++ b/target/arm/helper-a64.c
18
+++ b/hw/arm/sbsa-ref.c
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
19
@@ -XXX,XX +XXX,XX @@
25
float16 nan = a;
20
#include "exec/hwaddr.h"
26
if (float16_is_signaling_nan(a, fpst)) {
21
#include "kvm_arm.h"
27
float_raise(float_flag_invalid, fpst);
22
#include "hw/arm/boot.h"
28
- nan = float16_silence_nan(a, fpst);
23
+#include "hw/arm/smmuv3.h"
29
+ if (!fpst->default_nan_mode) {
24
#include "hw/block/flash.h"
30
+ nan = float16_silence_nan(a, fpst);
25
#include "hw/boards.h"
31
+ }
26
#include "hw/ide/internal.h"
32
}
27
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
33
if (fpst->default_nan_mode) {
28
DeviceState *dev;
34
nan = float16_default_nan(fpst);
29
int i;
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
30
36
float32 nan = a;
31
- dev = qdev_new("arm-smmuv3");
37
if (float32_is_signaling_nan(a, fpst)) {
32
+ dev = qdev_new(TYPE_ARM_SMMUV3);
38
float_raise(float_flag_invalid, fpst);
33
39
- nan = float32_silence_nan(a, fpst);
34
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
40
+ if (!fpst->default_nan_mode) {
35
&error_abort);
41
+ nan = float32_silence_nan(a, fpst);
36
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
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
37
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
38
--- a/hw/arm/virt.c
60
+++ b/target/arm/vfp_helper.c
39
+++ b/hw/arm/virt.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
40
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms,
62
float16 nan = f16;
41
return;
63
if (float16_is_signaling_nan(f16, fpst)) {
42
}
64
float_raise(float_flag_invalid, fpst);
43
65
- nan = float16_silence_nan(f16, fpst);
44
- dev = qdev_new("arm-smmuv3");
66
+ if (!fpst->default_nan_mode) {
45
+ dev = qdev_new(TYPE_ARM_SMMUV3);
67
+ nan = float16_silence_nan(f16, fpst);
46
68
+ }
47
object_property_set_link(OBJECT(dev), "primary-bus", OBJECT(bus),
69
}
48
&error_abort);
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);
127
--
49
--
128
2.20.1
50
2.34.1
129
51
130
52
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
3
Conversion to probe_access_full missed applying the page offset.
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
4
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
5
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reported-by: Sid Manning <sidneym@quicinc.com>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
[PMM: tweaked commit message]
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230126233134.103193-1-richard.henderson@linaro.org
10
Fixes: f3639a64f602 ("target/arm: Use softmmu tlbs for page table walking")
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
hw/gpio/gpio_pwr.c | 2 +-
14
target/arm/ptw.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/gpio/gpio_pwr.c
19
--- a/target/arm/ptw.c
19
+++ b/hw/gpio/gpio_pwr.c
20
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
21
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
22
if (unlikely(flags & TLB_INVALID_MASK)) {
22
{
23
goto fail;
23
if (level) {
24
}
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
25
- ptw->out_phys = full->phys_addr;
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
26
+ ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
26
}
27
ptw->out_rw = full->prot & PAGE_WRITE;
27
}
28
pte_attrs = full->pte_attrs;
28
29
pte_secure = full->attrs.secure;
29
--
30
--
30
2.20.1
31
2.34.1
31
32
32
33
diff view generated by jsdifflib
1
Implement the MVE saturating shift-right-and-narrow insns
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
2
4
do_srshr() is borrowed from sve_helper.c.
3
PL011 can be in either of 2 modes depending guest config: FIFO and
4
single register. The last mode could be viewed as a 1-element-deep FIFO.
5
5
6
Current code open-codes a bunch of depth-dependent logic. Refactor FIFO
7
depth handling code to isolate calculating current FIFO depth.
8
9
One functional (albeit guest-invisible) side-effect of this change is
10
that previously we would always increment s->read_pos in UARTDR read
11
handler even if FIFO was disabled, now we are limiting read_pos to not
12
exceed FIFO depth (read_pos itself is reset to 0 if user disables FIFO).
13
14
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-id: 20230123162304.26254-2-eiakovlev@linux.microsoft.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
9
---
19
---
10
target/arm/helper-mve.h | 30 +++++++++++
20
include/hw/char/pl011.h | 5 ++++-
11
target/arm/mve.decode | 28 ++++++++++
21
hw/char/pl011.c | 30 ++++++++++++++++++------------
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
22
2 files changed, 22 insertions(+), 13 deletions(-)
13
target/arm/translate-mve.c | 12 +++++
14
4 files changed, 174 insertions(+)
15
23
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
26
--- a/include/hw/char/pl011.h
19
+++ b/target/arm/helper-mve.h
27
+++ b/include/hw/char/pl011.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(PL011State, PL011)
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
/* This shares the same struct (and cast macro) as the base pl011 device */
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
#define TYPE_PL011_LUMINARY "pl011_luminary"
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
32
+/* Depth of UART FIFO in bytes, when FIFO mode is enabled (else depth == 1) */
33
+#define PL011_FIFO_DEPTH 16
24
+
34
+
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
struct PL011State {
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
SysBusDevice parent_obj;
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
@@ -XXX,XX +XXX,XX @@ struct PL011State {
29
+
39
uint32_t dmacr;
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
uint32_t int_enabled;
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
uint32_t int_level;
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
- uint32_t read_fifo[16];
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+ uint32_t read_fifo[PL011_FIFO_DEPTH];
34
+
44
uint32_t ilpr;
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
uint32_t ibrd;
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
uint32_t fbrd;
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
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
48
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
49
--- a/hw/char/pl011.c
57
+++ b/target/arm/mve.decode
50
+++ b/hw/char/pl011.c
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
51
@@ -XXX,XX +XXX,XX @@ static void pl011_update(PL011State *s)
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)
95
}
52
}
96
}
53
}
97
54
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
55
+static bool pl011_is_fifo_enabled(PL011State *s)
99
+{
56
+{
100
+ if (likely(sh < 64)) {
57
+ return (s->lcr & 0x10) != 0;
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
102
+ } else {
103
+ /* Rounding the sign bit always produces 0. */
104
+ return 0;
105
+ }
106
+}
58
+}
107
+
59
+
108
DO_VSHRN_ALL(vshrn, DO_SHR)
60
+static inline unsigned pl011_get_fifo_depth(PL011State *s)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
113
+{
61
+{
114
+ if (val > max) {
62
+ /* Note: FIFO depth is expected to be power-of-2 */
115
+ *satp = true;
63
+ return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
116
+ return max;
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
122
+ }
123
+}
64
+}
124
+
65
+
125
+/* Saturating narrowing right shifts */
66
static uint64_t pl011_read(void *opaque, hwaddr offset,
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
67
unsigned size)
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
68
{
128
+ void *vm, uint32_t shift) \
69
@@ -XXX,XX +XXX,XX @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
129
+ { \
70
c = s->read_fifo[s->read_pos];
130
+ LTYPE *m = vm; \
71
if (s->read_count > 0) {
131
+ TYPE *d = vd; \
72
s->read_count--;
132
+ uint16_t mask = mve_element_mask(env); \
73
- if (++s->read_pos == 16)
133
+ bool qc = false; \
74
- s->read_pos = 0;
134
+ unsigned le; \
75
+ s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
76
}
136
+ bool sat = false; \
77
if (s->read_count == 0) {
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
78
s->flags |= PL011_FLAG_RXFE;
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
79
@@ -XXX,XX +XXX,XX @@ static int pl011_can_receive(void *opaque)
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
80
PL011State *s = (PL011State *)opaque;
140
+ } \
81
int r;
141
+ if (qc) { \
82
142
+ env->vfp.qc[0] = qc; \
83
- if (s->lcr & 0x10) {
143
+ } \
84
- r = s->read_count < 16;
144
+ mve_advance_vpt(env); \
85
- } else {
145
+ }
86
- r = s->read_count < 1;
146
+
87
- }
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
88
+ r = s->read_count < pl011_get_fifo_depth(s);
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
89
trace_pl011_can_receive(s->lcr, s->read_count, r);
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
90
return r;
150
+
91
}
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
92
@@ -XXX,XX +XXX,XX @@ static void pl011_put_fifo(void *opaque, uint32_t value)
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
93
{
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
94
PL011State *s = (PL011State *)opaque;
154
+
95
int slot;
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
96
+ unsigned pipe_depth;
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
97
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
98
- slot = s->read_pos + s->read_count;
158
+
99
- if (slot >= 16)
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
100
- slot -= 16;
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
101
+ pipe_depth = pl011_get_fifo_depth(s);
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
102
+ slot = (s->read_pos + s->read_count) & (pipe_depth - 1);
162
+
103
s->read_fifo[slot] = value;
163
+#define DO_SHRN_SB(N, M, SATP) \
104
s->read_count++;
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
105
s->flags &= ~PL011_FLAG_RXFE;
165
+#define DO_SHRN_UB(N, M, SATP) \
106
trace_pl011_put_fifo(value, s->read_count);
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
107
- if (!(s->lcr & 0x10) || s->read_count == 16) {
167
+#define DO_SHRUN_B(N, M, SATP) \
108
+ if (s->read_count == pipe_depth) {
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
109
trace_pl011_put_fifo_full();
169
+
110
s->flags |= PL011_FLAG_RXFF;
170
+#define DO_SHRN_SH(N, M, SATP) \
111
}
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
112
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011 = {
172
+#define DO_SHRN_UH(N, M, SATP) \
113
VMSTATE_UINT32(dmacr, PL011State),
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
114
VMSTATE_UINT32(int_enabled, PL011State),
174
+#define DO_SHRUN_H(N, M, SATP) \
115
VMSTATE_UINT32(int_level, PL011State),
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
116
- VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
176
+
117
+ VMSTATE_UINT32_ARRAY(read_fifo, PL011State, PL011_FIFO_DEPTH),
177
+#define DO_RSHRN_SB(N, M, SATP) \
118
VMSTATE_UINT32(ilpr, PL011State),
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
119
VMSTATE_UINT32(ibrd, PL011State),
179
+#define DO_RSHRN_UB(N, M, SATP) \
120
VMSTATE_UINT32(fbrd, PL011State),
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)
224
--
121
--
225
2.20.1
122
2.34.1
226
123
227
124
diff view generated by jsdifflib
1
Implement the MVE shifts by immediate, which perform shifts
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
on a single general-purpose register.
3
2
4
These patterns overlap with the long-shift-by-immediates,
3
Previous change slightly modified the way we handle data writes when
5
so we have to rearrange the grouping a little here.
4
FIFO is disabled. Previously we kept incrementing read_pos and were
5
storing data at that position, although we only have a
6
single-register-deep FIFO now. Then we changed it to always store data
7
at pos 0.
6
8
9
If guest disables FIFO and the proceeds to read data, it will work out
10
fine, because we still read from current read_pos before setting it to
11
0.
12
13
However, to make code less fragile, introduce a post_load hook for
14
PL011State and move fixup read FIFO state when FIFO is disabled. Since
15
we are introducing a post_load hook, also do some sanity checking on
16
untrusted incoming input state.
17
18
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
19
Message-id: 20230123162304.26254-3-eiakovlev@linux.microsoft.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
10
---
21
---
11
target/arm/helper-mve.h | 3 ++
22
hw/char/pl011.c | 25 +++++++++++++++++++++++++
12
target/arm/translate.h | 1 +
23
1 file changed, 25 insertions(+)
13
target/arm/t32.decode | 31 ++++++++++++++-----
14
target/arm/mve_helper.c | 10 ++++++
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
24
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
25
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
19
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
27
--- a/hw/char/pl011.c
21
+++ b/target/arm/helper-mve.h
28
+++ b/hw/char/pl011.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011_clock = {
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
}
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
};
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
33
+static int pl011_post_load(void *opaque, int version_id)
34
+{
35
+ PL011State* s = opaque;
26
+
36
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
37
+ /* Sanity-check input state */
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
38
+ if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
+ s->read_count > ARRAY_SIZE(s->read_fifo)) {
30
index XXXXXXX..XXXXXXX 100644
40
+ return -1;
31
--- a/target/arm/translate.h
32
+++ b/target/arm/translate.h
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
41
+ }
84
+
42
+
85
+ {
43
+ if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
44
+ /*
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
45
+ * Older versions of PL011 didn't ensure that the single
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
46
+ * character in the FIFO in FIFO-disabled mode is in
47
+ * element 0 of the array; convert to follow the current
48
+ * code's assumptions.
49
+ */
50
+ s->read_fifo[0] = s->read_fifo[s->read_pos];
51
+ s->read_pos = 0;
89
+ }
52
+ }
90
+
53
+
91
+ {
54
+ return 0;
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
+}
55
+}
111
+
56
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
57
static const VMStateDescription vmstate_pl011 = {
113
+{
58
.name = "pl011",
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
59
.version_id = 2,
115
+}
60
.minimum_version_id = 2,
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
+ .post_load = pl011_post_load,
117
index XXXXXXX..XXXXXXX 100644
62
.fields = (VMStateField[]) {
118
--- a/target/arm/translate.c
63
VMSTATE_UINT32(readbuff, PL011State),
119
+++ b/target/arm/translate.c
64
VMSTATE_UINT32(flags, PL011State),
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
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
*/
211
--
65
--
212
2.20.1
66
2.34.1
213
214
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
Add a test booting and quickly shutdown a raspi2 machine,
3
PL011 currently lacks a reset method. Implement it.
4
to test the power management model:
5
4
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
5
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
8
Message-id: 20230123162304.26254-4-eiakovlev@linux.microsoft.com
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
44
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
10
---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
11
hw/char/pl011.c | 26 +++++++++++++++++++++-----
51
1 file changed, 43 insertions(+)
12
1 file changed, 21 insertions(+), 5 deletions(-)
52
13
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
14
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
54
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/acceptance/boot_linux_console.py
16
--- a/hw/char/pl011.c
56
+++ b/tests/acceptance/boot_linux_console.py
17
+++ b/hw/char/pl011.c
57
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void pl011_init(Object *obj)
58
from avocado import skip
19
s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
59
from avocado import skipUnless
20
ClockUpdate);
60
from avocado_qemu import Test
21
61
+from avocado_qemu import exec_command
22
- s->read_trigger = 1;
62
from avocado_qemu import exec_command_and_wait_for_pattern
23
- s->ifl = 0x12;
63
from avocado_qemu import interrupt_interactive_console_until_pattern
24
- s->cr = 0x300;
64
from avocado_qemu import wait_for_console_pattern
25
- s->flags = 0x90;
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
26
-
66
"""
27
s->id = pl011_id_arm;
67
self.do_test_arm_raspi2(0)
28
}
68
29
69
+ def test_arm_raspi2_initrd(self):
30
@@ -XXX,XX +XXX,XX @@ static void pl011_realize(DeviceState *dev, Error **errp)
70
+ """
31
pl011_event, NULL, s, NULL, true);
71
+ :avocado: tags=arch:arm
32
}
72
+ :avocado: tags=machine:raspi2
33
73
+ """
34
+static void pl011_reset(DeviceState *dev)
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
35
+{
75
+ 'pool/main/r/raspberrypi-firmware/'
36
+ PL011State *s = PL011(dev);
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
+
37
+
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
38
+ s->lcr = 0;
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
39
+ s->rsr = 0;
84
+ 'arm/rootfs-armv7a.cpio.gz')
40
+ s->dmacr = 0;
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
41
+ s->int_enabled = 0;
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
42
+ s->int_level = 0;
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
43
+ s->ilpr = 0;
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
44
+ s->ibrd = 0;
45
+ s->fbrd = 0;
46
+ s->read_pos = 0;
47
+ s->read_count = 0;
48
+ s->read_trigger = 1;
49
+ s->ifl = 0x12;
50
+ s->cr = 0x300;
51
+ s->flags = 0x90;
52
+}
89
+
53
+
90
+ self.vm.set_console()
54
static void pl011_class_init(ObjectClass *oc, void *data)
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
55
{
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
56
DeviceClass *dc = DEVICE_CLASS(oc);
93
+ 'panic=-1 noreboot ' +
57
94
+ 'dwc_otg.fiq_fsm_enable=0')
58
dc->realize = pl011_realize;
95
+ self.vm.add_args('-kernel', kernel_path,
59
+ dc->reset = pl011_reset;
96
+ '-dtb', dtb_path,
60
dc->vmsd = &vmstate_pl011;
97
+ '-initrd', initrd_path,
61
device_class_set_props(dc, pl011_properties);
98
+ '-append', kernel_command_line,
62
}
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
114
--
63
--
115
2.20.1
64
2.34.1
116
65
117
66
diff view generated by jsdifflib
New patch
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
1
2
3
Current FIFO handling code does not reset RXFE/RXFF flags when guest
4
resets FIFO by writing to UARTLCR register, although internal FIFO state
5
is reset to 0 read count. Actual guest-visible flag update will happen
6
only on next data read or write attempt. As a result of that any guest
7
that expects RXFE flag to be set (and RXFF to be cleared) after resetting
8
FIFO will never see that happen.
9
10
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20230123162304.26254-5-eiakovlev@linux.microsoft.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/char/pl011.c | 18 +++++++++++++-----
16
1 file changed, 13 insertions(+), 5 deletions(-)
17
18
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/char/pl011.c
21
+++ b/hw/char/pl011.c
22
@@ -XXX,XX +XXX,XX @@ static inline unsigned pl011_get_fifo_depth(PL011State *s)
23
return pl011_is_fifo_enabled(s) ? PL011_FIFO_DEPTH : 1;
24
}
25
26
+static inline void pl011_reset_fifo(PL011State *s)
27
+{
28
+ s->read_count = 0;
29
+ s->read_pos = 0;
30
+
31
+ /* Reset FIFO flags */
32
+ s->flags &= ~(PL011_FLAG_RXFF | PL011_FLAG_TXFF);
33
+ s->flags |= PL011_FLAG_RXFE | PL011_FLAG_TXFE;
34
+}
35
+
36
static uint64_t pl011_read(void *opaque, hwaddr offset,
37
unsigned size)
38
{
39
@@ -XXX,XX +XXX,XX @@ static void pl011_write(void *opaque, hwaddr offset,
40
case 11: /* UARTLCR_H */
41
/* Reset the FIFO state on FIFO enable or disable */
42
if ((s->lcr ^ value) & 0x10) {
43
- s->read_count = 0;
44
- s->read_pos = 0;
45
+ pl011_reset_fifo(s);
46
}
47
if ((s->lcr ^ value) & 0x1) {
48
int break_enable = value & 0x1;
49
@@ -XXX,XX +XXX,XX @@ static void pl011_reset(DeviceState *dev)
50
s->ilpr = 0;
51
s->ibrd = 0;
52
s->fbrd = 0;
53
- s->read_pos = 0;
54
- s->read_count = 0;
55
s->read_trigger = 1;
56
s->ifl = 0x12;
57
s->cr = 0x300;
58
- s->flags = 0x90;
59
+ s->flags = 0;
60
+ pl011_reset_fifo(s);
61
}
62
63
static void pl011_class_init(ObjectClass *oc, void *data)
64
--
65
2.34.1
diff view generated by jsdifflib
1
Implement the MVE long shifts by register, which perform shifts on a
1
From: Alexander Graf <agraf@csgraf.de>
2
pair of general-purpose registers treated as a 64-bit quantity, with
2
3
the shift count in another general-purpose register, which might be
3
We currently only support GICv2 emulation. To also support GICv3, we will
4
either positive or negative.
4
need to pass a few system registers into their respective handler functions.
5
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
6
This patch adds support for HVF to call into the TCG callbacks for GICv3
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
7
system register handlers. This is safe because the GICv3 TCG code is generic
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
8
as long as we limit ourselves to EL0 and EL1 - which are the only modes
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
9
supported by HVF.
10
we have to move the CSEL pattern into the same decodetree group.
10
11
11
To make sure nobody trips over that, we also annotate callbacks that don't
12
work in HVF mode, such as EL state change hooks.
13
14
With GICv3 support in place, we can run with more than 8 vCPUs.
15
16
Signed-off-by: Alexander Graf <agraf@csgraf.de>
17
Message-id: 20230128224459.70676-1-agraf@csgraf.de
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
15
---
20
---
16
target/arm/helper-mve.h | 6 +++
21
hw/intc/arm_gicv3_cpuif.c | 16 +++-
17
target/arm/translate.h | 1 +
22
target/arm/hvf/hvf.c | 151 ++++++++++++++++++++++++++++++++++++
18
target/arm/t32.decode | 16 +++++--
23
target/arm/hvf/trace-events | 2 +
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
24
3 files changed, 168 insertions(+), 1 deletion(-)
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
25
21
5 files changed, 182 insertions(+), 3 deletions(-)
26
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
22
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
28
--- a/hw/intc/arm_gicv3_cpuif.c
26
+++ b/target/arm/helper-mve.h
29
+++ b/hw/intc/arm_gicv3_cpuif.c
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
@@ -XXX,XX +XXX,XX @@
28
31
#include "hw/irq.h"
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
32
#include "cpu.h"
30
33
#include "target/arm/cpregs.h"
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
+#include "sysemu/tcg.h"
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+#include "sysemu/qtest.h"
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
/*
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
* Special case return value from hppvi_index(); must be larger than
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
40
* which case we'd get the wrong value.
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
41
* So instead we define the regs with no ri->opaque info, and
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
* get back to the GICv3CPUState from the CPUARMState.
43
+ *
44
+ * These CP regs callbacks can be called from either TCG or HVF code.
45
*/
46
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
47
48
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
49
define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
50
}
51
}
52
- arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
53
+ if (tcg_enabled() || qtest_enabled()) {
54
+ /*
55
+ * We can only trap EL changes with TCG. However the GIC interrupt
56
+ * state only changes on EL changes involving EL2 or EL3, so for
57
+ * the non-TCG case this is OK, as EL2 and EL3 can't exist.
58
+ */
59
+ arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
60
+ } else {
61
+ assert(!arm_feature(&cpu->env, ARM_FEATURE_EL2));
62
+ assert(!arm_feature(&cpu->env, ARM_FEATURE_EL3));
63
+ }
64
}
65
}
66
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
40
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
68
--- a/target/arm/hvf/hvf.c
42
+++ b/target/arm/translate.h
69
+++ b/target/arm/hvf/hvf.c
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 @@
70
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
71
#define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0)
57
72
#define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7)
58
&mve_shl_ri rdalo rdahi shim
73
59
+&mve_shl_rr rdalo rdahi rm
74
+#define SYSREG_ICC_AP0R0_EL1 SYSREG(3, 0, 12, 8, 4)
60
75
+#define SYSREG_ICC_AP0R1_EL1 SYSREG(3, 0, 12, 8, 5)
61
# rdahi: bits [3:1] from insn, bit 0 is 1
76
+#define SYSREG_ICC_AP0R2_EL1 SYSREG(3, 0, 12, 8, 6)
62
# rdalo: bits [3:1] from insn, bit 0 is 0
77
+#define SYSREG_ICC_AP0R3_EL1 SYSREG(3, 0, 12, 8, 7)
63
@@ -XXX,XX +XXX,XX @@
78
+#define SYSREG_ICC_AP1R0_EL1 SYSREG(3, 0, 12, 9, 0)
64
79
+#define SYSREG_ICC_AP1R1_EL1 SYSREG(3, 0, 12, 9, 1)
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
80
+#define SYSREG_ICC_AP1R2_EL1 SYSREG(3, 0, 12, 9, 2)
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
81
+#define SYSREG_ICC_AP1R3_EL1 SYSREG(3, 0, 12, 9, 3)
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
82
+#define SYSREG_ICC_ASGI1R_EL1 SYSREG(3, 0, 12, 11, 6)
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
83
+#define SYSREG_ICC_BPR0_EL1 SYSREG(3, 0, 12, 8, 3)
69
84
+#define SYSREG_ICC_BPR1_EL1 SYSREG(3, 0, 12, 12, 3)
70
{
85
+#define SYSREG_ICC_CTLR_EL1 SYSREG(3, 0, 12, 12, 4)
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
86
+#define SYSREG_ICC_DIR_EL1 SYSREG(3, 0, 12, 11, 1)
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
87
+#define SYSREG_ICC_EOIR0_EL1 SYSREG(3, 0, 12, 8, 1)
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
88
+#define SYSREG_ICC_EOIR1_EL1 SYSREG(3, 0, 12, 12, 1)
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+#define SYSREG_ICC_HPPIR0_EL1 SYSREG(3, 0, 12, 8, 2)
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
90
+#define SYSREG_ICC_HPPIR1_EL1 SYSREG(3, 0, 12, 12, 2)
76
+
91
+#define SYSREG_ICC_IAR0_EL1 SYSREG(3, 0, 12, 8, 0)
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
92
+#define SYSREG_ICC_IAR1_EL1 SYSREG(3, 0, 12, 12, 0)
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
93
+#define SYSREG_ICC_IGRPEN0_EL1 SYSREG(3, 0, 12, 12, 6)
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
94
+#define SYSREG_ICC_IGRPEN1_EL1 SYSREG(3, 0, 12, 12, 7)
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
95
+#define SYSREG_ICC_PMR_EL1 SYSREG(3, 0, 4, 6, 0)
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
96
+#define SYSREG_ICC_RPR_EL1 SYSREG(3, 0, 12, 11, 3)
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
97
+#define SYSREG_ICC_SGI0R_EL1 SYSREG(3, 0, 12, 11, 7)
83
]
98
+#define SYSREG_ICC_SGI1R_EL1 SYSREG(3, 0, 12, 11, 5)
84
99
+#define SYSREG_ICC_SRE_EL1 SYSREG(3, 0, 12, 12, 5)
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
100
+
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
101
#define WFX_IS_WFE (1 << 0)
87
+
102
88
+ # v8.1M CSEL and friends
103
#define TMR_CTL_ENABLE (1 << 0)
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
104
@@ -XXX,XX +XXX,XX @@ static bool is_id_sysreg(uint32_t reg)
105
SYSREG_CRM(reg) < 8;
90
}
106
}
91
{
107
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
108
+static uint32_t hvf_reg2cp_reg(uint32_t reg)
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
+{
109
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
110
+ return ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
111
+ (reg >> SYSREG_CRN_SHIFT) & SYSREG_CRN_MASK,
112
+ (reg >> SYSREG_CRM_SHIFT) & SYSREG_CRM_MASK,
113
+ (reg >> SYSREG_OP0_SHIFT) & SYSREG_OP0_MASK,
114
+ (reg >> SYSREG_OP1_SHIFT) & SYSREG_OP1_MASK,
115
+ (reg >> SYSREG_OP2_SHIFT) & SYSREG_OP2_MASK);
114
+}
116
+}
115
+
117
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
118
+static bool hvf_sysreg_read_cp(CPUState *cpu, uint32_t reg, uint64_t *val)
117
+{
119
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
120
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
119
+}
121
+ CPUARMState *env = &arm_cpu->env;
120
+
122
+ const ARMCPRegInfo *ri;
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
123
+
122
{
124
+ ri = get_arm_cp_reginfo(arm_cpu->cp_regs, hvf_reg2cp_reg(reg));
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
125
+ if (ri) {
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
126
+ if (ri->accessfn) {
125
{
127
+ if (ri->accessfn(env, ri, true) != CP_ACCESS_OK) {
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
128
+ return false;
127
}
129
+ }
128
+
130
+ }
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
131
+ if (ri->type & ARM_CP_CONST) {
130
+{
132
+ *val = ri->resetvalue;
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
133
+ } else if (ri->readfn) {
132
+}
134
+ *val = ri->readfn(env, ri);
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 {
135
+ } else {
182
+ val = src >> -shift;
136
+ *val = CPREG_FIELD64(env, ri);
183
+ }
137
+ }
184
+ extval = extract64(val, 0, 48);
138
+ trace_hvf_vgic_read(ri->name, *val);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
139
+ return true;
239
+ }
140
+ }
240
+
141
+
241
+ rda = tcg_temp_new_i64();
142
+ return false;
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
+}
143
+}
257
+
144
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
145
static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
146
{
147
ARMCPU *arm_cpu = ARM_CPU(cpu);
148
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
149
case SYSREG_OSDLR_EL1:
150
/* Dummy register */
151
break;
152
+ case SYSREG_ICC_AP0R0_EL1:
153
+ case SYSREG_ICC_AP0R1_EL1:
154
+ case SYSREG_ICC_AP0R2_EL1:
155
+ case SYSREG_ICC_AP0R3_EL1:
156
+ case SYSREG_ICC_AP1R0_EL1:
157
+ case SYSREG_ICC_AP1R1_EL1:
158
+ case SYSREG_ICC_AP1R2_EL1:
159
+ case SYSREG_ICC_AP1R3_EL1:
160
+ case SYSREG_ICC_ASGI1R_EL1:
161
+ case SYSREG_ICC_BPR0_EL1:
162
+ case SYSREG_ICC_BPR1_EL1:
163
+ case SYSREG_ICC_DIR_EL1:
164
+ case SYSREG_ICC_EOIR0_EL1:
165
+ case SYSREG_ICC_EOIR1_EL1:
166
+ case SYSREG_ICC_HPPIR0_EL1:
167
+ case SYSREG_ICC_HPPIR1_EL1:
168
+ case SYSREG_ICC_IAR0_EL1:
169
+ case SYSREG_ICC_IAR1_EL1:
170
+ case SYSREG_ICC_IGRPEN0_EL1:
171
+ case SYSREG_ICC_IGRPEN1_EL1:
172
+ case SYSREG_ICC_PMR_EL1:
173
+ case SYSREG_ICC_SGI0R_EL1:
174
+ case SYSREG_ICC_SGI1R_EL1:
175
+ case SYSREG_ICC_SRE_EL1:
176
+ case SYSREG_ICC_CTLR_EL1:
177
+ /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
178
+ if (!hvf_sysreg_read_cp(cpu, reg, &val)) {
179
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
180
+ }
181
+ break;
182
default:
183
if (is_id_sysreg(reg)) {
184
/* ID system registers read as RES0 */
185
@@ -XXX,XX +XXX,XX @@ static void pmswinc_write(CPUARMState *env, uint64_t value)
186
}
187
}
188
189
+static bool hvf_sysreg_write_cp(CPUState *cpu, uint32_t reg, uint64_t val)
259
+{
190
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
191
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
192
+ CPUARMState *env = &arm_cpu->env;
193
+ const ARMCPRegInfo *ri;
194
+
195
+ ri = get_arm_cp_reginfo(arm_cpu->cp_regs, hvf_reg2cp_reg(reg));
196
+
197
+ if (ri) {
198
+ if (ri->accessfn) {
199
+ if (ri->accessfn(env, ri, false) != CP_ACCESS_OK) {
200
+ return false;
201
+ }
202
+ }
203
+ if (ri->writefn) {
204
+ ri->writefn(env, ri, val);
205
+ } else {
206
+ CPREG_FIELD64(env, ri) = val;
207
+ }
208
+
209
+ trace_hvf_vgic_write(ri->name, val);
210
+ return true;
211
+ }
212
+
213
+ return false;
261
+}
214
+}
262
+
215
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
216
static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
264
+{
217
{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
218
ARMCPU *arm_cpu = ARM_CPU(cpu);
266
+}
219
@@ -XXX,XX +XXX,XX @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
267
+
220
case SYSREG_OSDLR_EL1:
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
221
/* Dummy register */
269
+{
222
break;
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
223
+ case SYSREG_ICC_AP0R0_EL1:
271
+}
224
+ case SYSREG_ICC_AP0R1_EL1:
272
+
225
+ case SYSREG_ICC_AP0R2_EL1:
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
226
+ case SYSREG_ICC_AP0R3_EL1:
274
+{
227
+ case SYSREG_ICC_AP1R0_EL1:
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
228
+ case SYSREG_ICC_AP1R1_EL1:
276
+}
229
+ case SYSREG_ICC_AP1R2_EL1:
277
+
230
+ case SYSREG_ICC_AP1R3_EL1:
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
231
+ case SYSREG_ICC_ASGI1R_EL1:
279
+{
232
+ case SYSREG_ICC_BPR0_EL1:
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
233
+ case SYSREG_ICC_BPR1_EL1:
281
+}
234
+ case SYSREG_ICC_CTLR_EL1:
282
+
235
+ case SYSREG_ICC_DIR_EL1:
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
236
+ case SYSREG_ICC_EOIR0_EL1:
284
+{
237
+ case SYSREG_ICC_EOIR1_EL1:
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
238
+ case SYSREG_ICC_HPPIR0_EL1:
286
+}
239
+ case SYSREG_ICC_HPPIR1_EL1:
287
+
240
+ case SYSREG_ICC_IAR0_EL1:
288
/*
241
+ case SYSREG_ICC_IAR1_EL1:
289
* Multiply and multiply accumulate
242
+ case SYSREG_ICC_IGRPEN0_EL1:
290
*/
243
+ case SYSREG_ICC_IGRPEN1_EL1:
244
+ case SYSREG_ICC_PMR_EL1:
245
+ case SYSREG_ICC_SGI0R_EL1:
246
+ case SYSREG_ICC_SGI1R_EL1:
247
+ case SYSREG_ICC_SRE_EL1:
248
+ /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
249
+ if (!hvf_sysreg_write_cp(cpu, reg, val)) {
250
+ hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
251
+ }
252
+ break;
253
default:
254
cpu_synchronize_state(cpu);
255
trace_hvf_unhandled_sysreg_write(env->pc, reg,
256
diff --git a/target/arm/hvf/trace-events b/target/arm/hvf/trace-events
257
index XXXXXXX..XXXXXXX 100644
258
--- a/target/arm/hvf/trace-events
259
+++ b/target/arm/hvf/trace-events
260
@@ -XXX,XX +XXX,XX @@ hvf_unknown_hvc(uint64_t x0) "unknown HVC! 0x%016"PRIx64
261
hvf_unknown_smc(uint64_t x0) "unknown SMC! 0x%016"PRIx64
262
hvf_exit(uint64_t syndrome, uint32_t ec, uint64_t pc) "exit: 0x%"PRIx64" [ec=0x%x pc=0x%"PRIx64"]"
263
hvf_psci_call(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint32_t cpuid) "PSCI Call x0=0x%016"PRIx64" x1=0x%016"PRIx64" x2=0x%016"PRIx64" x3=0x%016"PRIx64" cpu=0x%x"
264
+hvf_vgic_write(const char *name, uint64_t val) "vgic write to %s [val=0x%016"PRIx64"]"
265
+hvf_vgic_read(const char *name, uint64_t val) "vgic read from %s [val=0x%016"PRIx64"]"
291
--
266
--
292
2.20.1
267
2.34.1
293
294
diff view generated by jsdifflib
1
From: Nolan Leake <nolan@sigbus.net>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
This is just enough to make reboot and poweroff work. Works for
3
Up to now, the finalize_gic_version() code open coded what is essentially
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
4
a support bitmap match between host/emulation environment and desired
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
5
target GIC type.
6
do what linux does for reset.
6
7
7
This open coding leads to undesirable side effects. For example, a VM with
8
The watchdog timer functionality is not yet implemented.
8
KVM and -smp 10 will automatically choose GICv3 while the same command
9
9
line with TCG will stay on GICv2 and fail the launch.
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
10
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
11
This patch combines the TCG and KVM matching code paths by making
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
everything a 2 pass process. First, we determine which GIC versions the
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
current environment is able to support, then we go through a single
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
14
state machine to determine which target GIC mode that means for us.
15
[PMM: tweaked commit title; fixed region size to 0x200;
15
16
moved header file to include/]
16
After this patch, the only user noticable changes should be consolidated
17
error messages as well as TCG -M virt supporting -smp > 8 automatically.
18
19
Signed-off-by: Alexander Graf <agraf@csgraf.de>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
22
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
23
Message-id: 20221223090107.98888-2-agraf@csgraf.de
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
25
---
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
26
include/hw/arm/virt.h | 15 ++--
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
27
hw/arm/virt.c | 198 ++++++++++++++++++++++--------------------
21
hw/arm/bcm2835_peripherals.c | 13 ++-
28
2 files changed, 112 insertions(+), 101 deletions(-)
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
29
23
hw/misc/meson.build | 1 +
30
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
29
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
32
--- a/include/hw/arm/virt.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
33
+++ b/include/hw/arm/virt.h
32
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ typedef enum VirtMSIControllerType {
33
#include "hw/misc/bcm2835_mphi.h"
35
} VirtMSIControllerType;
34
#include "hw/misc/bcm2835_thermal.h"
36
35
#include "hw/misc/bcm2835_cprman.h"
37
typedef enum VirtGICType {
36
+#include "hw/misc/bcm2835_powermgt.h"
38
- VIRT_GIC_VERSION_MAX,
37
#include "hw/sd/sdhci.h"
39
- VIRT_GIC_VERSION_HOST,
38
#include "hw/sd/bcm2835_sdhost.h"
40
- VIRT_GIC_VERSION_2,
39
#include "hw/gpio/bcm2835_gpio.h"
41
- VIRT_GIC_VERSION_3,
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
42
- VIRT_GIC_VERSION_4,
41
BCM2835MphiState mphi;
43
+ VIRT_GIC_VERSION_MAX = 0,
42
UnimplementedDeviceState txp;
44
+ VIRT_GIC_VERSION_HOST = 1,
43
UnimplementedDeviceState armtmr;
45
+ /* The concrete GIC values have to match the GIC version number */
44
- UnimplementedDeviceState powermgt;
46
+ VIRT_GIC_VERSION_2 = 2,
45
+ BCM2835PowerMgtState powermgt;
47
+ VIRT_GIC_VERSION_3 = 3,
46
BCM2835CprmanState cprman;
48
+ VIRT_GIC_VERSION_4 = 4,
47
PL011State uart0;
49
VIRT_GIC_VERSION_NOSEL,
48
BCM2835AuxState aux;
50
} VirtGICType;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
51
50
new file mode 100644
52
+#define VIRT_GIC_VERSION_2_MASK BIT(VIRT_GIC_VERSION_2)
51
index XXXXXXX..XXXXXXX
53
+#define VIRT_GIC_VERSION_3_MASK BIT(VIRT_GIC_VERSION_3)
52
--- /dev/null
54
+#define VIRT_GIC_VERSION_4_MASK BIT(VIRT_GIC_VERSION_4)
53
+++ b/include/hw/misc/bcm2835_powermgt.h
55
+
54
@@ -XXX,XX +XXX,XX @@
56
struct VirtMachineClass {
55
+/*
57
MachineClass parent;
56
+ * BCM2835 Power Management emulation
58
bool disallow_affinity_adjustment;
57
+ *
59
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
63
+ */
64
+
65
+#ifndef BCM2835_POWERMGT_H
66
+#define BCM2835_POWERMGT_H
67
+
68
+#include "hw/sysbus.h"
69
+#include "qom/object.h"
70
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
73
+
74
+struct BCM2835PowerMgtState {
75
+ SysBusDevice busdev;
76
+ MemoryRegion iomem;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
85
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
61
--- a/hw/arm/virt.c
87
+++ b/hw/arm/bcm2835_peripherals.c
62
+++ b/hw/arm/virt.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
63
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
89
64
}
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
}
65
}
97
66
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
67
+static VirtGICType finalize_gic_version_do(const char *accel_name,
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
68
+ VirtGICType gic_version,
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
69
+ int gics_supported,
101
INTERRUPT_USB));
70
+ unsigned int max_cpus)
102
71
+{
103
+ /* Power Management */
72
+ /* Convert host/max/nosel to GIC version number */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
73
+ switch (gic_version) {
105
+ return;
74
+ case VIRT_GIC_VERSION_HOST:
75
+ if (!kvm_enabled()) {
76
+ error_report("gic-version=host requires KVM");
77
+ exit(1);
78
+ }
79
+
80
+ /* For KVM, gic-version=host means gic-version=max */
81
+ return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX,
82
+ gics_supported, max_cpus);
83
+ case VIRT_GIC_VERSION_MAX:
84
+ if (gics_supported & VIRT_GIC_VERSION_4_MASK) {
85
+ gic_version = VIRT_GIC_VERSION_4;
86
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
87
+ gic_version = VIRT_GIC_VERSION_3;
88
+ } else {
89
+ gic_version = VIRT_GIC_VERSION_2;
90
+ }
91
+ break;
92
+ case VIRT_GIC_VERSION_NOSEL:
93
+ if ((gics_supported & VIRT_GIC_VERSION_2_MASK) &&
94
+ max_cpus <= GIC_NCPU) {
95
+ gic_version = VIRT_GIC_VERSION_2;
96
+ } else if (gics_supported & VIRT_GIC_VERSION_3_MASK) {
97
+ /*
98
+ * in case the host does not support v2 emulation or
99
+ * the end-user requested more than 8 VCPUs we now default
100
+ * to v3. In any case defaulting to v2 would be broken.
101
+ */
102
+ gic_version = VIRT_GIC_VERSION_3;
103
+ } else if (max_cpus > GIC_NCPU) {
104
+ error_report("%s only supports GICv2 emulation but more than 8 "
105
+ "vcpus are requested", accel_name);
106
+ exit(1);
107
+ }
108
+ break;
109
+ case VIRT_GIC_VERSION_2:
110
+ case VIRT_GIC_VERSION_3:
111
+ case VIRT_GIC_VERSION_4:
112
+ break;
106
+ }
113
+ }
107
+
114
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
115
+ /* Check chosen version is effectively supported */
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
116
+ switch (gic_version) {
110
+
117
+ case VIRT_GIC_VERSION_2:
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
118
+ if (!(gics_supported & VIRT_GIC_VERSION_2_MASK)) {
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
119
+ error_report("%s does not support GICv2 emulation", accel_name);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
120
+ exit(1);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
121
+ }
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
122
+ break;
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
123
+ case VIRT_GIC_VERSION_3:
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
124
+ if (!(gics_supported & VIRT_GIC_VERSION_3_MASK)) {
118
new file mode 100644
125
+ error_report("%s does not support GICv3 emulation", accel_name);
119
index XXXXXXX..XXXXXXX
126
+ exit(1);
120
--- /dev/null
127
+ }
121
+++ b/hw/misc/bcm2835_powermgt.c
128
+ break;
122
@@ -XXX,XX +XXX,XX @@
129
+ case VIRT_GIC_VERSION_4:
123
+/*
130
+ if (!(gics_supported & VIRT_GIC_VERSION_4_MASK)) {
124
+ * BCM2835 Power Management emulation
131
+ error_report("%s does not support GICv4 emulation, is virtualization=on?",
125
+ *
132
+ accel_name);
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
133
+ exit(1);
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
134
+ }
128
+ *
135
+ break;
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
136
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
137
+ error_report("logic error in finalize_gic_version");
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
138
+ exit(1);
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
139
+ break;
172
+ }
140
+ }
173
+
141
+
174
+ return res;
142
+ return gic_version;
175
+}
143
+}
176
+
144
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
145
/*
178
+ uint64_t value, unsigned size)
146
* finalize_gic_version - Determines the final gic_version
179
+{
147
* according to the gic-version property
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
148
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
181
+
149
*/
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
150
static void finalize_gic_version(VirtMachineState *vms)
183
+ qemu_log_mask(LOG_GUEST_ERROR,
151
{
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
152
+ const char *accel_name = current_accel_name();
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
153
unsigned int max_cpus = MACHINE(vms)->smp.max_cpus;
186
+ value, offset);
154
+ int gics_supported = 0;
187
+ return;
155
188
+ }
156
- if (kvm_enabled()) {
189
+
157
- int probe_bitmap;
190
+ value = value & ~PASSWORD_MASK;
158
+ /* Determine which GIC versions the current environment supports */
191
+
159
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
192
+ switch (offset) {
160
+ int probe_bitmap = kvm_arm_vgic_probe();
193
+ case R_RSTC:
161
194
+ s->rstc = value;
162
- if (!kvm_irqchip_in_kernel()) {
195
+ if (value & V_RSTC_RESET) {
163
- switch (vms->gic_version) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
164
- case VIRT_GIC_VERSION_HOST:
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
165
- warn_report(
198
+ } else {
166
- "gic-version=host not relevant with kernel-irqchip=off "
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
167
- "as only userspace GICv2 is supported. Using v2 ...");
200
+ }
168
- return;
201
+ }
169
- case VIRT_GIC_VERSION_MAX:
202
+ break;
170
- case VIRT_GIC_VERSION_NOSEL:
203
+ case R_RSTS:
171
- vms->gic_version = VIRT_GIC_VERSION_2;
204
+ qemu_log_mask(LOG_UNIMP,
172
- return;
205
+ "bcm2835_powermgt_write: RSTS\n");
173
- case VIRT_GIC_VERSION_2:
206
+ s->rsts = value;
174
- return;
207
+ break;
175
- case VIRT_GIC_VERSION_3:
208
+ case R_WDOG:
176
- error_report(
209
+ qemu_log_mask(LOG_UNIMP,
177
- "gic-version=3 is not supported with kernel-irqchip=off");
210
+ "bcm2835_powermgt_write: WDOG\n");
178
- exit(1);
211
+ s->wdog = value;
179
- case VIRT_GIC_VERSION_4:
212
+ break;
180
- error_report(
213
+
181
- "gic-version=4 is not supported with kernel-irqchip=off");
214
+ default:
182
- exit(1);
215
+ qemu_log_mask(LOG_UNIMP,
183
- }
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
184
- }
217
+ "\n", offset);
185
-
218
+ break;
186
- probe_bitmap = kvm_arm_vgic_probe();
219
+ }
187
if (!probe_bitmap) {
220
+}
188
error_report("Unable to determine GIC version supported by host");
221
+
189
exit(1);
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
190
}
223
+ .read = bcm2835_powermgt_read,
191
224
+ .write = bcm2835_powermgt_write,
192
- switch (vms->gic_version) {
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
193
- case VIRT_GIC_VERSION_HOST:
226
+ .impl.min_access_size = 4,
194
- case VIRT_GIC_VERSION_MAX:
227
+ .impl.max_access_size = 4,
195
- if (probe_bitmap & KVM_ARM_VGIC_V3) {
228
+};
196
- vms->gic_version = VIRT_GIC_VERSION_3;
229
+
197
- } else {
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
198
- vms->gic_version = VIRT_GIC_VERSION_2;
231
+ .name = TYPE_BCM2835_POWERMGT,
199
- }
232
+ .version_id = 1,
200
- return;
233
+ .minimum_version_id = 1,
201
- case VIRT_GIC_VERSION_NOSEL:
234
+ .fields = (VMStateField[]) {
202
- if ((probe_bitmap & KVM_ARM_VGIC_V2) && max_cpus <= GIC_NCPU) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
203
- vms->gic_version = VIRT_GIC_VERSION_2;
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
204
- } else if (probe_bitmap & KVM_ARM_VGIC_V3) {
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
205
- /*
238
+ VMSTATE_END_OF_LIST()
206
- * in case the host does not support v2 in-kernel emulation or
239
+ }
207
- * the end-user requested more than 8 VCPUs we now default
240
+};
208
- * to v3. In any case defaulting to v2 would be broken.
241
+
209
- */
242
+static void bcm2835_powermgt_init(Object *obj)
210
- vms->gic_version = VIRT_GIC_VERSION_3;
243
+{
211
- } else if (max_cpus > GIC_NCPU) {
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
212
- error_report("host only supports in-kernel GICv2 emulation "
245
+
213
- "but more than 8 vcpus are requested");
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
214
- exit(1);
247
+ TYPE_BCM2835_POWERMGT, 0x200);
215
- }
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
216
- break;
249
+}
217
- case VIRT_GIC_VERSION_2:
250
+
218
- case VIRT_GIC_VERSION_3:
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
219
- break;
252
+{
220
- case VIRT_GIC_VERSION_4:
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
221
- error_report("gic-version=4 is not supported with KVM");
254
+
222
- exit(1);
255
+ /* https://elinux.org/BCM2835_registers#PM */
223
+ if (probe_bitmap & KVM_ARM_VGIC_V2) {
256
+ s->rstc = 0x00000102;
224
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
257
+ s->rsts = 0x00001000;
225
}
258
+ s->wdog = 0x00000000;
226
-
259
+}
227
- /* Check chosen version is effectively supported by the host */
260
+
228
- if (vms->gic_version == VIRT_GIC_VERSION_2 &&
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
229
- !(probe_bitmap & KVM_ARM_VGIC_V2)) {
262
+{
230
- error_report("host does not support in-kernel GICv2 emulation");
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
231
- exit(1);
264
+
232
- } else if (vms->gic_version == VIRT_GIC_VERSION_3 &&
265
+ dc->reset = bcm2835_powermgt_reset;
233
- !(probe_bitmap & KVM_ARM_VGIC_V3)) {
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
234
- error_report("host does not support in-kernel GICv3 emulation");
267
+}
235
- exit(1);
268
+
236
+ if (probe_bitmap & KVM_ARM_VGIC_V3) {
269
+static TypeInfo bcm2835_powermgt_info = {
237
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
270
+ .name = TYPE_BCM2835_POWERMGT,
238
}
271
+ .parent = TYPE_SYS_BUS_DEVICE,
239
- return;
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
240
- }
273
+ .class_init = bcm2835_powermgt_class_init,
241
-
274
+ .instance_init = bcm2835_powermgt_init,
242
- /* TCG mode */
275
+};
243
- switch (vms->gic_version) {
276
+
244
- case VIRT_GIC_VERSION_NOSEL:
277
+static void bcm2835_powermgt_register_types(void)
245
- vms->gic_version = VIRT_GIC_VERSION_2;
278
+{
246
- break;
279
+ type_register_static(&bcm2835_powermgt_info);
247
- case VIRT_GIC_VERSION_MAX:
280
+}
248
+ } else if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
281
+
249
+ /* KVM w/o kernel irqchip can only deal with GICv2 */
282
+type_init(bcm2835_powermgt_register_types)
250
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
251
+ accel_name = "KVM with kernel-irqchip=off";
284
index XXXXXXX..XXXXXXX 100644
252
+ } else {
285
--- a/hw/misc/meson.build
253
+ gics_supported |= VIRT_GIC_VERSION_2_MASK;
286
+++ b/hw/misc/meson.build
254
if (module_object_class_by_name("arm-gicv3")) {
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
255
- /* CONFIG_ARM_GICV3_TCG was set */
288
'bcm2835_rng.c',
256
+ gics_supported |= VIRT_GIC_VERSION_3_MASK;
289
'bcm2835_thermal.c',
257
if (vms->virt) {
290
'bcm2835_cprman.c',
258
/* GICv4 only makes sense if CPU has EL2 */
291
+ 'bcm2835_powermgt.c',
259
- vms->gic_version = VIRT_GIC_VERSION_4;
292
))
260
- } else {
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
261
- vms->gic_version = VIRT_GIC_VERSION_3;
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
262
+ gics_supported |= VIRT_GIC_VERSION_4_MASK;
263
}
264
- } else {
265
- vms->gic_version = VIRT_GIC_VERSION_2;
266
}
267
- break;
268
- case VIRT_GIC_VERSION_HOST:
269
- error_report("gic-version=host requires KVM");
270
- exit(1);
271
- case VIRT_GIC_VERSION_4:
272
- if (!vms->virt) {
273
- error_report("gic-version=4 requires virtualization enabled");
274
- exit(1);
275
- }
276
- break;
277
- case VIRT_GIC_VERSION_2:
278
- case VIRT_GIC_VERSION_3:
279
- break;
280
}
281
+
282
+ /*
283
+ * Then convert helpers like host/max to concrete GIC versions and ensure
284
+ * the desired version is supported
285
+ */
286
+ vms->gic_version = finalize_gic_version_do(accel_name, vms->gic_version,
287
+ gics_supported, max_cpus);
288
}
289
290
/*
295
--
291
--
296
2.20.1
292
2.34.1
297
298
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Add line item reference to quanta-gbs-bmc machine.
3
Let's explicitly list out all accelerators that we support when trying to
4
determine the supported set of GIC versions. KVM was already separate, so
5
the only missing one is HVF which simply reuses all of TCG's emulation
6
code and thus has the same compatibility matrix.
4
7
5
Signed-off-by: Patrick Venture <venture@google.com>
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
10
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
8
[PMM: fixed underline Sphinx warning]
11
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221223090107.98888-3-agraf@csgraf.de
14
[PMM: Added qtest to the list of accelerators]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
docs/system/arm/nuvoton.rst | 5 +++--
17
hw/arm/virt.c | 7 ++++++-
12
1 file changed, 3 insertions(+), 2 deletions(-)
18
1 file changed, 6 insertions(+), 1 deletion(-)
13
19
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/nuvoton.rst
22
--- a/hw/arm/virt.c
17
+++ b/docs/system/arm/nuvoton.rst
23
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
25
#include "sysemu/numa.h"
20
-=====================================================
26
#include "sysemu/runstate.h"
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
27
#include "sysemu/tpm.h"
22
+================================================================
28
+#include "sysemu/tcg.h"
23
29
#include "sysemu/kvm.h"
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
30
#include "sysemu/hvf.h"
25
designed to be used as Baseboard Management Controllers (BMCs) in various
31
+#include "sysemu/qtest.h"
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
32
#include "hw/loader.h"
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
33
#include "qapi/error.h"
28
Hyperscale applications. The following machines are based on this chip :
34
#include "qemu/bitops.h"
29
35
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
36
/* KVM w/o kernel irqchip can only deal with GICv2 */
31
- ``quanta-gsj`` Quanta GSJ server BMC
37
gics_supported |= VIRT_GIC_VERSION_2_MASK;
32
38
accel_name = "KVM with kernel-irqchip=off";
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
39
- } else {
40
+ } else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) {
41
gics_supported |= VIRT_GIC_VERSION_2_MASK;
42
if (module_object_class_by_name("arm-gicv3")) {
43
gics_supported |= VIRT_GIC_VERSION_3_MASK;
44
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
45
gics_supported |= VIRT_GIC_VERSION_4_MASK;
46
}
47
}
48
+ } else {
49
+ error_report("Unsupported accelerator, can not determine GIC support");
50
+ exit(1);
51
}
52
53
/*
34
--
54
--
35
2.20.1
55
2.34.1
36
56
37
57
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
3
Cortex-A76 supports 40bits of address space. sbsa-ref's memory
4
entry.
4
starts above this limit.
5
5
6
Signed-off-by: Patrick Venture <venture@google.com>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230126114416.2447685-1-marcin.juszkiewicz@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
docs/system/arm/aspeed.rst | 1 +
12
hw/arm/sbsa-ref.c | 1 -
12
1 file changed, 1 insertion(+)
13
1 file changed, 1 deletion(-)
13
14
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
--- a/hw/arm/sbsa-ref.c
17
+++ b/docs/system/arm/aspeed.rst
18
+++ b/hw/arm/sbsa-ref.c
18
@@ -XXX,XX +XXX,XX @@ etc.
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
19
AST2400 SoC based machines :
20
static const char * const valid_cpus[] = {
20
21
ARM_CPU_TYPE_NAME("cortex-a57"),
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
22
ARM_CPU_TYPE_NAME("cortex-a72"),
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
23
- ARM_CPU_TYPE_NAME("cortex-a76"),
23
24
ARM_CPU_TYPE_NAME("neoverse-n1"),
24
AST2500 SoC based machines :
25
ARM_CPU_TYPE_NAME("max"),
25
26
};
26
--
27
--
27
2.20.1
28
2.34.1
28
29
29
30
diff view generated by jsdifflib
New patch
1
The encodings 0,0,C7,C9,0 and 0,0,C7,C9,1 are AT SP1E1RP and AT
2
S1E1WP, but our ARMCPRegInfo definitions for them incorrectly name
3
them AT S1E1R and AT S1E1W (which are entirely different
4
instructions). Fix the names.
1
5
6
(This has no guest-visible effect as the names are for debug purposes
7
only.)
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Fuad Tabba <tabba@google.com>
12
Message-id: 20230130182459.3309057-2-peter.maydell@linaro.org
13
Message-id: 20230127175507.2895013-2-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 4 ++--
16
1 file changed, 2 insertions(+), 2 deletions(-)
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 const ARMCPRegInfo vhe_reginfo[] = {
23
24
#ifndef CONFIG_USER_ONLY
25
static const ARMCPRegInfo ats1e1_reginfo[] = {
26
- { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
27
+ { .name = "AT_S1E1RP", .state = ARM_CP_STATE_AA64,
28
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
29
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
30
.writefn = ats_write64 },
31
- { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
32
+ { .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
33
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
34
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
35
.writefn = ats_write64 },
36
--
37
2.34.1
diff view generated by jsdifflib
New patch
1
The AArch32 ATS12NSO* address translation operations are supposed to
2
trap to either EL2 or EL3 if they're executed at Secure EL1 (which
3
can only happen if EL3 is AArch64). We implement this, but we got
4
the syndrome value wrong: like other traps to EL2 or EL3 on an
5
AArch32 cpreg access, they should report the 0x3 syndrome, not the
6
0x0 'uncategorized' syndrome. This is clear in the access pseudocode
7
for these instructions.
1
8
9
Fix the syndrome value for these operations by correcting the
10
returned value from the ats_access() function.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Fuad Tabba <tabba@google.com>
15
Message-id: 20230130182459.3309057-3-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-3-peter.maydell@linaro.org
17
---
18
target/arm/helper.c | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
26
if (arm_current_el(env) == 1) {
27
if (arm_is_secure_below_el3(env)) {
28
if (env->cp15.scr_el3 & SCR_EEL2) {
29
- return CP_ACCESS_TRAP_UNCATEGORIZED_EL2;
30
+ return CP_ACCESS_TRAP_EL2;
31
}
32
- return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
33
+ return CP_ACCESS_TRAP_EL3;
34
}
35
return CP_ACCESS_TRAP_UNCATEGORIZED;
36
}
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
We added the CPAccessResult values CP_ACCESS_TRAP_UNCATEGORIZED_EL2
2
and CP_ACCESS_TRAP_UNCATEGORIZED_EL3 purely in order to use them in
3
the ats_access() function, but doing so was incorrect (a bug fixed in
4
a previous commit). There aren't any cases where we want an access
5
function to be able to request a trap to EL2 or EL3 with a zero
6
syndrome value, so remove these enum values.
1
7
8
As well as cleaning up dead code, the motivation here is that
9
we'd like to implement fine-grained-trap handling in
10
helper_access_check_cp_reg(). Although the fine-grained traps
11
to EL2 are always lower priority than trap-to-same-EL and
12
higher priority than trap-to-EL3, they are in the middle of
13
various other kinds of trap-to-EL2. Knowing that a trap-to-EL2
14
must always for us have the same syndrome (ie that an access
15
function will return CP_ACCESS_TRAP_EL2 and there is no other
16
kind of trap-to-EL2 enum value) means we don't have to try
17
to choose which of the two syndrome values to report if the
18
access would trap to EL2 both for the fine-grained-trap and
19
because the access function requires it.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Tested-by: Fuad Tabba <tabba@google.com>
24
Message-id: 20230130182459.3309057-4-peter.maydell@linaro.org
25
Message-id: 20230127175507.2895013-4-peter.maydell@linaro.org
26
---
27
target/arm/cpregs.h | 4 ++--
28
target/arm/op_helper.c | 2 ++
29
2 files changed, 4 insertions(+), 2 deletions(-)
30
31
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpregs.h
34
+++ b/target/arm/cpregs.h
35
@@ -XXX,XX +XXX,XX @@ typedef enum CPAccessResult {
36
* Access fails and results in an exception syndrome 0x0 ("uncategorized").
37
* Note that this is not a catch-all case -- the set of cases which may
38
* result in this failure is specifically defined by the architecture.
39
+ * This trap is always to the usual target EL, never directly to a
40
+ * specified target EL.
41
*/
42
CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
43
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2,
44
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3,
45
} CPAccessResult;
46
47
typedef struct ARMCPRegInfo ARMCPRegInfo;
48
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/op_helper.c
51
+++ b/target/arm/op_helper.c
52
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
53
case CP_ACCESS_TRAP:
54
break;
55
case CP_ACCESS_TRAP_UNCATEGORIZED:
56
+ /* Only CP_ACCESS_TRAP traps are direct to a specified EL */
57
+ assert((res & CP_ACCESS_EL_MASK) == 0);
58
if (cpu_isar_feature(aa64_ids, cpu) && isread &&
59
arm_cpreg_in_idspace(ri)) {
60
/*
61
--
62
2.34.1
diff view generated by jsdifflib
1
The function asimd_imm_const() in translate-neon.c is an
1
Rearrange the code in do_coproc_insn() so that we calculate the
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
2
syndrome value for a potential trap early; we're about to add a
3
also want for MVE. Move the implementation to translate.c, with a
3
second check that wants this value earlier than where it is currently
4
prototype in translate.h.
4
determined.
5
6
(Specifically, a trap to EL2 because of HSTR_EL2 should take
7
priority over an UNDEF to EL1, even when the UNDEF is because
8
the register does not exist at all or because its ri->access
9
bits non-configurably fail the access. So the check we put in
10
for HSTR_EL2 trapping at EL1 (which needs the syndrome) is
11
going to have to be done before the check "is the ARMCPRegInfo
12
pointer NULL".)
13
14
This commit is just code motion; the change to HSTR_EL2
15
handling that will use the 'syndrome' variable is in a
16
subsequent commit.
5
17
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
20
Tested-by: Fuad Tabba <tabba@google.com>
21
Message-id: 20230130182459.3309057-5-peter.maydell@linaro.org
22
Message-id: 20230127175507.2895013-5-peter.maydell@linaro.org
9
---
23
---
10
target/arm/translate.h | 16 ++++++++++
24
target/arm/translate.c | 83 +++++++++++++++++++++---------------------
11
target/arm/translate-neon.c | 63 -------------------------------------
25
1 file changed, 41 insertions(+), 42 deletions(-)
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
14
26
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
20
return opc | s->be_data;
21
}
22
23
+/**
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
25
+ *
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
29
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
30
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
31
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
119
a64_translate_init();
32
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
120
}
33
TCGv_ptr tcg_ri = NULL;
121
34
bool need_exit_tb;
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
35
+ uint32_t syndrome;
123
+{
36
+
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
37
+ /*
125
+ switch (cmode) {
38
+ * Note that since we are an implementation which takes an
126
+ case 0: case 1:
39
+ * exception on a trapped conditional instruction only if the
127
+ /* no-op */
40
+ * instruction passes its condition code check, we can take
128
+ break;
41
+ * advantage of the clause in the ARM ARM that allows us to set
129
+ case 2: case 3:
42
+ * the COND field in the instruction to 0xE in all cases.
130
+ imm <<= 8;
43
+ * We could fish the actual condition out of the insn (ARM)
131
+ break;
44
+ * or the condexec bits (Thumb) but it isn't necessary.
132
+ case 4: case 5:
45
+ */
133
+ imm <<= 16;
46
+ switch (cpnum) {
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:
47
+ case 14:
151
+ if (op) {
48
+ if (is64) {
152
+ /*
49
+ syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
153
+ * This is the only case where the top and bottom 32 bits
50
+ isread, false);
154
+ * of the encoded constant differ.
51
+ } else {
155
+ */
52
+ syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
156
+ uint64_t imm64 = 0;
53
+ rt, isread, false);
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
+ }
54
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
55
+ break;
168
+ case 15:
56
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
57
+ if (is64) {
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
58
+ syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
59
+ isread, false);
60
+ } else {
61
+ syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
62
+ rt, isread, false);
63
+ }
64
+ break;
65
+ default:
66
+ /*
67
+ * ARMv8 defines that only coprocessors 14 and 15 exist,
68
+ * so this can only happen if this is an ARMv7 or earlier CPU,
69
+ * in which case the syndrome information won't actually be
70
+ * guest visible.
71
+ */
72
+ assert(!arm_dc_feature(s, ARM_FEATURE_V8));
73
+ syndrome = syn_uncategorized();
171
+ break;
74
+ break;
172
+ }
75
+ }
173
+ if (op) {
76
174
+ imm = ~imm;
77
if (!ri) {
175
+ }
78
/*
176
+ return dup_const(MO_32, imm);
79
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
177
+}
80
* Note that on XScale all cp0..c13 registers do an access check
178
+
81
* call in order to handle c15_cpar.
179
/* Generate a label used for skipping this instruction */
82
*/
180
void arm_gen_condlabel(DisasContext *s)
83
- uint32_t syndrome;
181
{
84
-
85
- /*
86
- * Note that since we are an implementation which takes an
87
- * exception on a trapped conditional instruction only if the
88
- * instruction passes its condition code check, we can take
89
- * advantage of the clause in the ARM ARM that allows us to set
90
- * the COND field in the instruction to 0xE in all cases.
91
- * We could fish the actual condition out of the insn (ARM)
92
- * or the condexec bits (Thumb) but it isn't necessary.
93
- */
94
- switch (cpnum) {
95
- case 14:
96
- if (is64) {
97
- syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
98
- isread, false);
99
- } else {
100
- syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
101
- rt, isread, false);
102
- }
103
- break;
104
- case 15:
105
- if (is64) {
106
- syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
107
- isread, false);
108
- } else {
109
- syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
110
- rt, isread, false);
111
- }
112
- break;
113
- default:
114
- /*
115
- * ARMv8 defines that only coprocessors 14 and 15 exist,
116
- * so this can only happen if this is an ARMv7 or earlier CPU,
117
- * in which case the syndrome information won't actually be
118
- * guest visible.
119
- */
120
- assert(!arm_dc_feature(s, ARM_FEATURE_V8));
121
- syndrome = syn_uncategorized();
122
- break;
123
- }
124
-
125
gen_set_condexec(s);
126
gen_update_pc(s, 0);
127
tcg_ri = tcg_temp_new_ptr();
182
--
128
--
183
2.20.1
129
2.34.1
184
185
diff view generated by jsdifflib
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
1
The HSTR_EL2 register has a collection of trap bits which allow
2
that it accumulates 32-bit elements into a 64-bit accumulator
2
trapping to EL2 for AArch32 EL0 or EL1 accesses to coprocessor
3
stored in a pair of general-purpose registers.
3
registers. The specification of these bits is that when the bit is
4
set we should trap
5
* EL1 accesses
6
* EL0 accesses, if the access is not UNDEFINED when the
7
trap bit is 0
8
9
In other words, all UNDEF traps from EL0 to EL1 take precedence over
10
the HSTR_EL2 trap to EL2. (Since this is all AArch32, the only kind
11
of trap-to-EL1 is the UNDEF.)
12
13
Our implementation doesn't quite get this right -- we check for traps
14
in the order:
15
* no such register
16
* ARMCPRegInfo::access bits
17
* HSTR_EL2 trap bits
18
* ARMCPRegInfo::accessfn
19
20
So UNDEFs that happen because of the access bits or because the
21
register doesn't exist at all correctly take priority over the
22
HSTR_EL2 trap, but where a register can UNDEF at EL0 because of the
23
accessfn we are incorrectly always taking the HSTR_EL2 trap. There
24
aren't many of these, but one example is the PMCR; if you look at the
25
access pseudocode for this register you can see that UNDEFs taken
26
because of the value of PMUSERENR.EN are checked before the HSTR_EL2
27
bit.
28
29
Rearrange helper_access_check_cp_reg() so that we always call the
30
accessfn, and use its return value if it indicates that the access
31
traps to EL0 rather than continuing to do the HSTR_EL2 check.
4
32
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
35
Tested-by: Fuad Tabba <tabba@google.com>
36
Message-id: 20230130182459.3309057-6-peter.maydell@linaro.org
37
Message-id: 20230127175507.2895013-6-peter.maydell@linaro.org
8
---
38
---
9
target/arm/helper-mve.h | 3 ++
39
target/arm/op_helper.c | 21 ++++++++++++++++-----
10
target/arm/mve.decode | 6 +++-
40
1 file changed, 16 insertions(+), 5 deletions(-)
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
14
41
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
42
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
44
--- a/target/arm/op_helper.c
18
+++ b/target/arm/helper-mve.h
45
+++ b/target/arm/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
46
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
47
goto fail;
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
48
}
22
49
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
50
+ if (ri->accessfn) {
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
51
+ res = ri->accessfn(env, ri, isread);
25
+
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
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;
95
+
96
+ if (!dc_isar_feature(aa32_mve, s)) {
97
+ return false;
98
+ }
99
+ /*
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
104
+ return false;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
107
+ return true;
108
+ }
52
+ }
109
+
53
+
110
+ /*
54
/*
111
+ * This insn is subject to beat-wise execution. Partial execution
55
- * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
56
- * to sysregs non accessible at EL0 to have UNDEF-ed already.
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
57
+ * If the access function indicates a trap from EL0 to EL1 then
114
+ */
58
+ * that always takes priority over the HSTR_EL2 trap. (If it indicates
115
+ if (a->a || mve_skip_first_beat(s)) {
59
+ * a trap to EL3, then the HSTR_EL2 trap takes priority; if it indicates
116
+ /* Accumulate input from RdaHi:RdaLo */
60
+ * a trap to EL2, then the syndrome is the same either way so we don't
117
+ rda = tcg_temp_new_i64();
61
+ * care whether technically the architecture says that HSTR_EL2 trap or
118
+ rdalo = load_reg(s, a->rdalo);
62
+ * the other trap takes priority. So we take the "check HSTR_EL2" path
119
+ rdahi = load_reg(s, a->rdahi);
63
+ * for all of those cases.)
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
64
*/
121
+ tcg_temp_free_i32(rdalo);
65
+ if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) == 0) &&
122
+ tcg_temp_free_i32(rdahi);
66
+ arm_current_el(env) == 0) {
123
+ } else {
67
+ goto fail;
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
126
+ }
68
+ }
127
+
69
+
128
+ qm = mve_qreg_ptr(a->qm);
70
if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
129
+ if (a->u) {
71
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
72
uint32_t mask = 1 << ri->crn;
131
+ } else {
73
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
74
}
133
+ }
75
}
134
+ tcg_temp_free_ptr(qm);
76
135
+
77
- if (ri->accessfn) {
136
+ rdalo = tcg_temp_new_i32();
78
- res = ri->accessfn(env, ri, isread);
137
+ rdahi = tcg_temp_new_i32();
79
- }
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
80
if (likely(res == CP_ACCESS_OK)) {
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
81
return ri;
140
+ store_reg(s, a->rdalo, rdalo);
82
}
141
+ store_reg(s, a->rdahi, rdahi);
142
+ tcg_temp_free_i64(rda);
143
+ mve_update_eci(s);
144
+ return true;
145
+}
146
+
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
148
{
149
TCGv_ptr qd;
150
--
83
--
151
2.20.1
84
2.34.1
152
153
diff view generated by jsdifflib
1
Implement the MVE shifts by register, which perform
1
The semantics of HSTR_EL2 require that it traps cpreg accesses
2
shifts on a single general-purpose register.
2
to EL2 for:
3
* EL1 accesses
4
* EL0 accesses, if the access is not UNDEFINED when the
5
trap bit is 0
6
7
(You can see this in the I_ZFGJP priority ordering, where HSTR_EL2
8
traps from EL1 to EL2 are priority 12, UNDEFs are priority 13, and
9
HSTR_EL2 traps from EL0 are priority 15.)
10
11
However, we don't get this right for EL1 accesses which UNDEF because
12
the register doesn't exist at all or because its ri->access bits
13
non-configurably forbid the access. At EL1, check for the HSTR_EL2
14
trap early, before either of these UNDEF reasons.
15
16
We have to retain the HSTR_EL2 check in access_check_cp_reg(),
17
because at EL0 any kind of UNDEF-to-EL1 (including "no such
18
register", "bad ri->access" and "ri->accessfn returns 'trap to EL1'")
19
takes precedence over the trap to EL2. But we only need to do that
20
check for EL0 now.
3
21
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Tested-by: Fuad Tabba <tabba@google.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
25
Message-id: 20230130182459.3309057-7-peter.maydell@linaro.org
26
Message-id: 20230127175507.2895013-7-peter.maydell@linaro.org
7
---
27
---
8
target/arm/helper-mve.h | 2 ++
28
target/arm/op_helper.c | 6 +++++-
9
target/arm/translate.h | 1 +
29
target/arm/translate.c | 28 +++++++++++++++++++++++++++-
10
target/arm/t32.decode | 18 ++++++++++++++----
30
2 files changed, 32 insertions(+), 2 deletions(-)
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
14
31
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
34
--- a/target/arm/op_helper.c
18
+++ b/target/arm/helper-mve.h
35
+++ b/target/arm/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
20
37
goto fail;
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
}
38
}
60
39
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
40
- if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
41
+ /*
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
42
+ * HSTR_EL2 traps from EL1 are checked earlier, in generated code;
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
43
+ * we only need to check here for traps from EL0.
65
+ {
44
+ */
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
45
+ if (!is_a64(env) && arm_current_el(env) == 0 && ri->cp == 15 &&
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
46
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
47
uint32_t mask = 1 << ri->crn;
69
+ }
48
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
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
51
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
52
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
53
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
54
break;
104
}
55
}
105
56
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
57
+ if (s->hstr_active && cpnum == 15 && s->current_el == 1) {
107
+{
58
+ /*
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
59
+ * At EL1, check for a HSTR_EL2 trap, which must take precedence
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
60
+ * over the UNDEF for "no such register" or the UNDEF for "access
110
+ return false;
61
+ * permissions forbid this EL1 access". HSTR_EL2 traps from EL0
111
+ }
62
+ * only happen if the cpreg doesn't UNDEF at EL0, so we do those in
112
+ if (!dc_isar_feature(aa32_mve, s) ||
63
+ * access_check_cp_reg(), after the checks for whether the access
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
64
+ * configurably trapped to EL1.
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
65
+ */
115
+ a->rm == a->rda) {
66
+ uint32_t maskbit = is64 ? crm : crn;
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
67
+
117
+ unallocated_encoding(s);
68
+ if (maskbit != 4 && maskbit != 14) {
118
+ return true;
69
+ /* T4 and T14 are RES0 so never cause traps */
70
+ TCGv_i32 t;
71
+ DisasLabel over = gen_disas_label(s);
72
+
73
+ t = load_cpu_offset(offsetoflow32(CPUARMState, cp15.hstr_el2));
74
+ tcg_gen_andi_i32(t, t, 1u << maskbit);
75
+ tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label);
76
+ tcg_temp_free_i32(t);
77
+
78
+ gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
79
+ set_disas_label(s, over);
80
+ }
119
+ }
81
+ }
120
+
82
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
83
if (!ri) {
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
84
/*
123
+ return true;
85
* Unknown register; this might be a guest error or a QEMU
124
+}
86
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
125
+
87
return;
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
88
}
127
+{
89
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
90
- if (s->hstr_active || ri->accessfn ||
129
+}
91
+ if ((s->hstr_active && s->current_el == 0) || ri->accessfn ||
130
+
92
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
93
/*
132
+{
94
* Emit code to perform further access permissions checks at
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+}
135
+
136
/*
137
* Multiply and multiply accumulate
138
*/
139
--
95
--
140
2.20.1
96
2.34.1
141
142
diff view generated by jsdifflib
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
1
The HSTR_EL2 register is not supposed to have an effect unless EL2 is
2
insns had some bugs:
2
enabled in the current security state. We weren't checking for this,
3
* the 32x32 multiply of elements was being done as 32x32->32,
3
which meant that if the guest set up the HSTR_EL2 register we would
4
not 32x32->64
4
incorrectly trap even for accesses from Secure EL0 and EL1.
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
9
5
10
In particular, fixing the second of these allows us to recast
6
Add the missing checks. (Other places where we look at HSTR_EL2
11
the implementation to avoid 128-bit arithmetic entirely.
7
for the not-in-v8A bits TTEE and TJDBX are already checking that
8
we are in NS EL0 or EL1, so there we alredy know EL2 is enabled.)
12
9
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
12
Tested-by: Fuad Tabba <tabba@google.com>
13
Message-id: 20230130182459.3309057-8-peter.maydell@linaro.org
14
Message-id: 20230127175507.2895013-8-peter.maydell@linaro.org
20
---
15
---
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
16
target/arm/helper.c | 2 +-
22
1 file changed, 21 insertions(+), 17 deletions(-)
17
target/arm/op_helper.c | 1 +
18
2 files changed, 2 insertions(+), 1 deletion(-)
23
19
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/mve_helper.c
22
--- a/target/arm/helper.c
27
+++ b/target/arm/mve_helper.c
23
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
29
*/
25
DP_TBFLAG_A32(flags, VFPEN, 1);
30
31
#include "qemu/osdep.h"
32
-#include "qemu/int128.h"
33
#include "cpu.h"
34
#include "internals.h"
35
#include "vec_internal.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
38
39
/*
40
- * Rounding multiply add long dual accumulate high: we must keep
41
- * a 72-bit internal accumulator value and return the top 64 bits.
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
26
}
82
27
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
28
- if (el < 2 && env->cp15.hstr_el2 &&
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
29
+ if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) &&
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
30
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
31
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
87
32
}
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
34
index XXXXXXX..XXXXXXX 100644
90
35
--- a/target/arm/op_helper.c
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
36
+++ b/target/arm/op_helper.c
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
37
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
38
* we only need to check here for traps from EL0.
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
39
*/
95
40
if (!is_a64(env) && arm_current_el(env) == 0 && ri->cp == 15 &&
96
/* Vector add across vector */
41
+ arm_is_el2_enabled(env) &&
97
#define DO_VADDV(OP, ESIZE, TYPE) \
42
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
43
uint32_t mask = 1 << ri->crn;
44
98
--
45
--
99
2.20.1
46
2.34.1
100
101
diff view generated by jsdifflib
1
Implement the MVE vector shift right by immediate insns VSHRI and
1
Define the system registers which are provided by the
2
VRSHRI. As with Neon, we implement these by using helper functions
2
FEAT_FGT fine-grained trap architectural feature:
3
which perform left shifts but allow negative shift counts to indicate
3
HFGRTR_EL2, HFGWTR_EL2, HDFGRTR_EL2, HDFGWTR_EL2, HFGITR_EL2
4
right shifts.
4
5
All these registers are a set of bit fields, where each bit is set
6
for a trap and clear to not trap on a particular system register
7
access. The R and W register pairs are for system registers,
8
allowing trapping to be done separately for reads and writes; the I
9
register is for system instructions where trapping is on instruction
10
execution.
11
12
The data storage in the CPU state struct is arranged as a set of
13
arrays rather than separate fields so that when we're looking up the
14
bits for a system register access we can just index into the array
15
rather than having to use a switch to select a named struct member.
16
The later FEAT_FGT2 will add extra elements to these arrays.
17
18
The field definitions for the new registers are in cpregs.h because
19
in practice the code that needs them is code that also needs
20
the cpregs information; cpu.h is included in a lot more files.
21
We're also going to add some FGT-specific definitions to cpregs.h
22
in the next commit.
23
24
We do not implement HAFGRTR_EL2, because we don't implement
25
FEAT_AMUv1.
5
26
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
29
Tested-by: Fuad Tabba <tabba@google.com>
30
Message-id: 20230130182459.3309057-9-peter.maydell@linaro.org
31
Message-id: 20230127175507.2895013-9-peter.maydell@linaro.org
9
---
32
---
10
target/arm/helper-mve.h | 12 ++++++++++++
33
target/arm/cpregs.h | 285 ++++++++++++++++++++++++++++++++++++++++++++
11
target/arm/translate.h | 20 ++++++++++++++++++++
34
target/arm/cpu.h | 15 +++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
35
target/arm/helper.c | 40 +++++++
13
target/arm/mve_helper.c | 7 +++++++
36
3 files changed, 340 insertions(+)
14
target/arm/translate-mve.c | 5 +++++
37
15
target/arm/translate-neon.c | 18 ------------------
38
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
6 files changed, 72 insertions(+), 18 deletions(-)
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
40
--- a/target/arm/cpregs.h
21
+++ b/target/arm/helper-mve.h
41
+++ b/target/arm/cpregs.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
42
@@ -XXX,XX +XXX,XX @@ typedef enum CPAccessResult {
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
43
CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
44
} CPAccessResult;
25
45
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+/* Indexes into fgt_read[] */
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+#define FGTREG_HFGRTR 0
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+#define FGTREG_HDFGRTR 1
29
+
49
+/* Indexes into fgt_write[] */
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
+#define FGTREG_HFGWTR 0
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+#define FGTREG_HDFGWTR 1
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+/* Indexes into fgt_exec[] */
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+#define FGTREG_HFGITR 0
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
+
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
+FIELD(HFGRTR_EL2, AFSR0_EL1, 0, 1)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
+FIELD(HFGRTR_EL2, AFSR1_EL1, 1, 1)
37
+
57
+FIELD(HFGRTR_EL2, AIDR_EL1, 2, 1)
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
58
+FIELD(HFGRTR_EL2, AMAIR_EL1, 3, 1)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
59
+FIELD(HFGRTR_EL2, APDAKEY, 4, 1)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
60
+FIELD(HFGRTR_EL2, APDBKEY, 5, 1)
41
+
61
+FIELD(HFGRTR_EL2, APGAKEY, 6, 1)
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
62
+FIELD(HFGRTR_EL2, APIAKEY, 7, 1)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
63
+FIELD(HFGRTR_EL2, APIBKEY, 8, 1)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
64
+FIELD(HFGRTR_EL2, CCSIDR_EL1, 9, 1)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
65
+FIELD(HFGRTR_EL2, CLIDR_EL1, 10, 1)
66
+FIELD(HFGRTR_EL2, CONTEXTIDR_EL1, 11, 1)
67
+FIELD(HFGRTR_EL2, CPACR_EL1, 12, 1)
68
+FIELD(HFGRTR_EL2, CSSELR_EL1, 13, 1)
69
+FIELD(HFGRTR_EL2, CTR_EL0, 14, 1)
70
+FIELD(HFGRTR_EL2, DCZID_EL0, 15, 1)
71
+FIELD(HFGRTR_EL2, ESR_EL1, 16, 1)
72
+FIELD(HFGRTR_EL2, FAR_EL1, 17, 1)
73
+FIELD(HFGRTR_EL2, ISR_EL1, 18, 1)
74
+FIELD(HFGRTR_EL2, LORC_EL1, 19, 1)
75
+FIELD(HFGRTR_EL2, LOREA_EL1, 20, 1)
76
+FIELD(HFGRTR_EL2, LORID_EL1, 21, 1)
77
+FIELD(HFGRTR_EL2, LORN_EL1, 22, 1)
78
+FIELD(HFGRTR_EL2, LORSA_EL1, 23, 1)
79
+FIELD(HFGRTR_EL2, MAIR_EL1, 24, 1)
80
+FIELD(HFGRTR_EL2, MIDR_EL1, 25, 1)
81
+FIELD(HFGRTR_EL2, MPIDR_EL1, 26, 1)
82
+FIELD(HFGRTR_EL2, PAR_EL1, 27, 1)
83
+FIELD(HFGRTR_EL2, REVIDR_EL1, 28, 1)
84
+FIELD(HFGRTR_EL2, SCTLR_EL1, 29, 1)
85
+FIELD(HFGRTR_EL2, SCXTNUM_EL1, 30, 1)
86
+FIELD(HFGRTR_EL2, SCXTNUM_EL0, 31, 1)
87
+FIELD(HFGRTR_EL2, TCR_EL1, 32, 1)
88
+FIELD(HFGRTR_EL2, TPIDR_EL1, 33, 1)
89
+FIELD(HFGRTR_EL2, TPIDRRO_EL0, 34, 1)
90
+FIELD(HFGRTR_EL2, TPIDR_EL0, 35, 1)
91
+FIELD(HFGRTR_EL2, TTBR0_EL1, 36, 1)
92
+FIELD(HFGRTR_EL2, TTBR1_EL1, 37, 1)
93
+FIELD(HFGRTR_EL2, VBAR_EL1, 38, 1)
94
+FIELD(HFGRTR_EL2, ICC_IGRPENN_EL1, 39, 1)
95
+FIELD(HFGRTR_EL2, ERRIDR_EL1, 40, 1)
96
+FIELD(HFGRTR_EL2, ERRSELR_EL1, 41, 1)
97
+FIELD(HFGRTR_EL2, ERXFR_EL1, 42, 1)
98
+FIELD(HFGRTR_EL2, ERXCTLR_EL1, 43, 1)
99
+FIELD(HFGRTR_EL2, ERXSTATUS_EL1, 44, 1)
100
+FIELD(HFGRTR_EL2, ERXMISCN_EL1, 45, 1)
101
+FIELD(HFGRTR_EL2, ERXPFGF_EL1, 46, 1)
102
+FIELD(HFGRTR_EL2, ERXPFGCTL_EL1, 47, 1)
103
+FIELD(HFGRTR_EL2, ERXPFGCDN_EL1, 48, 1)
104
+FIELD(HFGRTR_EL2, ERXADDR_EL1, 49, 1)
105
+FIELD(HFGRTR_EL2, NACCDATA_EL1, 50, 1)
106
+/* 51-53: RES0 */
107
+FIELD(HFGRTR_EL2, NSMPRI_EL1, 54, 1)
108
+FIELD(HFGRTR_EL2, NTPIDR2_EL0, 55, 1)
109
+/* 56-63: RES0 */
110
+
111
+/* These match HFGRTR but bits for RO registers are RES0 */
112
+FIELD(HFGWTR_EL2, AFSR0_EL1, 0, 1)
113
+FIELD(HFGWTR_EL2, AFSR1_EL1, 1, 1)
114
+FIELD(HFGWTR_EL2, AMAIR_EL1, 3, 1)
115
+FIELD(HFGWTR_EL2, APDAKEY, 4, 1)
116
+FIELD(HFGWTR_EL2, APDBKEY, 5, 1)
117
+FIELD(HFGWTR_EL2, APGAKEY, 6, 1)
118
+FIELD(HFGWTR_EL2, APIAKEY, 7, 1)
119
+FIELD(HFGWTR_EL2, APIBKEY, 8, 1)
120
+FIELD(HFGWTR_EL2, CONTEXTIDR_EL1, 11, 1)
121
+FIELD(HFGWTR_EL2, CPACR_EL1, 12, 1)
122
+FIELD(HFGWTR_EL2, CSSELR_EL1, 13, 1)
123
+FIELD(HFGWTR_EL2, ESR_EL1, 16, 1)
124
+FIELD(HFGWTR_EL2, FAR_EL1, 17, 1)
125
+FIELD(HFGWTR_EL2, LORC_EL1, 19, 1)
126
+FIELD(HFGWTR_EL2, LOREA_EL1, 20, 1)
127
+FIELD(HFGWTR_EL2, LORN_EL1, 22, 1)
128
+FIELD(HFGWTR_EL2, LORSA_EL1, 23, 1)
129
+FIELD(HFGWTR_EL2, MAIR_EL1, 24, 1)
130
+FIELD(HFGWTR_EL2, PAR_EL1, 27, 1)
131
+FIELD(HFGWTR_EL2, SCTLR_EL1, 29, 1)
132
+FIELD(HFGWTR_EL2, SCXTNUM_EL1, 30, 1)
133
+FIELD(HFGWTR_EL2, SCXTNUM_EL0, 31, 1)
134
+FIELD(HFGWTR_EL2, TCR_EL1, 32, 1)
135
+FIELD(HFGWTR_EL2, TPIDR_EL1, 33, 1)
136
+FIELD(HFGWTR_EL2, TPIDRRO_EL0, 34, 1)
137
+FIELD(HFGWTR_EL2, TPIDR_EL0, 35, 1)
138
+FIELD(HFGWTR_EL2, TTBR0_EL1, 36, 1)
139
+FIELD(HFGWTR_EL2, TTBR1_EL1, 37, 1)
140
+FIELD(HFGWTR_EL2, VBAR_EL1, 38, 1)
141
+FIELD(HFGWTR_EL2, ICC_IGRPENN_EL1, 39, 1)
142
+FIELD(HFGWTR_EL2, ERRSELR_EL1, 41, 1)
143
+FIELD(HFGWTR_EL2, ERXCTLR_EL1, 43, 1)
144
+FIELD(HFGWTR_EL2, ERXSTATUS_EL1, 44, 1)
145
+FIELD(HFGWTR_EL2, ERXMISCN_EL1, 45, 1)
146
+FIELD(HFGWTR_EL2, ERXPFGCTL_EL1, 47, 1)
147
+FIELD(HFGWTR_EL2, ERXPFGCDN_EL1, 48, 1)
148
+FIELD(HFGWTR_EL2, ERXADDR_EL1, 49, 1)
149
+FIELD(HFGWTR_EL2, NACCDATA_EL1, 50, 1)
150
+FIELD(HFGWTR_EL2, NSMPRI_EL1, 54, 1)
151
+FIELD(HFGWTR_EL2, NTPIDR2_EL0, 55, 1)
152
+
153
+FIELD(HFGITR_EL2, ICIALLUIS, 0, 1)
154
+FIELD(HFGITR_EL2, ICIALLU, 1, 1)
155
+FIELD(HFGITR_EL2, ICIVAU, 2, 1)
156
+FIELD(HFGITR_EL2, DCIVAC, 3, 1)
157
+FIELD(HFGITR_EL2, DCISW, 4, 1)
158
+FIELD(HFGITR_EL2, DCCSW, 5, 1)
159
+FIELD(HFGITR_EL2, DCCISW, 6, 1)
160
+FIELD(HFGITR_EL2, DCCVAU, 7, 1)
161
+FIELD(HFGITR_EL2, DCCVAP, 8, 1)
162
+FIELD(HFGITR_EL2, DCCVADP, 9, 1)
163
+FIELD(HFGITR_EL2, DCCIVAC, 10, 1)
164
+FIELD(HFGITR_EL2, DCZVA, 11, 1)
165
+FIELD(HFGITR_EL2, ATS1E1R, 12, 1)
166
+FIELD(HFGITR_EL2, ATS1E1W, 13, 1)
167
+FIELD(HFGITR_EL2, ATS1E0R, 14, 1)
168
+FIELD(HFGITR_EL2, ATS1E0W, 15, 1)
169
+FIELD(HFGITR_EL2, ATS1E1RP, 16, 1)
170
+FIELD(HFGITR_EL2, ATS1E1WP, 17, 1)
171
+FIELD(HFGITR_EL2, TLBIVMALLE1OS, 18, 1)
172
+FIELD(HFGITR_EL2, TLBIVAE1OS, 19, 1)
173
+FIELD(HFGITR_EL2, TLBIASIDE1OS, 20, 1)
174
+FIELD(HFGITR_EL2, TLBIVAAE1OS, 21, 1)
175
+FIELD(HFGITR_EL2, TLBIVALE1OS, 22, 1)
176
+FIELD(HFGITR_EL2, TLBIVAALE1OS, 23, 1)
177
+FIELD(HFGITR_EL2, TLBIRVAE1OS, 24, 1)
178
+FIELD(HFGITR_EL2, TLBIRVAAE1OS, 25, 1)
179
+FIELD(HFGITR_EL2, TLBIRVALE1OS, 26, 1)
180
+FIELD(HFGITR_EL2, TLBIRVAALE1OS, 27, 1)
181
+FIELD(HFGITR_EL2, TLBIVMALLE1IS, 28, 1)
182
+FIELD(HFGITR_EL2, TLBIVAE1IS, 29, 1)
183
+FIELD(HFGITR_EL2, TLBIASIDE1IS, 30, 1)
184
+FIELD(HFGITR_EL2, TLBIVAAE1IS, 31, 1)
185
+FIELD(HFGITR_EL2, TLBIVALE1IS, 32, 1)
186
+FIELD(HFGITR_EL2, TLBIVAALE1IS, 33, 1)
187
+FIELD(HFGITR_EL2, TLBIRVAE1IS, 34, 1)
188
+FIELD(HFGITR_EL2, TLBIRVAAE1IS, 35, 1)
189
+FIELD(HFGITR_EL2, TLBIRVALE1IS, 36, 1)
190
+FIELD(HFGITR_EL2, TLBIRVAALE1IS, 37, 1)
191
+FIELD(HFGITR_EL2, TLBIRVAE1, 38, 1)
192
+FIELD(HFGITR_EL2, TLBIRVAAE1, 39, 1)
193
+FIELD(HFGITR_EL2, TLBIRVALE1, 40, 1)
194
+FIELD(HFGITR_EL2, TLBIRVAALE1, 41, 1)
195
+FIELD(HFGITR_EL2, TLBIVMALLE1, 42, 1)
196
+FIELD(HFGITR_EL2, TLBIVAE1, 43, 1)
197
+FIELD(HFGITR_EL2, TLBIASIDE1, 44, 1)
198
+FIELD(HFGITR_EL2, TLBIVAAE1, 45, 1)
199
+FIELD(HFGITR_EL2, TLBIVALE1, 46, 1)
200
+FIELD(HFGITR_EL2, TLBIVAALE1, 47, 1)
201
+FIELD(HFGITR_EL2, CFPRCTX, 48, 1)
202
+FIELD(HFGITR_EL2, DVPRCTX, 49, 1)
203
+FIELD(HFGITR_EL2, CPPRCTX, 50, 1)
204
+FIELD(HFGITR_EL2, ERET, 51, 1)
205
+FIELD(HFGITR_EL2, SVC_EL0, 52, 1)
206
+FIELD(HFGITR_EL2, SVC_EL1, 53, 1)
207
+FIELD(HFGITR_EL2, DCCVAC, 54, 1)
208
+FIELD(HFGITR_EL2, NBRBINJ, 55, 1)
209
+FIELD(HFGITR_EL2, NBRBIALL, 56, 1)
210
+
211
+FIELD(HDFGRTR_EL2, DBGBCRN_EL1, 0, 1)
212
+FIELD(HDFGRTR_EL2, DBGBVRN_EL1, 1, 1)
213
+FIELD(HDFGRTR_EL2, DBGWCRN_EL1, 2, 1)
214
+FIELD(HDFGRTR_EL2, DBGWVRN_EL1, 3, 1)
215
+FIELD(HDFGRTR_EL2, MDSCR_EL1, 4, 1)
216
+FIELD(HDFGRTR_EL2, DBGCLAIM, 5, 1)
217
+FIELD(HDFGRTR_EL2, DBGAUTHSTATUS_EL1, 6, 1)
218
+FIELD(HDFGRTR_EL2, DBGPRCR_EL1, 7, 1)
219
+/* 8: RES0: OSLAR_EL1 is WO */
220
+FIELD(HDFGRTR_EL2, OSLSR_EL1, 9, 1)
221
+FIELD(HDFGRTR_EL2, OSECCR_EL1, 10, 1)
222
+FIELD(HDFGRTR_EL2, OSDLR_EL1, 11, 1)
223
+FIELD(HDFGRTR_EL2, PMEVCNTRN_EL0, 12, 1)
224
+FIELD(HDFGRTR_EL2, PMEVTYPERN_EL0, 13, 1)
225
+FIELD(HDFGRTR_EL2, PMCCFILTR_EL0, 14, 1)
226
+FIELD(HDFGRTR_EL2, PMCCNTR_EL0, 15, 1)
227
+FIELD(HDFGRTR_EL2, PMCNTEN, 16, 1)
228
+FIELD(HDFGRTR_EL2, PMINTEN, 17, 1)
229
+FIELD(HDFGRTR_EL2, PMOVS, 18, 1)
230
+FIELD(HDFGRTR_EL2, PMSELR_EL0, 19, 1)
231
+/* 20: RES0: PMSWINC_EL0 is WO */
232
+/* 21: RES0: PMCR_EL0 is WO */
233
+FIELD(HDFGRTR_EL2, PMMIR_EL1, 22, 1)
234
+FIELD(HDFGRTR_EL2, PMBLIMITR_EL1, 23, 1)
235
+FIELD(HDFGRTR_EL2, PMBPTR_EL1, 24, 1)
236
+FIELD(HDFGRTR_EL2, PMBSR_EL1, 25, 1)
237
+FIELD(HDFGRTR_EL2, PMSCR_EL1, 26, 1)
238
+FIELD(HDFGRTR_EL2, PMSEVFR_EL1, 27, 1)
239
+FIELD(HDFGRTR_EL2, PMSFCR_EL1, 28, 1)
240
+FIELD(HDFGRTR_EL2, PMSICR_EL1, 29, 1)
241
+FIELD(HDFGRTR_EL2, PMSIDR_EL1, 30, 1)
242
+FIELD(HDFGRTR_EL2, PMSIRR_EL1, 31, 1)
243
+FIELD(HDFGRTR_EL2, PMSLATFR_EL1, 32, 1)
244
+FIELD(HDFGRTR_EL2, TRC, 33, 1)
245
+FIELD(HDFGRTR_EL2, TRCAUTHSTATUS, 34, 1)
246
+FIELD(HDFGRTR_EL2, TRCAUXCTLR, 35, 1)
247
+FIELD(HDFGRTR_EL2, TRCCLAIM, 36, 1)
248
+FIELD(HDFGRTR_EL2, TRCCNTVRn, 37, 1)
249
+/* 38, 39: RES0 */
250
+FIELD(HDFGRTR_EL2, TRCID, 40, 1)
251
+FIELD(HDFGRTR_EL2, TRCIMSPECN, 41, 1)
252
+/* 42: RES0: TRCOSLAR is WO */
253
+FIELD(HDFGRTR_EL2, TRCOSLSR, 43, 1)
254
+FIELD(HDFGRTR_EL2, TRCPRGCTLR, 44, 1)
255
+FIELD(HDFGRTR_EL2, TRCSEQSTR, 45, 1)
256
+FIELD(HDFGRTR_EL2, TRCSSCSRN, 46, 1)
257
+FIELD(HDFGRTR_EL2, TRCSTATR, 47, 1)
258
+FIELD(HDFGRTR_EL2, TRCVICTLR, 48, 1)
259
+/* 49: RES0: TRFCR_EL1 is WO */
260
+FIELD(HDFGRTR_EL2, TRBBASER_EL1, 50, 1)
261
+FIELD(HDFGRTR_EL2, TRBIDR_EL1, 51, 1)
262
+FIELD(HDFGRTR_EL2, TRBLIMITR_EL1, 52, 1)
263
+FIELD(HDFGRTR_EL2, TRBMAR_EL1, 53, 1)
264
+FIELD(HDFGRTR_EL2, TRBPTR_EL1, 54, 1)
265
+FIELD(HDFGRTR_EL2, TRBSR_EL1, 55, 1)
266
+FIELD(HDFGRTR_EL2, TRBTRG_EL1, 56, 1)
267
+FIELD(HDFGRTR_EL2, PMUSERENR_EL0, 57, 1)
268
+FIELD(HDFGRTR_EL2, PMCEIDN_EL0, 58, 1)
269
+FIELD(HDFGRTR_EL2, NBRBIDR, 59, 1)
270
+FIELD(HDFGRTR_EL2, NBRBCTL, 60, 1)
271
+FIELD(HDFGRTR_EL2, NBRBDATA, 61, 1)
272
+FIELD(HDFGRTR_EL2, NPMSNEVFR_EL1, 62, 1)
273
+FIELD(HDFGRTR_EL2, PMBIDR_EL1, 63, 1)
274
+
275
+/*
276
+ * These match HDFGRTR_EL2, but bits for RO registers are RES0.
277
+ * A few bits are for WO registers, where the HDFGRTR_EL2 bit is RES0.
278
+ */
279
+FIELD(HDFGWTR_EL2, DBGBCRN_EL1, 0, 1)
280
+FIELD(HDFGWTR_EL2, DBGBVRN_EL1, 1, 1)
281
+FIELD(HDFGWTR_EL2, DBGWCRN_EL1, 2, 1)
282
+FIELD(HDFGWTR_EL2, DBGWVRN_EL1, 3, 1)
283
+FIELD(HDFGWTR_EL2, MDSCR_EL1, 4, 1)
284
+FIELD(HDFGWTR_EL2, DBGCLAIM, 5, 1)
285
+FIELD(HDFGWTR_EL2, DBGPRCR_EL1, 7, 1)
286
+FIELD(HDFGWTR_EL2, OSLAR_EL1, 8, 1)
287
+FIELD(HDFGWTR_EL2, OSLSR_EL1, 9, 1)
288
+FIELD(HDFGWTR_EL2, OSECCR_EL1, 10, 1)
289
+FIELD(HDFGWTR_EL2, OSDLR_EL1, 11, 1)
290
+FIELD(HDFGWTR_EL2, PMEVCNTRN_EL0, 12, 1)
291
+FIELD(HDFGWTR_EL2, PMEVTYPERN_EL0, 13, 1)
292
+FIELD(HDFGWTR_EL2, PMCCFILTR_EL0, 14, 1)
293
+FIELD(HDFGWTR_EL2, PMCCNTR_EL0, 15, 1)
294
+FIELD(HDFGWTR_EL2, PMCNTEN, 16, 1)
295
+FIELD(HDFGWTR_EL2, PMINTEN, 17, 1)
296
+FIELD(HDFGWTR_EL2, PMOVS, 18, 1)
297
+FIELD(HDFGWTR_EL2, PMSELR_EL0, 19, 1)
298
+FIELD(HDFGWTR_EL2, PMSWINC_EL0, 20, 1)
299
+FIELD(HDFGWTR_EL2, PMCR_EL0, 21, 1)
300
+FIELD(HDFGWTR_EL2, PMBLIMITR_EL1, 23, 1)
301
+FIELD(HDFGWTR_EL2, PMBPTR_EL1, 24, 1)
302
+FIELD(HDFGWTR_EL2, PMBSR_EL1, 25, 1)
303
+FIELD(HDFGWTR_EL2, PMSCR_EL1, 26, 1)
304
+FIELD(HDFGWTR_EL2, PMSEVFR_EL1, 27, 1)
305
+FIELD(HDFGWTR_EL2, PMSFCR_EL1, 28, 1)
306
+FIELD(HDFGWTR_EL2, PMSICR_EL1, 29, 1)
307
+FIELD(HDFGWTR_EL2, PMSIRR_EL1, 31, 1)
308
+FIELD(HDFGWTR_EL2, PMSLATFR_EL1, 32, 1)
309
+FIELD(HDFGWTR_EL2, TRC, 33, 1)
310
+FIELD(HDFGWTR_EL2, TRCAUXCTLR, 35, 1)
311
+FIELD(HDFGWTR_EL2, TRCCLAIM, 36, 1)
312
+FIELD(HDFGWTR_EL2, TRCCNTVRn, 37, 1)
313
+FIELD(HDFGWTR_EL2, TRCIMSPECN, 41, 1)
314
+FIELD(HDFGWTR_EL2, TRCOSLAR, 42, 1)
315
+FIELD(HDFGWTR_EL2, TRCPRGCTLR, 44, 1)
316
+FIELD(HDFGWTR_EL2, TRCSEQSTR, 45, 1)
317
+FIELD(HDFGWTR_EL2, TRCSSCSRN, 46, 1)
318
+FIELD(HDFGWTR_EL2, TRCVICTLR, 48, 1)
319
+FIELD(HDFGWTR_EL2, TRFCR_EL1, 49, 1)
320
+FIELD(HDFGWTR_EL2, TRBBASER_EL1, 50, 1)
321
+FIELD(HDFGWTR_EL2, TRBLIMITR_EL1, 52, 1)
322
+FIELD(HDFGWTR_EL2, TRBMAR_EL1, 53, 1)
323
+FIELD(HDFGWTR_EL2, TRBPTR_EL1, 54, 1)
324
+FIELD(HDFGWTR_EL2, TRBSR_EL1, 55, 1)
325
+FIELD(HDFGWTR_EL2, TRBTRG_EL1, 56, 1)
326
+FIELD(HDFGWTR_EL2, PMUSERENR_EL0, 57, 1)
327
+FIELD(HDFGWTR_EL2, NBRBCTL, 60, 1)
328
+FIELD(HDFGWTR_EL2, NBRBDATA, 61, 1)
329
+FIELD(HDFGWTR_EL2, NPMSNEVFR_EL1, 62, 1)
330
+
331
typedef struct ARMCPRegInfo ARMCPRegInfo;
332
333
/*
334
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
46
index XXXXXXX..XXXXXXX 100644
335
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
336
--- a/target/arm/cpu.h
48
+++ b/target/arm/translate.h
337
+++ b/target/arm/cpu.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
338
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
50
return x * 2 + 1;
339
uint64_t disr_el1;
340
uint64_t vdisr_el2;
341
uint64_t vsesr_el2;
342
+
343
+ /*
344
+ * Fine-Grained Trap registers. We store these as arrays so the
345
+ * access checking code doesn't have to manually select
346
+ * HFGRTR_EL2 vs HFDFGRTR_EL2 etc when looking up the bit to test.
347
+ * FEAT_FGT2 will add more elements to these arrays.
348
+ */
349
+ uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
350
+ uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
351
+ uint64_t fgt_exec[1]; /* HFGITR */
352
} cp15;
353
354
struct {
355
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
356
return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
51
}
357
}
52
358
53
+static inline int rsub_64(DisasContext *s, int x)
359
+static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
54
+{
360
+{
55
+ return 64 - x;
361
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
56
+}
362
+}
57
+
363
+
58
+static inline int rsub_32(DisasContext *s, int x)
364
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
365
{
366
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
367
diff --git a/target/arm/helper.c b/target/arm/helper.c
368
index XXXXXXX..XXXXXXX 100644
369
--- a/target/arm/helper.c
370
+++ b/target/arm/helper.c
371
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
372
if (cpu_isar_feature(aa64_hcx, cpu)) {
373
valid_mask |= SCR_HXEN;
374
}
375
+ if (cpu_isar_feature(aa64_fgt, cpu)) {
376
+ valid_mask |= SCR_FGTEN;
377
+ }
378
} else {
379
valid_mask &= ~(SCR_RW | SCR_ST);
380
if (cpu_isar_feature(aa32_ras, cpu)) {
381
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
382
.access = PL3_RW,
383
.fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
384
};
385
+
386
+static CPAccessResult access_fgt(CPUARMState *env, const ARMCPRegInfo *ri,
387
+ bool isread)
59
+{
388
+{
60
+ return 32 - x;
389
+ if (arm_current_el(env) == 2 &&
390
+ arm_feature(env, ARM_FEATURE_EL3) && !(env->cp15.scr_el3 & SCR_FGTEN)) {
391
+ return CP_ACCESS_TRAP_EL3;
392
+ }
393
+ return CP_ACCESS_OK;
61
+}
394
+}
62
+
395
+
63
+static inline int rsub_16(DisasContext *s, int x)
396
+static const ARMCPRegInfo fgt_reginfo[] = {
64
+{
397
+ { .name = "HFGRTR_EL2", .state = ARM_CP_STATE_AA64,
65
+ return 16 - x;
398
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
66
+}
399
+ .access = PL2_RW, .accessfn = access_fgt,
67
+
400
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HFGRTR]) },
68
+static inline int rsub_8(DisasContext *s, int x)
401
+ { .name = "HFGWTR_EL2", .state = ARM_CP_STATE_AA64,
69
+{
402
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 5,
70
+ return 8 - x;
403
+ .access = PL2_RW, .accessfn = access_fgt,
71
+}
404
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HFGWTR]) },
72
+
405
+ { .name = "HDFGRTR_EL2", .state = ARM_CP_STATE_AA64,
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
406
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 4,
74
{
407
+ .access = PL2_RW, .accessfn = access_fgt,
75
return (dc->features & (1ULL << feature)) != 0;
408
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HDFGRTR]) },
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
409
+ { .name = "HDFGWTR_EL2", .state = ARM_CP_STATE_AA64,
77
index XXXXXXX..XXXXXXX 100644
410
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 5,
78
--- a/target/arm/mve.decode
411
+ .access = PL2_RW, .accessfn = access_fgt,
79
+++ b/target/arm/mve.decode
412
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HDFGWTR]) },
80
@@ -XXX,XX +XXX,XX @@
413
+ { .name = "HFGITR_EL2", .state = ARM_CP_STATE_AA64,
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
414
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 6,
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
415
+ .access = PL2_RW, .accessfn = access_fgt,
83
416
+ .fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
417
+};
85
+%rshift_i5 16:5 !function=rsub_32
418
#endif /* TARGET_AARCH64 */
86
+%rshift_i4 16:4 !function=rsub_16
419
87
+%rshift_i3 16:3 !function=rsub_8
420
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
88
+
421
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
422
if (cpu_isar_feature(aa64_scxtnum, cpu)) {
90
+ size=0 shift=%rshift_i3
423
define_arm_cp_regs(cpu, scxtnum_reginfo);
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
424
}
92
+ size=1 shift=%rshift_i4
425
+
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
426
+ if (cpu_isar_feature(aa64_fgt, cpu)) {
94
+ size=2 shift=%rshift_i5
427
+ define_arm_cp_regs(cpu, fgt_reginfo);
95
+
428
+ }
96
# Vector loads and stores
429
#endif
97
430
98
# Widening loads and narrowing stores:
431
if (cpu_isar_feature(any_predinv, cpu)) {
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
163
}
164
165
-static inline int rsub_64(DisasContext *s, int x)
166
-{
167
- return 64 - x;
168
-}
169
-
170
-static inline int rsub_32(DisasContext *s, int x)
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
184
{
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
186
--
432
--
187
2.20.1
433
2.34.1
188
189
diff view generated by jsdifflib
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
1
Implement the machinery for fine-grained traps on normal sysregs.
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
2
Any sysreg with a fine-grained trap will set the new field to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
3
indicate which FGT register bit it should trap on.
4
reimplementing it all.
4
5
FGT traps only happen when an AArch64 EL2 enables them for
6
an AArch64 EL1. They therefore are only relevant for AArch32
7
cpregs when the cpreg can be accessed from EL0. The logic
8
in access_check_cp_reg() will check this, so it is safe to
9
add a .fgt marking to an ARM_CP_STATE_BOTH ARMCPRegInfo.
10
11
The DO_BIT and DO_REV_BIT macros define enum constants FGT_##bitname
12
which can be used to specify the FGT bit, eg
13
.fgt = FGT_AFSR0_EL1
14
(We assume that there is no bit name duplication across the FGT
15
registers, for brevity's sake.)
16
17
Subsequent commits will add the .fgt fields to the relevant register
18
definitions and define the FGT_nnn values for them.
19
20
Note that some of the FGT traps are for instructions that we don't
21
handle via the cpregs mechanisms (mostly these are instruction traps).
22
Those we will have to handle separately.
5
23
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
26
Tested-by: Fuad Tabba <tabba@google.com>
27
Message-id: 20230130182459.3309057-10-peter.maydell@linaro.org
28
Message-id: 20230127175507.2895013-10-peter.maydell@linaro.org
9
---
29
---
10
target/arm/translate.h | 3 +-
30
target/arm/cpregs.h | 72 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-a64.c | 86 ++++----------------------------------
31
target/arm/cpu.h | 1 +
12
target/arm/translate.c | 17 +++++++-
32
target/arm/internals.h | 20 +++++++++++
13
3 files changed, 24 insertions(+), 82 deletions(-)
33
target/arm/translate.h | 2 ++
14
34
target/arm/helper.c | 9 +++++
35
target/arm/op_helper.c | 30 ++++++++++++++++
36
target/arm/translate-a64.c | 3 +-
37
target/arm/translate.c | 2 ++
38
8 files changed, 138 insertions(+), 1 deletion(-)
39
40
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpregs.h
43
+++ b/target/arm/cpregs.h
44
@@ -XXX,XX +XXX,XX @@ FIELD(HDFGWTR_EL2, NBRBCTL, 60, 1)
45
FIELD(HDFGWTR_EL2, NBRBDATA, 61, 1)
46
FIELD(HDFGWTR_EL2, NPMSNEVFR_EL1, 62, 1)
47
48
+/* Which fine-grained trap bit register to check, if any */
49
+FIELD(FGT, TYPE, 10, 3)
50
+FIELD(FGT, REV, 9, 1) /* Is bit sense reversed? */
51
+FIELD(FGT, IDX, 6, 3) /* Index within a uint64_t[] array */
52
+FIELD(FGT, BITPOS, 0, 6) /* Bit position within the uint64_t */
53
+
54
+/*
55
+ * Macros to define FGT_##bitname enum constants to use in ARMCPRegInfo::fgt
56
+ * fields. We assume for brevity's sake that there are no duplicated
57
+ * bit names across the various FGT registers.
58
+ */
59
+#define DO_BIT(REG, BITNAME) \
60
+ FGT_##BITNAME = FGT_##REG | R_##REG##_EL2_##BITNAME##_SHIFT
61
+
62
+/* Some bits have reversed sense, so 0 means trap and 1 means not */
63
+#define DO_REV_BIT(REG, BITNAME) \
64
+ FGT_##BITNAME = FGT_##REG | FGT_REV | R_##REG##_EL2_##BITNAME##_SHIFT
65
+
66
+typedef enum FGTBit {
67
+ /*
68
+ * These bits tell us which register arrays to use:
69
+ * if FGT_R is set then reads are checked against fgt_read[];
70
+ * if FGT_W is set then writes are checked against fgt_write[];
71
+ * if FGT_EXEC is set then all accesses are checked against fgt_exec[].
72
+ *
73
+ * For almost all bits in the R/W register pairs, the bit exists in
74
+ * both registers for a RW register, in HFGRTR/HDFGRTR for a RO register
75
+ * with the corresponding HFGWTR/HDFGTWTR bit being RES0, and vice-versa
76
+ * for a WO register. There are unfortunately a couple of exceptions
77
+ * (PMCR_EL0, TRFCR_EL1) where the register being trapped is RW but
78
+ * the FGT system only allows trapping of writes, not reads.
79
+ *
80
+ * Note that we arrange these bits so that a 0 FGTBit means "no trap".
81
+ */
82
+ FGT_R = 1 << R_FGT_TYPE_SHIFT,
83
+ FGT_W = 2 << R_FGT_TYPE_SHIFT,
84
+ FGT_EXEC = 4 << R_FGT_TYPE_SHIFT,
85
+ FGT_RW = FGT_R | FGT_W,
86
+ /* Bit to identify whether trap bit is reversed sense */
87
+ FGT_REV = R_FGT_REV_MASK,
88
+
89
+ /*
90
+ * If a bit exists in HFGRTR/HDFGRTR then either the register being
91
+ * trapped is RO or the bit also exists in HFGWTR/HDFGWTR, so we either
92
+ * want to trap for both reads and writes or else it's harmless to mark
93
+ * it as trap-on-writes.
94
+ * If a bit exists only in HFGWTR/HDFGWTR then either the register being
95
+ * trapped is WO, or else it is one of the two oddball special cases
96
+ * which are RW but have only a write trap. We mark these as only
97
+ * FGT_W so we get the right behaviour for those special cases.
98
+ * (If a bit was added in future that provided only a read trap for an
99
+ * RW register we'd need to do something special to get the FGT_R bit
100
+ * only. But this seems unlikely to happen.)
101
+ *
102
+ * So for the DO_BIT/DO_REV_BIT macros: use FGT_HFGRTR/FGT_HDFGRTR if
103
+ * the bit exists in that register. Otherwise use FGT_HFGWTR/FGT_HDFGWTR.
104
+ */
105
+ FGT_HFGRTR = FGT_RW | (FGTREG_HFGRTR << R_FGT_IDX_SHIFT),
106
+ FGT_HFGWTR = FGT_W | (FGTREG_HFGWTR << R_FGT_IDX_SHIFT),
107
+ FGT_HDFGRTR = FGT_RW | (FGTREG_HDFGRTR << R_FGT_IDX_SHIFT),
108
+ FGT_HDFGWTR = FGT_W | (FGTREG_HDFGWTR << R_FGT_IDX_SHIFT),
109
+ FGT_HFGITR = FGT_EXEC | (FGTREG_HFGITR << R_FGT_IDX_SHIFT),
110
+} FGTBit;
111
+
112
+#undef DO_BIT
113
+#undef DO_REV_BIT
114
+
115
typedef struct ARMCPRegInfo ARMCPRegInfo;
116
117
/*
118
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
119
CPAccessRights access;
120
/* Security state: ARM_CP_SECSTATE_* bits/values */
121
CPSecureState secure;
122
+ /*
123
+ * Which fine-grained trap register bit to check, if any. This
124
+ * value encodes both the trap register and bit within it.
125
+ */
126
+ FGTBit fgt;
127
/*
128
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
129
* this register was defined: can be used to hand data through to the
130
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/cpu.h
133
+++ b/target/arm/cpu.h
134
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
135
/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
136
FIELD(TBFLAG_ANY, ALIGN_MEM, 10, 1)
137
FIELD(TBFLAG_ANY, PSTATE__IL, 11, 1)
138
+FIELD(TBFLAG_ANY, FGT_ACTIVE, 12, 1)
139
140
/*
141
* Bit usage when in AArch32 state, both A- and M-profile.
142
diff --git a/target/arm/internals.h b/target/arm/internals.h
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/internals.h
145
+++ b/target/arm/internals.h
146
@@ -XXX,XX +XXX,XX @@ static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
147
((1 << (1 - 1)) | (1 << (2 - 1)) | \
148
(1 << (4 - 1)) | (1 << (8 - 1)) | (1 << (16 - 1)))
149
150
+/*
151
+ * Return true if it is possible to take a fine-grained-trap to EL2.
152
+ */
153
+static inline bool arm_fgt_active(CPUARMState *env, int el)
154
+{
155
+ /*
156
+ * The Arm ARM only requires the "{E2H,TGE} != {1,1}" test for traps
157
+ * that can affect EL0, but it is harmless to do the test also for
158
+ * traps on registers that are only accessible at EL1 because if the test
159
+ * returns true then we can't be executing at EL1 anyway.
160
+ * FGT traps only happen when EL2 is enabled and EL1 is AArch64;
161
+ * traps from AArch32 only happen for the EL0 is AArch32 case.
162
+ */
163
+ return cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
164
+ el < 2 && arm_is_el2_enabled(env) &&
165
+ arm_el_is_aa64(env, 1) &&
166
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE) &&
167
+ (!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN));
168
+}
169
+
170
#endif
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
171
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
172
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
173
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
174
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
175
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
20
* VMVN and VBIC (when cmode < 14 && op == 1).
176
bool is_nonstreaming;
21
*
177
/* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
178
bool mve_no_pred;
23
- * callers must catch this.
179
+ /* True if fine-grained traps are active */
24
+ * callers must catch this; we return the 64-bit constant value defined
180
+ bool fgt_active;
25
+ * for AArch64.
181
/*
26
*
182
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
183
* < 0, set by the current instruction.
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
184
diff --git a/target/arm/helper.c b/target/arm/helper.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/target/arm/helper.c
187
+++ b/target/arm/helper.c
188
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
189
if (arm_singlestep_active(env)) {
190
DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
191
}
192
+
193
return flags;
194
}
195
196
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
197
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
198
}
199
200
+ if (arm_fgt_active(env, el)) {
201
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
202
+ }
203
+
204
if (env->uncached_cpsr & CPSR_IL) {
205
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
206
}
207
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
208
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
209
}
210
211
+ if (arm_fgt_active(env, el)) {
212
+ DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
213
+ }
214
+
215
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
216
/*
217
* Set MTE_ACTIVE if any access may be Checked, and leave clear
218
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/target/arm/op_helper.c
221
+++ b/target/arm/op_helper.c
222
@@ -XXX,XX +XXX,XX @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
223
}
224
}
225
226
+ /*
227
+ * Fine-grained traps also are lower priority than undef-to-EL1,
228
+ * higher priority than trap-to-EL3, and we don't care about priority
229
+ * order with other EL2 traps because the syndrome value is the same.
230
+ */
231
+ if (arm_fgt_active(env, arm_current_el(env))) {
232
+ uint64_t trapword = 0;
233
+ unsigned int idx = FIELD_EX32(ri->fgt, FGT, IDX);
234
+ unsigned int bitpos = FIELD_EX32(ri->fgt, FGT, BITPOS);
235
+ bool rev = FIELD_EX32(ri->fgt, FGT, REV);
236
+ bool trapbit;
237
+
238
+ if (ri->fgt & FGT_EXEC) {
239
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_exec));
240
+ trapword = env->cp15.fgt_exec[idx];
241
+ } else if (isread && (ri->fgt & FGT_R)) {
242
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_read));
243
+ trapword = env->cp15.fgt_read[idx];
244
+ } else if (!isread && (ri->fgt & FGT_W)) {
245
+ assert(idx < ARRAY_SIZE(env->cp15.fgt_write));
246
+ trapword = env->cp15.fgt_write[idx];
247
+ }
248
+
249
+ trapbit = extract64(trapword, bitpos, 1);
250
+ if (trapbit != rev) {
251
+ res = CP_ACCESS_TRAP_EL2;
252
+ goto fail;
253
+ }
254
+ }
255
+
256
if (likely(res == CP_ACCESS_OK)) {
257
return ri;
258
}
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
259
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
260
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
261
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
262
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
263
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
34
{
35
int rd = extract32(insn, 0, 5);
36
int cmode = extract32(insn, 12, 4);
37
- int cmode_3_1 = extract32(cmode, 1, 3);
38
- int cmode_0 = extract32(cmode, 0, 1);
39
int o2 = extract32(insn, 11, 1);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
41
bool is_neg = extract32(insn, 29, 1);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
43
return;
264
return;
44
}
265
}
45
266
46
- /* See AdvSIMDExpandImm() in ARM ARM */
267
- if (ri->accessfn) {
47
- switch (cmode_3_1) {
268
+ if (ri->accessfn || (ri->fgt && s->fgt_active)) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
269
/* Emit code to perform further access permissions checks at
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
270
* runtime; this may result in an exception.
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
271
*/
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
272
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
52
- {
273
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
53
- int shift = cmode_3_1 * 8;
274
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
275
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
55
- break;
276
+ dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
56
- }
277
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
278
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
279
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
131
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
280
diff --git a/target/arm/translate.c b/target/arm/translate.c
134
index XXXXXXX..XXXXXXX 100644
281
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate.c
282
--- a/target/arm/translate.c
136
+++ b/target/arm/translate.c
283
+++ b/target/arm/translate.c
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
284
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
138
case 14:
285
}
139
if (op) {
286
140
/*
287
if ((s->hstr_active && s->current_el == 0) || ri->accessfn ||
141
- * This is the only case where the top and bottom 32 bits
288
+ (ri->fgt && s->fgt_active) ||
142
- * of the encoded constant differ.
289
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
143
+ * This and cmode == 15 op == 1 are the only cases where
290
/*
144
+ * the top and bottom 32 bits of the encoded constant differ.
291
* Emit code to perform further access permissions checks at
145
*/
292
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
146
uint64_t imm64 = 0;
293
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
147
int n;
294
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
295
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
296
+ dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
150
break;
297
151
case 15:
298
if (arm_feature(env, ARM_FEATURE_M)) {
152
+ if (op) {
299
dc->vfp_enabled = 1;
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
168
--
300
--
169
2.20.1
301
2.34.1
170
171
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 0..11.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-11-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-11-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 14 ++++++++++++++
11
target/arm/helper.c | 17 +++++++++++++++++
12
2 files changed, 31 insertions(+)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
FGT_HDFGRTR = FGT_RW | (FGTREG_HDFGRTR << R_FGT_IDX_SHIFT),
20
FGT_HDFGWTR = FGT_W | (FGTREG_HDFGWTR << R_FGT_IDX_SHIFT),
21
FGT_HFGITR = FGT_EXEC | (FGTREG_HFGITR << R_FGT_IDX_SHIFT),
22
+
23
+ /* Trap bits in HFGRTR_EL2 / HFGWTR_EL2, starting from bit 0. */
24
+ DO_BIT(HFGRTR, AFSR0_EL1),
25
+ DO_BIT(HFGRTR, AFSR1_EL1),
26
+ DO_BIT(HFGRTR, AIDR_EL1),
27
+ DO_BIT(HFGRTR, AMAIR_EL1),
28
+ DO_BIT(HFGRTR, APDAKEY),
29
+ DO_BIT(HFGRTR, APDBKEY),
30
+ DO_BIT(HFGRTR, APGAKEY),
31
+ DO_BIT(HFGRTR, APIAKEY),
32
+ DO_BIT(HFGRTR, APIBKEY),
33
+ DO_BIT(HFGRTR, CCSIDR_EL1),
34
+ DO_BIT(HFGRTR, CLIDR_EL1),
35
+ DO_BIT(HFGRTR, CONTEXTIDR_EL1),
36
} FGTBit;
37
38
#undef DO_BIT
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
44
{ .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
45
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
46
.access = PL1_RW, .accessfn = access_tvm_trvm,
47
+ .fgt = FGT_CONTEXTIDR_EL1,
48
.secure = ARM_CP_SECSTATE_NS,
49
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
50
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
53
.access = PL1_R,
54
.accessfn = access_tid4,
55
+ .fgt = FGT_CCSIDR_EL1,
56
.readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
57
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
59
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
60
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
61
.access = PL1_R, .type = ARM_CP_CONST,
62
.accessfn = access_aa64_tid1,
63
+ .fgt = FGT_AIDR_EL1,
64
.resetvalue = 0 },
65
/*
66
* Auxiliary fault status registers: these also are IMPDEF, and we
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
68
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
69
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
70
.access = PL1_RW, .accessfn = access_tvm_trvm,
71
+ .fgt = FGT_AFSR0_EL1,
72
.type = ARM_CP_CONST, .resetvalue = 0 },
73
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
+ .fgt = FGT_AFSR1_EL1,
77
.type = ARM_CP_CONST, .resetvalue = 0 },
78
/*
79
* MAIR can just read-as-written because we don't implement caches
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
81
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
82
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
+ .fgt = FGT_AMAIR_EL1,
85
.type = ARM_CP_CONST, .resetvalue = 0 },
86
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
87
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
89
{ .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
90
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
91
.access = PL1_RW, .accessfn = access_pauth,
92
+ .fgt = FGT_APDAKEY,
93
.fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
94
{ .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
95
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
96
.access = PL1_RW, .accessfn = access_pauth,
97
+ .fgt = FGT_APDAKEY,
98
.fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
99
{ .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
100
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
101
.access = PL1_RW, .accessfn = access_pauth,
102
+ .fgt = FGT_APDBKEY,
103
.fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
104
{ .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
105
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
106
.access = PL1_RW, .accessfn = access_pauth,
107
+ .fgt = FGT_APDBKEY,
108
.fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
109
{ .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
110
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
111
.access = PL1_RW, .accessfn = access_pauth,
112
+ .fgt = FGT_APGAKEY,
113
.fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
114
{ .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
115
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
116
.access = PL1_RW, .accessfn = access_pauth,
117
+ .fgt = FGT_APGAKEY,
118
.fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
119
{ .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
120
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
121
.access = PL1_RW, .accessfn = access_pauth,
122
+ .fgt = FGT_APIAKEY,
123
.fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
124
{ .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
125
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
126
.access = PL1_RW, .accessfn = access_pauth,
127
+ .fgt = FGT_APIAKEY,
128
.fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
129
{ .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
130
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
131
.access = PL1_RW, .accessfn = access_pauth,
132
+ .fgt = FGT_APIBKEY,
133
.fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
134
{ .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
135
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
136
.access = PL1_RW, .accessfn = access_pauth,
137
+ .fgt = FGT_APIBKEY,
138
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
139
};
140
141
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
142
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
143
.access = PL1_R, .type = ARM_CP_CONST,
144
.accessfn = access_tid4,
145
+ .fgt = FGT_CLIDR_EL1,
146
.resetvalue = cpu->clidr
147
};
148
define_one_arm_cp_reg(cpu, &clidr);
149
--
150
2.34.1
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 12..23.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-12-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-12-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 12 ++++++++++++
11
target/arm/helper.c | 12 ++++++++++++
12
2 files changed, 24 insertions(+)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
DO_BIT(HFGRTR, CCSIDR_EL1),
20
DO_BIT(HFGRTR, CLIDR_EL1),
21
DO_BIT(HFGRTR, CONTEXTIDR_EL1),
22
+ DO_BIT(HFGRTR, CPACR_EL1),
23
+ DO_BIT(HFGRTR, CSSELR_EL1),
24
+ DO_BIT(HFGRTR, CTR_EL0),
25
+ DO_BIT(HFGRTR, DCZID_EL0),
26
+ DO_BIT(HFGRTR, ESR_EL1),
27
+ DO_BIT(HFGRTR, FAR_EL1),
28
+ DO_BIT(HFGRTR, ISR_EL1),
29
+ DO_BIT(HFGRTR, LORC_EL1),
30
+ DO_BIT(HFGRTR, LOREA_EL1),
31
+ DO_BIT(HFGRTR, LORID_EL1),
32
+ DO_BIT(HFGRTR, LORN_EL1),
33
+ DO_BIT(HFGRTR, LORSA_EL1),
34
} FGTBit;
35
36
#undef DO_BIT
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
42
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
43
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
44
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
45
+ .fgt = FGT_CPACR_EL1,
46
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
47
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
48
};
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
.access = PL1_RW,
52
.accessfn = access_tid4,
53
+ .fgt = FGT_CSSELR_EL1,
54
.writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
58
.resetfn = arm_cp_reset_ignore },
59
{ .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
60
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
61
+ .fgt = FGT_ISR_EL1,
62
.type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
63
/* 32 bit ITLB invalidates */
64
{ .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
66
{ .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
67
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
68
.access = PL1_RW, .accessfn = access_tvm_trvm,
69
+ .fgt = FGT_FAR_EL1,
70
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
71
.resetvalue = 0, },
72
};
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
74
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
75
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
76
.access = PL1_RW, .accessfn = access_tvm_trvm,
77
+ .fgt = FGT_ESR_EL1,
78
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
79
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
80
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
82
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
83
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
84
.access = PL0_R, .type = ARM_CP_NO_RAW,
85
+ .fgt = FGT_DCZID_EL0,
86
.readfn = aa64_dczid_read },
87
{ .name = "DC_ZVA", .state = ARM_CP_STATE_AA64,
88
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1,
89
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
90
{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
91
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
92
.access = PL1_RW, .accessfn = access_lor_other,
93
+ .fgt = FGT_LORSA_EL1,
94
.type = ARM_CP_CONST, .resetvalue = 0 },
95
{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
97
.access = PL1_RW, .accessfn = access_lor_other,
98
+ .fgt = FGT_LOREA_EL1,
99
.type = ARM_CP_CONST, .resetvalue = 0 },
100
{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
102
.access = PL1_RW, .accessfn = access_lor_other,
103
+ .fgt = FGT_LORN_EL1,
104
.type = ARM_CP_CONST, .resetvalue = 0 },
105
{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
107
.access = PL1_RW, .accessfn = access_lor_other,
108
+ .fgt = FGT_LORC_EL1,
109
.type = ARM_CP_CONST, .resetvalue = 0 },
110
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
112
.access = PL1_R, .accessfn = access_lor_ns,
113
+ .fgt = FGT_LORID_EL1,
114
.type = ARM_CP_CONST, .resetvalue = 0 },
115
};
116
117
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
118
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
119
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
120
.access = PL0_R, .accessfn = ctr_el0_access,
121
+ .fgt = FGT_CTR_EL0,
122
.type = ARM_CP_CONST, .resetvalue = cpu->ctr },
123
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
124
{ .name = "TCMTR",
125
--
126
2.34.1
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 24..35.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-13-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-13-peter.maydell@linaro.org
9
---
10
target/arm/cpregs.h | 12 ++++++++++++
11
target/arm/helper.c | 14 ++++++++++++++
12
2 files changed, 26 insertions(+)
13
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
17
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
DO_BIT(HFGRTR, LORID_EL1),
20
DO_BIT(HFGRTR, LORN_EL1),
21
DO_BIT(HFGRTR, LORSA_EL1),
22
+ DO_BIT(HFGRTR, MAIR_EL1),
23
+ DO_BIT(HFGRTR, MIDR_EL1),
24
+ DO_BIT(HFGRTR, MPIDR_EL1),
25
+ DO_BIT(HFGRTR, PAR_EL1),
26
+ DO_BIT(HFGRTR, REVIDR_EL1),
27
+ DO_BIT(HFGRTR, SCTLR_EL1),
28
+ DO_BIT(HFGRTR, SCXTNUM_EL1),
29
+ DO_BIT(HFGRTR, SCXTNUM_EL0),
30
+ DO_BIT(HFGRTR, TCR_EL1),
31
+ DO_BIT(HFGRTR, TPIDR_EL1),
32
+ DO_BIT(HFGRTR, TPIDRRO_EL0),
33
+ DO_BIT(HFGRTR, TPIDR_EL0),
34
} FGTBit;
35
36
#undef DO_BIT
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
42
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
43
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
44
.access = PL1_RW, .accessfn = access_tvm_trvm,
45
+ .fgt = FGT_MAIR_EL1,
46
.fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
47
.resetvalue = 0 },
48
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
50
{ .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
51
.opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
52
.access = PL0_RW,
53
+ .fgt = FGT_TPIDR_EL0,
54
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 },
55
{ .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
56
.access = PL0_RW,
57
+ .fgt = FGT_TPIDR_EL0,
58
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
59
offsetoflow32(CPUARMState, cp15.tpidrurw_ns) },
60
.resetfn = arm_cp_reset_ignore },
61
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
62
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
63
.access = PL0_R | PL1_W,
64
+ .fgt = FGT_TPIDRRO_EL0,
65
.fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
66
.resetvalue = 0},
67
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
68
.access = PL0_R | PL1_W,
69
+ .fgt = FGT_TPIDRRO_EL0,
70
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
71
offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
72
.resetfn = arm_cp_reset_ignore },
73
{ .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
74
.opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
75
.access = PL1_RW,
76
+ .fgt = FGT_TPIDR_EL1,
77
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 },
78
{ .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4,
79
.access = PL1_RW,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
81
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
82
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
+ .fgt = FGT_TCR_EL1,
85
.writefn = vmsa_tcr_el12_write,
86
.raw_writefn = raw_write,
87
.resetvalue = 0,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
89
.type = ARM_CP_ALIAS,
90
.opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
91
.access = PL1_RW, .resetvalue = 0,
92
+ .fgt = FGT_PAR_EL1,
93
.fieldoffset = offsetof(CPUARMState, cp15.par_el[1]),
94
.writefn = par_write },
95
#endif
96
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
97
{ .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
98
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
99
.access = PL0_RW, .accessfn = access_scxtnum,
100
+ .fgt = FGT_SCXTNUM_EL0,
101
.fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
102
{ .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
103
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
104
.access = PL1_RW, .accessfn = access_scxtnum,
105
+ .fgt = FGT_SCXTNUM_EL1,
106
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
107
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
108
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
109
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
110
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
111
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
112
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
113
+ .fgt = FGT_MIDR_EL1,
114
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
115
.readfn = midr_read },
116
/* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
117
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
118
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
119
.access = PL1_R,
120
.accessfn = access_aa64_tid1,
121
+ .fgt = FGT_REVIDR_EL1,
122
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
123
};
124
ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
125
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
126
ARMCPRegInfo mpidr_cp_reginfo[] = {
127
{ .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
128
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
129
+ .fgt = FGT_MPIDR_EL1,
130
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
131
};
132
#ifdef CONFIG_USER_ONLY
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
.name = "SCTLR", .state = ARM_CP_STATE_BOTH,
135
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
136
.access = PL1_RW, .accessfn = access_tvm_trvm,
137
+ .fgt = FGT_SCTLR_EL1,
138
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
139
offsetof(CPUARMState, cp15.sctlr_ns) },
140
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
141
--
142
2.34.1
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitions for the registers trapped
2
by HFGRTR/HFGWTR bits 36..63.
1
3
4
Of these, some correspond to RAS registers which we implement as
5
always-UNDEF: these don't need any extra handling for FGT because the
6
UNDEF-to-EL1 always takes priority over any theoretical
7
FGT-trap-to-EL2.
8
9
Bit 50 (NACCDATA_EL1) is for the ACCDATA_EL1 register which is part
10
of the FEAT_LS64_ACCDATA feature which we don't yet implement.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Fuad Tabba <tabba@google.com>
15
Message-id: 20230130182459.3309057-14-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-14-peter.maydell@linaro.org
17
---
18
target/arm/cpregs.h | 7 +++++++
19
hw/intc/arm_gicv3_cpuif.c | 2 ++
20
target/arm/helper.c | 10 ++++++++++
21
3 files changed, 19 insertions(+)
22
23
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpregs.h
26
+++ b/target/arm/cpregs.h
27
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
28
DO_BIT(HFGRTR, TPIDR_EL1),
29
DO_BIT(HFGRTR, TPIDRRO_EL0),
30
DO_BIT(HFGRTR, TPIDR_EL0),
31
+ DO_BIT(HFGRTR, TTBR0_EL1),
32
+ DO_BIT(HFGRTR, TTBR1_EL1),
33
+ DO_BIT(HFGRTR, VBAR_EL1),
34
+ DO_BIT(HFGRTR, ICC_IGRPENN_EL1),
35
+ DO_BIT(HFGRTR, ERRIDR_EL1),
36
+ DO_REV_BIT(HFGRTR, NSMPRI_EL1),
37
+ DO_REV_BIT(HFGRTR, NTPIDR2_EL0),
38
} FGTBit;
39
40
#undef DO_BIT
41
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/intc/arm_gicv3_cpuif.c
44
+++ b/hw/intc/arm_gicv3_cpuif.c
45
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
46
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6,
47
.type = ARM_CP_IO | ARM_CP_NO_RAW,
48
.access = PL1_RW, .accessfn = gicv3_fiq_access,
49
+ .fgt = FGT_ICC_IGRPENN_EL1,
50
.readfn = icc_igrpen_read,
51
.writefn = icc_igrpen_write,
52
},
53
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
54
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 7,
55
.type = ARM_CP_IO | ARM_CP_NO_RAW,
56
.access = PL1_RW, .accessfn = gicv3_irq_access,
57
+ .fgt = FGT_ICC_IGRPENN_EL1,
58
.readfn = icc_igrpen_read,
59
.writefn = icc_igrpen_write,
60
},
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
66
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
67
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
68
.access = PL1_RW, .accessfn = access_tvm_trvm,
69
+ .fgt = FGT_TTBR0_EL1,
70
.writefn = vmsa_ttbr_write, .resetvalue = 0,
71
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
72
offsetof(CPUARMState, cp15.ttbr0_ns) } },
73
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
+ .fgt = FGT_TTBR1_EL1,
77
.writefn = vmsa_ttbr_write, .resetvalue = 0,
78
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
79
offsetof(CPUARMState, cp15.ttbr1_ns) } },
80
@@ -XXX,XX +XXX,XX @@ static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
81
* ERRSELR_EL1
82
* may generate UNDEFINED, which is the effect we get by not
83
* listing them at all.
84
+ *
85
+ * These registers have fine-grained trap bits, but UNDEF-to-EL1
86
+ * is higher priority than FGT-to-EL2 so we do not need to list them
87
+ * in order to check for an FGT.
88
*/
89
static const ARMCPRegInfo minimal_ras_reginfo[] = {
90
{ .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
91
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo minimal_ras_reginfo[] = {
92
{ .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
93
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
94
.access = PL1_R, .accessfn = access_terr,
95
+ .fgt = FGT_ERRIDR_EL1,
96
.type = ARM_CP_CONST, .resetvalue = 0 },
97
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
98
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
99
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
100
{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
102
.access = PL0_RW, .accessfn = access_tpidr2,
103
+ .fgt = FGT_NTPIDR2_EL0,
104
.fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
105
{ .name = "SVCR", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
107
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
108
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
109
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
110
.access = PL1_RW, .accessfn = access_esm,
111
+ .fgt = FGT_NSMPRI_EL1,
112
.type = ARM_CP_CONST, .resetvalue = 0 },
113
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
114
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
115
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
116
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
117
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
118
.access = PL1_RW, .writefn = vbar_write,
119
+ .fgt = FGT_VBAR_EL1,
120
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
121
offsetof(CPUARMState, cp15.vbar_ns) },
122
.resetvalue = 0 },
123
--
124
2.34.1
diff view generated by jsdifflib
New patch
1
Mark up the sysreg definitons for the registers trapped
2
by HDFGRTR/HDFGWTR bits 0..11. These cover various debug
3
related registers.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Fuad Tabba <tabba@google.com>
8
Message-id: 20230130182459.3309057-15-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-15-peter.maydell@linaro.org
10
---
11
target/arm/cpregs.h | 12 ++++++++++++
12
target/arm/debug_helper.c | 11 +++++++++++
13
2 files changed, 23 insertions(+)
14
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpregs.h
18
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
20
DO_BIT(HFGRTR, ERRIDR_EL1),
21
DO_REV_BIT(HFGRTR, NSMPRI_EL1),
22
DO_REV_BIT(HFGRTR, NTPIDR2_EL0),
23
+
24
+ /* Trap bits in HDFGRTR_EL2 / HDFGWTR_EL2, starting from bit 0. */
25
+ DO_BIT(HDFGRTR, DBGBCRN_EL1),
26
+ DO_BIT(HDFGRTR, DBGBVRN_EL1),
27
+ DO_BIT(HDFGRTR, DBGWCRN_EL1),
28
+ DO_BIT(HDFGRTR, DBGWVRN_EL1),
29
+ DO_BIT(HDFGRTR, MDSCR_EL1),
30
+ DO_BIT(HDFGRTR, DBGCLAIM),
31
+ DO_BIT(HDFGWTR, OSLAR_EL1),
32
+ DO_BIT(HDFGRTR, OSLSR_EL1),
33
+ DO_BIT(HDFGRTR, OSECCR_EL1),
34
+ DO_BIT(HDFGRTR, OSDLR_EL1),
35
} FGTBit;
36
37
#undef DO_BIT
38
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/debug_helper.c
41
+++ b/target/arm/debug_helper.c
42
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
43
{ .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
44
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
45
.access = PL1_RW, .accessfn = access_tda,
46
+ .fgt = FGT_MDSCR_EL1,
47
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
48
.resetvalue = 0 },
49
/*
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
51
{ .name = "OSECCR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
52
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
53
.access = PL1_RW, .accessfn = access_tda,
54
+ .fgt = FGT_OSECCR_EL1,
55
.type = ARM_CP_CONST, .resetvalue = 0 },
56
/*
57
* DBGDSCRint[15,12,5:2] map to MDSCR_EL1[15,12,5:2]. Map all bits as
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
59
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
60
.access = PL1_W, .type = ARM_CP_NO_RAW,
61
.accessfn = access_tdosa,
62
+ .fgt = FGT_OSLAR_EL1,
63
.writefn = oslar_write },
64
{ .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
65
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
66
.access = PL1_R, .resetvalue = 10,
67
.accessfn = access_tdosa,
68
+ .fgt = FGT_OSLSR_EL1,
69
.fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
70
/* Dummy OSDLR_EL1: 32-bit Linux will read this */
71
{ .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
72
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
73
.access = PL1_RW, .accessfn = access_tdosa,
74
+ .fgt = FGT_OSDLR_EL1,
75
.writefn = osdlr_write,
76
.fieldoffset = offsetof(CPUARMState, cp15.osdlr_el1) },
77
/*
78
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
79
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 6,
80
.type = ARM_CP_ALIAS,
81
.access = PL1_RW, .accessfn = access_tda,
82
+ .fgt = FGT_DBGCLAIM,
83
.writefn = dbgclaimset_write, .readfn = dbgclaimset_read },
84
{ .name = "DBGCLAIMCLR_EL1", .state = ARM_CP_STATE_BOTH,
85
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 6,
86
.access = PL1_RW, .accessfn = access_tda,
87
+ .fgt = FGT_DBGCLAIM,
88
.writefn = dbgclaimclr_write, .raw_writefn = raw_write,
89
.fieldoffset = offsetof(CPUARMState, cp15.dbgclaim) },
90
};
91
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
92
{ .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
93
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
94
.access = PL1_RW, .accessfn = access_tda,
95
+ .fgt = FGT_DBGBVRN_EL1,
96
.fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
97
.writefn = dbgbvr_write, .raw_writefn = raw_write
98
},
99
{ .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
100
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
101
.access = PL1_RW, .accessfn = access_tda,
102
+ .fgt = FGT_DBGBCRN_EL1,
103
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
104
.writefn = dbgbcr_write, .raw_writefn = raw_write
105
},
106
@@ -XXX,XX +XXX,XX @@ void define_debug_regs(ARMCPU *cpu)
107
{ .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
108
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
109
.access = PL1_RW, .accessfn = access_tda,
110
+ .fgt = FGT_DBGWVRN_EL1,
111
.fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
112
.writefn = dbgwvr_write, .raw_writefn = raw_write
113
},
114
{ .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
115
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
116
.access = PL1_RW, .accessfn = access_tda,
117
+ .fgt = FGT_DBGWCRN_EL1,
118
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
119
.writefn = dbgwcr_write, .raw_writefn = raw_write
120
},
121
--
122
2.34.1
diff view generated by jsdifflib
1
Implement the MVE VSHLC insn, which performs a shift left of the
1
Mark up the sysreg definitions for the registers trapped
2
entire vector with carry in bits provided from a general purpose
2
by HDFGRTR/HDFGWTR bits 12..x.
3
register and carry out bits written back to that register.
3
4
Bits 12..22 and bit 58 are for PMU registers.
5
6
The remaining bits in HDFGRTR/HDFGWTR are for traps on
7
registers that are part of features we don't implement:
8
9
Bits 23..32 and 63 : FEAT_SPE
10
Bits 33..48 : FEAT_ETE
11
Bits 50..56 : FEAT_TRBE
12
Bits 59..61 : FEAT_BRBE
13
Bit 62 : FEAT_SPEv1p2.
4
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
17
Tested-by: Fuad Tabba <tabba@google.com>
18
Message-id: 20230130182459.3309057-16-peter.maydell@linaro.org
19
Message-id: 20230127175507.2895013-16-peter.maydell@linaro.org
8
---
20
---
9
target/arm/helper-mve.h | 2 ++
21
target/arm/cpregs.h | 12 ++++++++++++
10
target/arm/mve.decode | 2 ++
22
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
23
2 files changed, 49 insertions(+)
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
24
13
4 files changed, 72 insertions(+)
25
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
27
--- a/target/arm/cpregs.h
18
+++ b/target/arm/helper-mve.h
28
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
DO_BIT(HDFGRTR, OSLSR_EL1),
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
DO_BIT(HDFGRTR, OSECCR_EL1),
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DO_BIT(HDFGRTR, OSDLR_EL1),
23
+
33
+ DO_BIT(HDFGRTR, PMEVCNTRN_EL0),
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
34
+ DO_BIT(HDFGRTR, PMEVTYPERN_EL0),
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
35
+ DO_BIT(HDFGRTR, PMCCFILTR_EL0),
36
+ DO_BIT(HDFGRTR, PMCCNTR_EL0),
37
+ DO_BIT(HDFGRTR, PMCNTEN),
38
+ DO_BIT(HDFGRTR, PMINTEN),
39
+ DO_BIT(HDFGRTR, PMOVS),
40
+ DO_BIT(HDFGRTR, PMSELR_EL0),
41
+ DO_BIT(HDFGWTR, PMSWINC_EL0),
42
+ DO_BIT(HDFGWTR, PMCR_EL0),
43
+ DO_BIT(HDFGRTR, PMMIR_EL1),
44
+ DO_BIT(HDFGRTR, PMCEIDN_EL0),
45
} FGTBit;
46
47
#undef DO_BIT
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mve.decode
50
--- a/target/arm/helper.c
28
+++ b/target/arm/mve.decode
51
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
53
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
54
.writefn = pmcntenset_write,
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
55
.accessfn = pmreg_access,
33
+
56
+ .fgt = FGT_PMCNTEN,
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
57
.raw_writefn = raw_write },
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
58
{ .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64, .type = ARM_CP_IO,
36
index XXXXXXX..XXXXXXX 100644
59
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
37
--- a/target/arm/mve_helper.c
60
.access = PL0_RW, .accessfn = pmreg_access,
38
+++ b/target/arm/mve_helper.c
61
+ .fgt = FGT_PMCNTEN,
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
62
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
63
.writefn = pmcntenset_write, .raw_writefn = raw_write },
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
64
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
65
.access = PL0_RW,
43
+
66
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
67
.accessfn = pmreg_access,
45
+ uint32_t shift)
68
+ .fgt = FGT_PMCNTEN,
46
+{
69
.writefn = pmcntenclr_write,
47
+ uint32_t *d = vd;
70
.type = ARM_CP_ALIAS | ARM_CP_IO },
48
+ uint16_t mask = mve_element_mask(env);
71
{ .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
49
+ unsigned e;
72
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
50
+ uint32_t r;
73
.access = PL0_RW, .accessfn = pmreg_access,
51
+
74
+ .fgt = FGT_PMCNTEN,
52
+ /*
75
.type = ARM_CP_ALIAS | ARM_CP_IO,
53
+ * For each 32-bit element, we shift it left, bringing in the
76
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
77
.writefn = pmcntenclr_write },
55
+ * the top become the new rdm, if the predicate mask permits.
78
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
56
+ * The final rdm value is returned to update the register.
79
.access = PL0_RW, .type = ARM_CP_IO,
57
+ * shift == 0 here means "shift by 32 bits".
80
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
58
+ */
81
.accessfn = pmreg_access,
59
+ if (shift == 0) {
82
+ .fgt = FGT_PMOVS,
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
83
.writefn = pmovsr_write,
61
+ r = rdm;
84
.raw_writefn = raw_write },
62
+ if (mask & 1) {
85
{ .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
63
+ rdm = d[H4(e)];
86
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
64
+ }
87
.access = PL0_RW, .accessfn = pmreg_access,
65
+ mergemask(&d[H4(e)], r, mask);
88
+ .fgt = FGT_PMOVS,
66
+ }
89
.type = ARM_CP_ALIAS | ARM_CP_IO,
67
+ } else {
90
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
91
.writefn = pmovsr_write,
69
+
92
.raw_writefn = raw_write },
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
93
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
94
.access = PL0_W, .accessfn = pmreg_access_swinc,
72
+ if (mask & 1) {
95
+ .fgt = FGT_PMSWINC_EL0,
73
+ rdm = d[H4(e)] >> (32 - shift);
96
.type = ARM_CP_NO_RAW | ARM_CP_IO,
74
+ }
97
.writefn = pmswinc_write },
75
+ mergemask(&d[H4(e)], r, mask);
98
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
76
+ }
99
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
77
+ }
100
.access = PL0_W, .accessfn = pmreg_access_swinc,
78
+ mve_advance_vpt(env);
101
+ .fgt = FGT_PMSWINC_EL0,
79
+ return rdm;
102
.type = ARM_CP_NO_RAW | ARM_CP_IO,
80
+}
103
.writefn = pmswinc_write },
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
104
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
82
index XXXXXXX..XXXXXXX 100644
105
.access = PL0_RW, .type = ARM_CP_ALIAS,
83
--- a/target/arm/translate-mve.c
106
+ .fgt = FGT_PMSELR_EL0,
84
+++ b/target/arm/translate-mve.c
107
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
108
.accessfn = pmreg_access_selr, .writefn = pmselr_write,
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
109
.raw_writefn = raw_write},
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
110
{ .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64,
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
111
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5,
89
+
112
.access = PL0_RW, .accessfn = pmreg_access_selr,
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
113
+ .fgt = FGT_PMSELR_EL0,
91
+{
114
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
92
+ /*
115
.writefn = pmselr_write, .raw_writefn = raw_write, },
93
+ * Whole Vector Left Shift with Carry. The carry is taken
116
{ .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
94
+ * from a general purpose register and written back there.
117
.access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
95
+ * An imm of 0 means "shift by 32".
118
+ .fgt = FGT_PMCCNTR_EL0,
96
+ */
119
.readfn = pmccntr_read, .writefn = pmccntr_write32,
97
+ TCGv_ptr qd;
120
.accessfn = pmreg_access_ccntr },
98
+ TCGv_i32 rdm;
121
{ .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
99
+
122
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
123
.access = PL0_RW, .accessfn = pmreg_access_ccntr,
101
+ return false;
124
+ .fgt = FGT_PMCCNTR_EL0,
102
+ }
125
.type = ARM_CP_IO,
103
+ if (a->rdm == 13 || a->rdm == 15) {
126
.fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
127
.readfn = pmccntr_read, .writefn = pmccntr_write,
105
+ return false;
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
106
+ }
129
{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
130
.writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
108
+ return true;
131
.access = PL0_RW, .accessfn = pmreg_access,
109
+ }
132
+ .fgt = FGT_PMCCFILTR_EL0,
110
+
133
.type = ARM_CP_ALIAS | ARM_CP_IO,
111
+ qd = mve_qreg_ptr(a->qd);
134
.resetvalue = 0, },
112
+ rdm = load_reg(s, a->rdm);
135
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
136
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
114
+ store_reg(s, a->rdm, rdm);
137
.writefn = pmccfiltr_write, .raw_writefn = raw_write,
115
+ tcg_temp_free_ptr(qd);
138
.access = PL0_RW, .accessfn = pmreg_access,
116
+ mve_update_eci(s);
139
+ .fgt = FGT_PMCCFILTR_EL0,
117
+ return true;
140
.type = ARM_CP_IO,
118
+}
141
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
142
.resetvalue = 0, },
143
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
144
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
145
.accessfn = pmreg_access,
146
+ .fgt = FGT_PMEVTYPERN_EL0,
147
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
148
{ .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
149
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
150
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
151
.accessfn = pmreg_access,
152
+ .fgt = FGT_PMEVTYPERN_EL0,
153
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
154
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
155
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
156
.accessfn = pmreg_access_xevcntr,
157
+ .fgt = FGT_PMEVCNTRN_EL0,
158
.writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
159
{ .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
160
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
161
.access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
162
.accessfn = pmreg_access_xevcntr,
163
+ .fgt = FGT_PMEVCNTRN_EL0,
164
.writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
165
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
166
.access = PL0_R | PL1_RW, .accessfn = access_tpm,
167
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
168
.writefn = pmuserenr_write, .raw_writefn = raw_write },
169
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
170
.access = PL1_RW, .accessfn = access_tpm,
171
+ .fgt = FGT_PMINTEN,
172
.type = ARM_CP_ALIAS | ARM_CP_IO,
173
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
174
.resetvalue = 0,
175
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
176
{ .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
177
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
178
.access = PL1_RW, .accessfn = access_tpm,
179
+ .fgt = FGT_PMINTEN,
180
.type = ARM_CP_IO,
181
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
182
.writefn = pmintenset_write, .raw_writefn = raw_write,
183
.resetvalue = 0x0 },
184
{ .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
185
.access = PL1_RW, .accessfn = access_tpm,
186
+ .fgt = FGT_PMINTEN,
187
.type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
188
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
189
.writefn = pmintenclr_write, },
190
{ .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
191
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
192
.access = PL1_RW, .accessfn = access_tpm,
193
+ .fgt = FGT_PMINTEN,
194
.type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
195
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
196
.writefn = pmintenclr_write },
197
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
198
/* PMOVSSET is not implemented in v7 before v7ve */
199
{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
200
.access = PL0_RW, .accessfn = pmreg_access,
201
+ .fgt = FGT_PMOVS,
202
.type = ARM_CP_ALIAS | ARM_CP_IO,
203
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
204
.writefn = pmovsset_write,
205
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
206
{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
207
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
208
.access = PL0_RW, .accessfn = pmreg_access,
209
+ .fgt = FGT_PMOVS,
210
.type = ARM_CP_ALIAS | ARM_CP_IO,
211
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
212
.writefn = pmovsset_write,
213
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
214
ARMCPRegInfo pmcr = {
215
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
216
.access = PL0_RW,
217
+ .fgt = FGT_PMCR_EL0,
218
.type = ARM_CP_IO | ARM_CP_ALIAS,
219
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
220
.accessfn = pmreg_access, .writefn = pmcr_write,
221
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
222
.name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
223
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
224
.access = PL0_RW, .accessfn = pmreg_access,
225
+ .fgt = FGT_PMCR_EL0,
226
.type = ARM_CP_IO,
227
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
228
.resetvalue = cpu->isar.reset_pmcr_el0,
229
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
230
{ .name = pmevcntr_name, .cp = 15, .crn = 14,
231
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
232
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
233
+ .fgt = FGT_PMEVCNTRN_EL0,
234
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
235
.accessfn = pmreg_access_xevcntr },
236
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
237
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
238
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
239
.type = ARM_CP_IO,
240
+ .fgt = FGT_PMEVCNTRN_EL0,
241
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
242
.raw_readfn = pmevcntr_rawread,
243
.raw_writefn = pmevcntr_rawwrite },
244
{ .name = pmevtyper_name, .cp = 15, .crn = 14,
245
.crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
246
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
247
+ .fgt = FGT_PMEVTYPERN_EL0,
248
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
249
.accessfn = pmreg_access },
250
{ .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
251
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
252
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
253
+ .fgt = FGT_PMEVTYPERN_EL0,
254
.type = ARM_CP_IO,
255
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
256
.raw_writefn = pmevtyper_rawwrite },
257
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
258
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
259
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
260
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
261
+ .fgt = FGT_PMCEIDN_EL0,
262
.resetvalue = extract64(cpu->pmceid0, 32, 32) },
263
{ .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
264
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
265
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
266
+ .fgt = FGT_PMCEIDN_EL0,
267
.resetvalue = extract64(cpu->pmceid1, 32, 32) },
268
};
269
define_arm_cp_regs(cpu, v81_pmu_regs);
270
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
271
.name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
272
.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
273
.access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
274
+ .fgt = FGT_PMMIR_EL1,
275
.resetvalue = 0
276
};
277
define_one_arm_cp_reg(cpu, &v84_pmmir);
278
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
279
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
280
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
281
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
282
+ .fgt = FGT_PMCEIDN_EL0,
283
.resetvalue = extract64(cpu->pmceid0, 0, 32) },
284
{ .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
285
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
286
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
287
+ .fgt = FGT_PMCEIDN_EL0,
288
.resetvalue = cpu->pmceid0 },
289
{ .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
290
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
291
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
292
+ .fgt = FGT_PMCEIDN_EL0,
293
.resetvalue = extract64(cpu->pmceid1, 0, 32) },
294
{ .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
295
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
296
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
297
+ .fgt = FGT_PMCEIDN_EL0,
298
.resetvalue = cpu->pmceid1 },
299
};
300
#ifdef CONFIG_USER_ONLY
119
--
301
--
120
2.20.1
302
2.34.1
121
122
diff view generated by jsdifflib
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
1
Mark up the sysreg definitions for the system instructions
2
2
trapped by HFGITR bits 0..11. These bits cover various
3
do_urshr() is borrowed from sve_helper.c.
3
cache maintenance operations.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
7
Tested-by: Fuad Tabba <tabba@google.com>
8
Message-id: 20230130182459.3309057-17-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-17-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper-mve.h | 10 ++++++++++
11
target/arm/cpregs.h | 14 ++++++++++++++
10
target/arm/mve.decode | 11 +++++++++++
12
target/arm/helper.c | 28 ++++++++++++++++++++++++++++
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
13
2 files changed, 42 insertions(+)
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
14
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
17
--- a/target/arm/cpregs.h
18
+++ b/target/arm/helper-mve.h
18
+++ b/target/arm/cpregs.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
DO_BIT(HDFGWTR, PMCR_EL0),
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DO_BIT(HDFGRTR, PMMIR_EL1),
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DO_BIT(HDFGRTR, PMCEIDN_EL0),
23
+
23
+
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+ /* Trap bits in HFGITR_EL2, starting from bit 0 */
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+ DO_BIT(HFGITR, ICIALLUIS),
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+ DO_BIT(HFGITR, ICIALLU),
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+ DO_BIT(HFGITR, ICIVAU),
28
+
28
+ DO_BIT(HFGITR, DCIVAC),
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+ DO_BIT(HFGITR, DCISW),
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ DO_BIT(HFGITR, DCCSW),
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ DO_BIT(HFGITR, DCCISW),
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ DO_BIT(HFGITR, DCCVAU),
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
33
+ DO_BIT(HFGITR, DCCVAP),
34
+ DO_BIT(HFGITR, DCCVADP),
35
+ DO_BIT(HFGITR, DCCIVAC),
36
+ DO_BIT(HFGITR, DCZVA),
37
} FGTBit;
38
39
#undef DO_BIT
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
42
--- a/target/arm/helper.c
36
+++ b/target/arm/mve.decode
43
+++ b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
#ifndef CONFIG_USER_ONLY
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
/* Avoid overhead of an access check that always passes in user-mode */
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
.accessfn = aa64_zva_access,
41
+
48
+ .fgt = FGT_DCZVA,
42
+# Narrowing shifts (which only support b and h sizes)
49
#endif
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
50
},
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
51
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
53
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
47
+
54
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
55
.access = PL1_W, .type = ARM_CP_NOP,
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
56
+ .fgt = FGT_ICIALLUIS,
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
57
.accessfn = access_ticab },
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
58
{ .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
59
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
53
index XXXXXXX..XXXXXXX 100644
60
.access = PL1_W, .type = ARM_CP_NOP,
54
--- a/target/arm/mve_helper.c
61
+ .fgt = FGT_ICIALLU,
55
+++ b/target/arm/mve_helper.c
62
.accessfn = access_tocu },
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
63
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
57
64
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
58
DO_VSHLL_ALL(vshllb, false)
65
.access = PL0_W, .type = ARM_CP_NOP,
59
DO_VSHLL_ALL(vshllt, true)
66
+ .fgt = FGT_ICIVAU,
60
+
67
.accessfn = access_tocu },
61
+/*
68
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
62
+ * Narrowing right shifts, taking a double sized input, shifting it
69
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
63
+ * and putting the result in either the top or bottom half of the output.
70
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
71
+ .fgt = FGT_DCIVAC,
65
+ */
72
.type = ARM_CP_NOP },
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
73
{ .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
74
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
68
+ void *vm, uint32_t shift) \
75
+ .fgt = FGT_DCISW,
69
+ { \
76
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
70
+ LTYPE *m = vm; \
77
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
71
+ TYPE *d = vd; \
78
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
72
+ uint16_t mask = mve_element_mask(env); \
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
73
+ unsigned le; \
80
.accessfn = aa64_cacheop_poc_access },
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
81
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
82
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
83
+ .fgt = FGT_DCCSW,
77
+ } \
84
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
78
+ mve_advance_vpt(env); \
85
{ .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
79
+ }
86
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
80
+
87
.access = PL0_W, .type = ARM_CP_NOP,
81
+#define DO_VSHRN_ALL(OP, FN) \
88
+ .fgt = FGT_DCCVAU,
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
89
.accessfn = access_tocu },
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
90
{ .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
91
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
92
.access = PL0_W, .type = ARM_CP_NOP,
86
+
93
+ .fgt = FGT_DCCIVAC,
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
94
.accessfn = aa64_cacheop_poc_access },
88
+{
95
{ .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
89
+ if (likely(sh < 64)) {
96
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
97
+ .fgt = FGT_DCCISW,
91
+ } else if (sh == 64) {
98
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
92
+ return x >> 63;
99
/* TLBI operations */
93
+ } else {
100
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
94
+ return 0;
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
95
+ }
102
{ .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
96
+}
103
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
97
+
104
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
105
+ .fgt = FGT_DCCVAP,
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
106
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
};
101
index XXXXXXX..XXXXXXX 100644
108
102
--- a/target/arm/translate-mve.c
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
103
+++ b/target/arm/translate-mve.c
110
{ .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
111
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
105
DO_VSHLL(VSHLL_BU, vshllbu)
112
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
106
DO_VSHLL(VSHLL_TS, vshllts)
113
+ .fgt = FGT_DCCVADP,
107
DO_VSHLL(VSHLL_TU, vshlltu)
114
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
108
+
115
};
109
+#define DO_2SHIFT_N(INSN, FN) \
116
#endif /*CONFIG_USER_ONLY*/
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
117
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
111
+ { \
118
{ .name = "DC_IGVAC", .state = ARM_CP_STATE_AA64,
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
119
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 3,
113
+ gen_helper_mve_##FN##b, \
120
.type = ARM_CP_NOP, .access = PL1_W,
114
+ gen_helper_mve_##FN##h, \
121
+ .fgt = FGT_DCIVAC,
115
+ }; \
122
.accessfn = aa64_cacheop_poc_access },
116
+ return do_2shift(s, a, fns[a->size], false); \
123
{ .name = "DC_IGSW", .state = ARM_CP_STATE_AA64,
117
+ }
124
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 4,
118
+
125
+ .fgt = FGT_DCISW,
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
126
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
127
{ .name = "DC_IGDVAC", .state = ARM_CP_STATE_AA64,
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
128
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 5,
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
129
.type = ARM_CP_NOP, .access = PL1_W,
130
+ .fgt = FGT_DCIVAC,
131
.accessfn = aa64_cacheop_poc_access },
132
{ .name = "DC_IGDSW", .state = ARM_CP_STATE_AA64,
133
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 6,
134
+ .fgt = FGT_DCISW,
135
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
136
{ .name = "DC_CGSW", .state = ARM_CP_STATE_AA64,
137
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 4,
138
+ .fgt = FGT_DCCSW,
139
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
140
{ .name = "DC_CGDSW", .state = ARM_CP_STATE_AA64,
141
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 6,
142
+ .fgt = FGT_DCCSW,
143
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
144
{ .name = "DC_CIGSW", .state = ARM_CP_STATE_AA64,
145
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 4,
146
+ .fgt = FGT_DCCISW,
147
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
148
{ .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
149
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
150
+ .fgt = FGT_DCCISW,
151
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
152
};
153
154
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
155
{ .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
156
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
157
.type = ARM_CP_NOP, .access = PL0_W,
158
+ .fgt = FGT_DCCVAP,
159
.accessfn = aa64_cacheop_poc_access },
160
{ .name = "DC_CGDVAP", .state = ARM_CP_STATE_AA64,
161
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 5,
162
.type = ARM_CP_NOP, .access = PL0_W,
163
+ .fgt = FGT_DCCVAP,
164
.accessfn = aa64_cacheop_poc_access },
165
{ .name = "DC_CGVADP", .state = ARM_CP_STATE_AA64,
166
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 3,
167
.type = ARM_CP_NOP, .access = PL0_W,
168
+ .fgt = FGT_DCCVADP,
169
.accessfn = aa64_cacheop_poc_access },
170
{ .name = "DC_CGDVADP", .state = ARM_CP_STATE_AA64,
171
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 5,
172
.type = ARM_CP_NOP, .access = PL0_W,
173
+ .fgt = FGT_DCCVADP,
174
.accessfn = aa64_cacheop_poc_access },
175
{ .name = "DC_CIGVAC", .state = ARM_CP_STATE_AA64,
176
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 3,
177
.type = ARM_CP_NOP, .access = PL0_W,
178
+ .fgt = FGT_DCCIVAC,
179
.accessfn = aa64_cacheop_poc_access },
180
{ .name = "DC_CIGDVAC", .state = ARM_CP_STATE_AA64,
181
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5,
182
.type = ARM_CP_NOP, .access = PL0_W,
183
+ .fgt = FGT_DCCIVAC,
184
.accessfn = aa64_cacheop_poc_access },
185
{ .name = "DC_GVA", .state = ARM_CP_STATE_AA64,
186
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 3,
187
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
188
#ifndef CONFIG_USER_ONLY
189
/* Avoid overhead of an access check that always passes in user-mode */
190
.accessfn = aa64_zva_access,
191
+ .fgt = FGT_DCZVA,
192
#endif
193
},
194
{ .name = "DC_GZVA", .state = ARM_CP_STATE_AA64,
195
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
196
#ifndef CONFIG_USER_ONLY
197
/* Avoid overhead of an access check that always passes in user-mode */
198
.accessfn = aa64_zva_access,
199
+ .fgt = FGT_DCZVA,
200
#endif
201
},
202
};
123
--
203
--
124
2.20.1
204
2.34.1
125
126
diff view generated by jsdifflib
1
Implement the MVE VSRI and VSLI insns, which perform a
1
Mark up the sysreg definitions for the system instructions
2
shift-and-insert operation.
2
trapped by HFGITR bits 12..17. These bits cover AT address
3
translation instructions.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
7
Tested-by: Fuad Tabba <tabba@google.com>
8
Message-id: 20230130182459.3309057-18-peter.maydell@linaro.org
9
Message-id: 20230127175507.2895013-18-peter.maydell@linaro.org
7
---
10
---
8
target/arm/helper-mve.h | 8 ++++++++
11
target/arm/cpregs.h | 6 ++++++
9
target/arm/mve.decode | 9 ++++++++
12
target/arm/helper.c | 6 ++++++
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
13
2 files changed, 12 insertions(+)
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
13
14
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-mve.h
17
--- a/target/arm/cpregs.h
17
+++ b/target/arm/helper-mve.h
18
+++ b/target/arm/cpregs.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
DO_BIT(HFGITR, DCCVADP),
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DO_BIT(HFGITR, DCCIVAC),
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DO_BIT(HFGITR, DCZVA),
22
+
23
+ DO_BIT(HFGITR, ATS1E1R),
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+ DO_BIT(HFGITR, ATS1E1W),
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+ DO_BIT(HFGITR, ATS1E0R),
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+ DO_BIT(HFGITR, ATS1E0W),
26
+
27
+ DO_BIT(HFGITR, ATS1E1RP),
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ DO_BIT(HFGITR, ATS1E1WP),
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
} FGTBit;
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
#undef DO_BIT
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
34
--- a/target/arm/helper.c
33
+++ b/target/arm/mve.decode
35
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
35
37
{ .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
38
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
39
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
38
+
40
+ .fgt = FGT_ATS1E1R,
39
+# Shift-and-insert
41
.writefn = ats_write64 },
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
42
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
43
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
44
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
43
+
45
+ .fgt = FGT_ATS1E1W,
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
46
.writefn = ats_write64 },
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
47
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
48
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
49
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
48
index XXXXXXX..XXXXXXX 100644
50
+ .fgt = FGT_ATS1E0R,
49
--- a/target/arm/mve_helper.c
51
.writefn = ats_write64 },
50
+++ b/target/arm/mve_helper.c
52
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
53
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
54
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
55
+ .fgt = FGT_ATS1E0W,
54
56
.writefn = ats_write64 },
55
+/* Shift-and-insert; we always work with 64 bits at a time */
57
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
58
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
59
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
58
+ void *vm, uint32_t shift) \
60
{ .name = "AT_S1E1RP", .state = ARM_CP_STATE_AA64,
59
+ { \
61
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
60
+ uint64_t *d = vd, *m = vm; \
62
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
61
+ uint16_t mask; \
63
+ .fgt = FGT_ATS1E1RP,
62
+ uint64_t shiftmask; \
64
.writefn = ats_write64 },
63
+ unsigned e; \
65
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
64
+ if (shift == 0 || shift == ESIZE * 8) { \
66
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
65
+ /* \
67
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
68
+ .fgt = FGT_ATS1E1WP,
67
+ * The generic logic would give the right answer for 0 but \
69
.writefn = ats_write64 },
68
+ * fails for <dt>. \
70
};
69
+ */ \
71
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
114
--
72
--
115
2.20.1
73
2.34.1
116
117
diff view generated by jsdifflib
1
Implement the MVE VHLL (vector shift left long) insn. This has two
1
Mark up the sysreg definitions for the system instructions
2
encodings: the T1 encoding is the usual shift-by-immediate format,
2
trapped by HFGITR bits 18..47. These bits cover TLBI
3
and the T2 encoding is a special case where the shift count is always
3
TLB maintenance instructions.
4
equal to the element size.
4
5
(If we implemented FEAT_XS we would need to trap some of the
6
instructions added by that feature using these bits; but we don't
7
yet, so will need to add the .fgt markup when we do.)
5
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
11
Tested-by: Fuad Tabba <tabba@google.com>
12
Message-id: 20230130182459.3309057-19-peter.maydell@linaro.org
13
Message-id: 20230127175507.2895013-19-peter.maydell@linaro.org
9
---
14
---
10
target/arm/helper-mve.h | 9 +++++++
15
target/arm/cpregs.h | 30 ++++++++++++++++++++++++++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
16
target/arm/helper.c | 30 ++++++++++++++++++++++++++++++
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
17
2 files changed, 60 insertions(+)
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
15
18
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
21
--- a/target/arm/cpregs.h
19
+++ b/target/arm/helper-mve.h
22
+++ b/target/arm/cpregs.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
DO_BIT(HFGITR, ATS1E0W),
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
DO_BIT(HFGITR, ATS1E1RP),
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
DO_BIT(HFGITR, ATS1E1WP),
24
+
27
+ DO_BIT(HFGITR, TLBIVMALLE1OS),
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ DO_BIT(HFGITR, TLBIVAE1OS),
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+ DO_BIT(HFGITR, TLBIASIDE1OS),
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ DO_BIT(HFGITR, TLBIVAAE1OS),
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ DO_BIT(HFGITR, TLBIVALE1OS),
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ DO_BIT(HFGITR, TLBIVAALE1OS),
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ DO_BIT(HFGITR, TLBIRVAE1OS),
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ DO_BIT(HFGITR, TLBIRVAAE1OS),
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ DO_BIT(HFGITR, TLBIRVALE1OS),
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
36
+ DO_BIT(HFGITR, TLBIRVAALE1OS),
37
+ DO_BIT(HFGITR, TLBIVMALLE1IS),
38
+ DO_BIT(HFGITR, TLBIVAE1IS),
39
+ DO_BIT(HFGITR, TLBIASIDE1IS),
40
+ DO_BIT(HFGITR, TLBIVAAE1IS),
41
+ DO_BIT(HFGITR, TLBIVALE1IS),
42
+ DO_BIT(HFGITR, TLBIVAALE1IS),
43
+ DO_BIT(HFGITR, TLBIRVAE1IS),
44
+ DO_BIT(HFGITR, TLBIRVAAE1IS),
45
+ DO_BIT(HFGITR, TLBIRVALE1IS),
46
+ DO_BIT(HFGITR, TLBIRVAALE1IS),
47
+ DO_BIT(HFGITR, TLBIRVAE1),
48
+ DO_BIT(HFGITR, TLBIRVAAE1),
49
+ DO_BIT(HFGITR, TLBIRVALE1),
50
+ DO_BIT(HFGITR, TLBIRVAALE1),
51
+ DO_BIT(HFGITR, TLBIVMALLE1),
52
+ DO_BIT(HFGITR, TLBIVAE1),
53
+ DO_BIT(HFGITR, TLBIASIDE1),
54
+ DO_BIT(HFGITR, TLBIVAAE1),
55
+ DO_BIT(HFGITR, TLBIVALE1),
56
+ DO_BIT(HFGITR, TLBIVAALE1),
57
} FGTBit;
58
59
#undef DO_BIT
60
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
62
--- a/target/arm/helper.c
36
+++ b/target/arm/mve.decode
63
+++ b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
65
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
66
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
40
67
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
68
+ .fgt = FGT_TLBIVMALLE1IS,
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
69
.writefn = tlbi_aa64_vmalle1is_write },
43
+# VSHLL encoding T2 where shift == esize
70
{ .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
71
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
45
+ qd=%qd qm=%qm size=0 shift=8
72
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
73
+ .fgt = FGT_TLBIVAE1IS,
47
+ qd=%qd qm=%qm size=1 shift=16
74
.writefn = tlbi_aa64_vae1is_write },
48
+
75
{ .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
76
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
50
%rshift_i5 16:5 !function=rsub_32
77
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
51
%rshift_i4 16:4 !function=rsub_16
78
+ .fgt = FGT_TLBIASIDE1IS,
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
79
.writefn = tlbi_aa64_vmalle1is_write },
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
80
{ .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
81
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
55
82
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
83
+ .fgt = FGT_TLBIVAAE1IS,
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
84
.writefn = tlbi_aa64_vae1is_write },
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
85
{ .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
59
+# overlaps what would be size=0b11 VMULH/VRMULH
86
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
60
+{
87
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
88
+ .fgt = FGT_TLBIVALE1IS,
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
89
.writefn = tlbi_aa64_vae1is_write },
63
90
{ .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
91
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
92
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
93
+ .fgt = FGT_TLBIVAALE1IS,
67
+}
94
.writefn = tlbi_aa64_vae1is_write },
68
+
95
{ .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
69
+{
96
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
97
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
98
+ .fgt = FGT_TLBIVMALLE1,
72
+
99
.writefn = tlbi_aa64_vmalle1_write },
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
100
{ .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
74
+}
101
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
75
+
102
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
76
+{
103
+ .fgt = FGT_TLBIVAE1,
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
104
.writefn = tlbi_aa64_vae1_write },
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
105
{ .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
79
+
106
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
107
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
81
+}
108
+ .fgt = FGT_TLBIASIDE1,
82
+
109
.writefn = tlbi_aa64_vmalle1_write },
83
+{
110
{ .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
111
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
112
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
86
+
113
+ .fgt = FGT_TLBIVAAE1,
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
114
.writefn = tlbi_aa64_vae1_write },
88
+}
115
{ .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
89
116
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
117
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
118
+ .fgt = FGT_TLBIVALE1,
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
.writefn = tlbi_aa64_vae1_write },
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
120
{ .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
121
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
122
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
96
+
123
+ .fgt = FGT_TLBIVAALE1,
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
124
.writefn = tlbi_aa64_vae1_write },
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
125
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
126
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
100
+
127
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
128
{ .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
129
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
103
+
130
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
131
+ .fgt = FGT_TLBIRVAE1IS,
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
132
.writefn = tlbi_aa64_rvae1is_write },
106
+
133
{ .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
134
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
135
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
136
+ .fgt = FGT_TLBIRVAAE1IS,
110
index XXXXXXX..XXXXXXX 100644
137
.writefn = tlbi_aa64_rvae1is_write },
111
--- a/target/arm/mve_helper.c
138
{ .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
112
+++ b/target/arm/mve_helper.c
139
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
140
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
141
+ .fgt = FGT_TLBIRVALE1IS,
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
142
.writefn = tlbi_aa64_rvae1is_write },
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
143
{ .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
117
+
144
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
118
+/*
145
.access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW,
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
146
+ .fgt = FGT_TLBIRVAALE1IS,
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
147
.writefn = tlbi_aa64_rvae1is_write },
121
+ * the input, and LESIZE, LTYPE for the output.
148
{ .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
149
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
123
+ * because the long shift is strictly left-only.
150
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
124
+ */
151
+ .fgt = FGT_TLBIRVAE1OS,
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
152
.writefn = tlbi_aa64_rvae1is_write },
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
153
{ .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
127
+ void *vm, uint32_t shift) \
154
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
128
+ { \
155
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
129
+ LTYPE *d = vd; \
156
+ .fgt = FGT_TLBIRVAAE1OS,
130
+ TYPE *m = vm; \
157
.writefn = tlbi_aa64_rvae1is_write },
131
+ uint16_t mask = mve_element_mask(env); \
158
{ .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
132
+ unsigned le; \
159
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
133
+ assert(shift <= 16); \
160
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
161
+ .fgt = FGT_TLBIRVALE1OS,
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
162
.writefn = tlbi_aa64_rvae1is_write },
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
163
{ .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
137
+ } \
164
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
138
+ mve_advance_vpt(env); \
165
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
139
+ }
166
+ .fgt = FGT_TLBIRVAALE1OS,
140
+
167
.writefn = tlbi_aa64_rvae1is_write },
141
+#define DO_VSHLL_ALL(OP, TOP) \
168
{ .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
169
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
170
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
171
+ .fgt = FGT_TLBIRVAE1,
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
172
.writefn = tlbi_aa64_rvae1_write },
146
+
173
{ .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
147
+DO_VSHLL_ALL(vshllb, false)
174
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
148
+DO_VSHLL_ALL(vshllt, true)
175
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
176
+ .fgt = FGT_TLBIRVAAE1,
150
index XXXXXXX..XXXXXXX 100644
177
.writefn = tlbi_aa64_rvae1_write },
151
--- a/target/arm/translate-mve.c
178
{ .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
152
+++ b/target/arm/translate-mve.c
179
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
180
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
181
+ .fgt = FGT_TLBIRVALE1,
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
182
.writefn = tlbi_aa64_rvae1_write },
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
183
{ .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
157
+
184
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
158
+#define DO_VSHLL(INSN, FN) \
185
.access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
186
+ .fgt = FGT_TLBIRVAALE1,
160
+ { \
187
.writefn = tlbi_aa64_rvae1_write },
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
188
{ .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
162
+ gen_helper_mve_##FN##b, \
189
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
163
+ gen_helper_mve_##FN##h, \
190
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
164
+ }; \
191
{ .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
165
+ return do_2shift(s, a, fns[a->size], false); \
192
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
166
+ }
193
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
167
+
194
+ .fgt = FGT_TLBIVMALLE1OS,
168
+DO_VSHLL(VSHLL_BS, vshllbs)
195
.writefn = tlbi_aa64_vmalle1is_write },
169
+DO_VSHLL(VSHLL_BU, vshllbu)
196
{ .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64,
170
+DO_VSHLL(VSHLL_TS, vshllts)
197
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1,
171
+DO_VSHLL(VSHLL_TU, vshlltu)
198
+ .fgt = FGT_TLBIVAE1OS,
199
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
200
.writefn = tlbi_aa64_vae1is_write },
201
{ .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
202
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
203
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
204
+ .fgt = FGT_TLBIASIDE1OS,
205
.writefn = tlbi_aa64_vmalle1is_write },
206
{ .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64,
207
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3,
208
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
209
+ .fgt = FGT_TLBIVAAE1OS,
210
.writefn = tlbi_aa64_vae1is_write },
211
{ .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64,
212
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5,
213
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
214
+ .fgt = FGT_TLBIVALE1OS,
215
.writefn = tlbi_aa64_vae1is_write },
216
{ .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64,
217
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7,
218
.access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW,
219
+ .fgt = FGT_TLBIVAALE1OS,
220
.writefn = tlbi_aa64_vae1is_write },
221
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
222
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
172
--
223
--
173
2.20.1
224
2.34.1
174
175
diff view generated by jsdifflib
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
1
Mark up the sysreg definitions for the system instructions
2
and VQSHLU.
2
trapped by HFGITR bits 48..63.
3
3
4
The size-and-immediate encoding here is the same as Neon, and we
4
Some of these bits are for trapping instructions which are
5
handle it the same way neon-dp.decode does.
5
not in the system instruction encoding (i.e. which are
6
not handled by the ARMCPRegInfo mechanism):
7
* ERET, ERETAA, ERETAB
8
* SVC
9
10
We will have to handle those separately and manually.
6
11
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
14
Tested-by: Fuad Tabba <tabba@google.com>
15
Message-id: 20230130182459.3309057-20-peter.maydell@linaro.org
16
Message-id: 20230127175507.2895013-20-peter.maydell@linaro.org
10
---
17
---
11
target/arm/helper-mve.h | 16 +++++++++++
18
target/arm/cpregs.h | 4 ++++
12
target/arm/mve.decode | 23 +++++++++++++++
19
target/arm/helper.c | 9 +++++++++
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
20
2 files changed, 13 insertions(+)
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
4 files changed, 147 insertions(+)
16
21
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-mve.h
24
--- a/target/arm/cpregs.h
20
+++ b/target/arm/helper-mve.h
25
+++ b/target/arm/cpregs.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ typedef enum FGTBit {
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
DO_BIT(HFGITR, TLBIVAAE1),
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DO_BIT(HFGITR, TLBIVALE1),
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
DO_BIT(HFGITR, TLBIVAALE1),
25
+
30
+ DO_BIT(HFGITR, CFPRCTX),
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ DO_BIT(HFGITR, DVPRCTX),
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ DO_BIT(HFGITR, CPPRCTX),
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ DO_BIT(HFGITR, DCCVAC),
29
+
34
} FGTBit;
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
#undef DO_BIT
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
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
38
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
39
--- a/target/arm/helper.c
44
+++ b/target/arm/mve.decode
40
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
46
&2op qd qm qn size
42
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
47
&2scalar qd qn rm size
43
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
48
&1imm qd imm cmode op
44
.access = PL0_W, .type = ARM_CP_NOP,
49
+&2shift qd qm shift size
45
+ .fgt = FGT_DCCVAC,
50
46
.accessfn = aa64_cacheop_poc_access },
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
47
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
52
# Note that both Rn and Qd are 3 bits only (no D bit)
48
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
53
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
50
{ .name = "DC_CGVAC", .state = ARM_CP_STATE_AA64,
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
51
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 3,
56
52
.type = ARM_CP_NOP, .access = PL0_W,
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
53
+ .fgt = FGT_DCCVAC,
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
54
.accessfn = aa64_cacheop_poc_access },
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
55
{ .name = "DC_CGDVAC", .state = ARM_CP_STATE_AA64,
60
+
56
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 5,
61
# Vector loads and stores
57
.type = ARM_CP_NOP, .access = PL0_W,
62
58
+ .fgt = FGT_DCCVAC,
63
# Widening loads and narrowing stores:
59
.accessfn = aa64_cacheop_poc_access },
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
60
{ .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
65
# So we have a single decode line and check the cmode/op in the
61
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
66
# trans function.
62
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
63
static const ARMCPRegInfo predinv_reginfo[] = {
68
+
64
{ .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
69
+# Shifts by immediate
65
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
70
+
66
+ .fgt = FGT_CFPRCTX,
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
67
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
68
{ .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
69
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
74
+
70
+ .fgt = FGT_DVPRCTX,
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
71
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
72
{ .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
73
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
78
+
74
+ .fgt = FGT_CPPRCTX,
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
75
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
76
/*
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
77
* Note the AArch32 opcodes have a different OPC1.
82
+
78
*/
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
79
{ .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
80
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
81
+ .fgt = FGT_CFPRCTX,
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
82
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
87
index XXXXXXX..XXXXXXX 100644
83
{ .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
88
--- a/target/arm/mve_helper.c
84
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
89
+++ b/target/arm/mve_helper.c
85
+ .fgt = FGT_DVPRCTX,
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
86
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
87
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
92
#define DO_UQRSHL_OP(N, M, satp) \
88
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
89
+ .fgt = FGT_CPPRCTX,
94
+#define DO_SUQSHL_OP(N, M, satp) \
90
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
91
};
96
92
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
177
+{
178
+ TCGv_ptr qd, qm;
179
+ int shift = a->shift;
180
+
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
189
+
190
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
192
+ * which permits a negative shift count to indicate a right-shift,
193
+ * we must negate the shift count.
194
+ */
195
+ if (negateshift) {
196
+ shift = -shift;
197
+ }
198
+
199
+ qd = mve_qreg_ptr(a->qd);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
206
+}
207
+
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
210
+ { \
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
212
+ gen_helper_mve_##FN##b, \
213
+ gen_helper_mve_##FN##h, \
214
+ gen_helper_mve_##FN##w, \
215
+ NULL, \
216
+ }; \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
218
+ }
219
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
224
--
93
--
225
2.20.1
94
2.34.1
226
227
diff view generated by jsdifflib
1
Use dup_const() instead of bitfield_replicate() in
1
Implement the HFGITR_EL2.ERET fine-grained trap. This traps
2
disas_simd_mod_imm().
2
execution from AArch64 EL1 of ERET, ERETAA and ERETAB. The trap is
3
reported with a syndrome value of 0x1a.
3
4
4
(We can't replace the other use of bitfield_replicate() in this file,
5
The trap must take precedence over a possible pointer-authentication
5
in logic_imm_decode_wmask(), because that location needs to handle 2
6
trap for ERETAA and ERETAB.
6
and 4 bit elements, which dup_const() cannot.)
7
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
10
Tested-by: Fuad Tabba <tabba@google.com>
11
Message-id: 20230130182459.3309057-21-peter.maydell@linaro.org
12
Message-id: 20230127175507.2895013-21-peter.maydell@linaro.org
11
---
13
---
12
target/arm/translate-a64.c | 2 +-
14
target/arm/cpu.h | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/arm/syndrome.h | 10 ++++++++++
16
target/arm/translate.h | 2 ++
17
target/arm/helper.c | 3 +++
18
target/arm/translate-a64.c | 10 ++++++++++
19
5 files changed, 26 insertions(+)
14
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
26
FIELD(TBFLAG_A64, SVL, 24, 4)
27
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
28
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
29
+FIELD(TBFLAG_A64, FGT_ERET, 29, 1)
30
31
/*
32
* Helpers for using the above.
33
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/syndrome.h
36
+++ b/target/arm/syndrome.h
37
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
38
EC_AA64_SMC = 0x17,
39
EC_SYSTEMREGISTERTRAP = 0x18,
40
EC_SVEACCESSTRAP = 0x19,
41
+ EC_ERETTRAP = 0x1a,
42
EC_SMETRAP = 0x1d,
43
EC_INSNABORT = 0x20,
44
EC_INSNABORT_SAME_EL = 0x21,
45
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
46
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
47
}
48
49
+/*
50
+ * eret_op is bits [1:0] of the ERET instruction, so:
51
+ * 0 for ERET, 2 for ERETAA, 3 for ERETAB.
52
+ */
53
+static inline uint32_t syn_erettrap(int eret_op)
54
+{
55
+ return (EC_ERETTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL | eret_op;
56
+}
57
+
58
static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
59
{
60
return (EC_SMETRAP << ARM_EL_EC_SHIFT)
61
diff --git a/target/arm/translate.h b/target/arm/translate.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate.h
64
+++ b/target/arm/translate.h
65
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
66
bool mve_no_pred;
67
/* True if fine-grained traps are active */
68
bool fgt_active;
69
+ /* True if fine-grained trap on ERET is enabled */
70
+ bool fgt_eret;
71
/*
72
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
73
* < 0, set by the current instruction.
74
diff --git a/target/arm/helper.c b/target/arm/helper.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/helper.c
77
+++ b/target/arm/helper.c
78
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
79
80
if (arm_fgt_active(env, el)) {
81
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
82
+ if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
83
+ DP_TBFLAG_A64(flags, FGT_ERET, 1);
84
+ }
85
}
86
87
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
89
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
90
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
91
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
92
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
20
/* FMOV (vector, immediate) - half-precision */
93
if (op4 != 0) {
21
imm = vfp_expand_imm(MO_16, abcdefgh);
94
goto do_unallocated;
22
/* now duplicate across the lanes */
95
}
23
- imm = bitfield_replicate(imm, 16);
96
+ if (s->fgt_eret) {
24
+ imm = dup_const(MO_16, imm);
97
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
25
} else {
98
+ return;
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
99
+ }
27
}
100
dst = tcg_temp_new_i64();
101
tcg_gen_ld_i64(dst, cpu_env,
102
offsetof(CPUARMState, elr_el[s->current_el]));
103
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
104
if (rn != 0x1f || op4 != 0x1f) {
105
goto do_unallocated;
106
}
107
+ /* The FGT trap takes precedence over an auth trap. */
108
+ if (s->fgt_eret) {
109
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
110
+ return;
111
+ }
112
dst = tcg_temp_new_i64();
113
tcg_gen_ld_i64(dst, cpu_env,
114
offsetof(CPUARMState, elr_el[s->current_el]));
115
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
116
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
117
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
118
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
119
+ dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
120
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
121
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
122
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
28
--
123
--
29
2.20.1
124
2.34.1
30
31
diff view generated by jsdifflib
1
The MVE extension to v8.1M includes some new shift instructions which
1
Implement the HFGITR_EL2.SVC_EL0 and SVC_EL1 fine-grained traps.
2
sit entirely within the non-coprocessor part of the encoding space
2
These trap execution of the SVC instruction from AArch32 and AArch64.
3
and which operate only on general-purpose registers. They take up
3
(As usual, AArch32 can only trap from EL0, as fine grained traps are
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
4
disabled with an AArch32 EL1.)
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
5
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
8
Tested-by: Fuad Tabba <tabba@google.com>
9
Message-id: 20230130182459.3309057-22-peter.maydell@linaro.org
10
Message-id: 20230127175507.2895013-22-peter.maydell@linaro.org
27
---
11
---
28
target/arm/helper-mve.h | 3 ++
12
target/arm/cpu.h | 1 +
29
target/arm/translate.h | 1 +
13
target/arm/translate.h | 2 ++
30
target/arm/t32.decode | 28 +++++++++++++
14
target/arm/helper.c | 20 ++++++++++++++++++++
31
target/arm/mve_helper.c | 10 +++++
15
target/arm/translate-a64.c | 9 ++++++++-
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 12 +++++++++---
33
5 files changed, 132 insertions(+)
17
5 files changed, 40 insertions(+), 4 deletions(-)
34
18
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
21
--- a/target/arm/cpu.h
38
+++ b/target/arm/helper-mve.h
22
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
FIELD(TBFLAG_ANY, ALIGN_MEM, 10, 1)
41
25
FIELD(TBFLAG_ANY, PSTATE__IL, 11, 1)
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
26
FIELD(TBFLAG_ANY, FGT_ACTIVE, 12, 1)
43
+
27
+FIELD(TBFLAG_ANY, FGT_SVC, 13, 1)
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
/*
30
* Bit usage when in AArch32 state, both A- and M-profile.
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
33
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
34
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
bool fgt_active;
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
/* True if fine-grained trap on ERET is enabled */
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
bool fgt_eret;
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
39
+ /* True if fine-grained trap on SVC is enabled */
55
40
+ bool fgt_svc;
56
/**
41
/*
57
* arm_tbflags_from_tb:
42
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
43
* < 0, set by the current instruction.
44
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
46
--- a/target/arm/helper.c
61
+++ b/target/arm/t32.decode
47
+++ b/target/arm/helper.c
62
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
63
&mcr !extern cp opc1 crn crm opc2 rt
49
return arm_mmu_idx_el(env, arm_current_el(env));
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
}
50
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
51
88
{
52
+static inline bool fgt_svc(CPUARMState *env, int el)
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
+{
53
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
54
+ /*
55
+ * Assuming fine-grained-traps are active, return true if we
56
+ * should be trapping on SVC instructions. Only AArch64 can
57
+ * trap on an SVC at EL1, but we don't need to special-case this
58
+ * because if this is AArch32 EL1 then arm_fgt_active() is false.
59
+ * We also know el is 0 or 1.
60
+ */
61
+ return el == 0 ?
62
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) :
63
+ FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1);
122
+}
64
+}
123
+
65
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
66
static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
125
+{
67
ARMMMUIdx mmu_idx,
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
68
CPUARMTBFlags flags)
127
+}
69
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
70
71
if (arm_fgt_active(env, el)) {
72
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
73
+ if (fgt_svc(env, el)) {
74
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
75
+ }
76
}
77
78
if (env->uncached_cpsr & CPSR_IL) {
79
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
80
if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
81
DP_TBFLAG_A64(flags, FGT_ERET, 1);
82
}
83
+ if (fgt_svc(env, el)) {
84
+ DP_TBFLAG_ANY(flags, FGT_SVC, 1);
85
+ }
86
}
87
88
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
89
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-a64.c
92
+++ b/target/arm/translate-a64.c
93
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
94
int opc = extract32(insn, 21, 3);
95
int op2_ll = extract32(insn, 0, 5);
96
int imm16 = extract32(insn, 5, 16);
97
+ uint32_t syndrome;
98
99
switch (opc) {
100
case 0:
101
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
102
*/
103
switch (op2_ll) {
104
case 1: /* SVC */
105
+ syndrome = syn_aa64_svc(imm16);
106
+ if (s->fgt_svc) {
107
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
108
+ break;
109
+ }
110
gen_ss_advance(s);
111
- gen_exception_insn(s, 4, EXCP_SWI, syn_aa64_svc(imm16));
112
+ gen_exception_insn(s, 4, EXCP_SWI, syndrome);
113
break;
114
case 2: /* HVC */
115
if (s->current_el == 0) {
116
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
117
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
118
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
119
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
120
+ dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
121
dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
122
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
123
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
126
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
127
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
128
@@ -XXX,XX +XXX,XX @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
129
(a->imm == semihost_imm)) {
130
gen_exception_internal_insn(s, EXCP_SEMIHOST);
131
} else {
132
- gen_update_pc(s, curr_insn_len(s));
133
- s->svc_imm = a->imm;
134
- s->base.is_jmp = DISAS_SWI;
135
+ if (s->fgt_svc) {
136
+ uint32_t syndrome = syn_aa32_svc(a->imm, s->thumb);
137
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
138
+ } else {
139
+ gen_update_pc(s, curr_insn_len(s));
140
+ s->svc_imm = a->imm;
141
+ s->base.is_jmp = DISAS_SWI;
142
+ }
143
}
133
return true;
144
return true;
134
}
145
}
135
146
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
136
+/*
147
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
137
+ * v8.1M MVE wide-shifts
148
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
138
+ */
149
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
150
+ dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
140
+ WideShiftImmFn *fn)
151
141
+{
152
if (arm_feature(env, ARM_FEATURE_M)) {
142
+ TCGv_i64 rda;
153
dc->vfp_enabled = 1;
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
*/
229
--
154
--
230
2.20.1
155
2.34.1
231
232
diff view generated by jsdifflib
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
1
FEAT_FGT also implements an extra trap bit in the MDCR_EL2 and
2
VORR and VBIC). These have essentially the same encoding
2
MDCR_EL3 registers: bit TDCC enables trapping of use of the Debug
3
as their Neon equivalents, and we implement the decode
3
Comms Channel registers OSDTRRX_EL1, OSDTRTX_EL1, MDCCSR_EL0,
4
in the same way.
4
MDCCINT_EL0, DBGDTR_EL0, DBGDTRRX_EL0 and DBGDTRTX_EL0 (and their
5
AArch32 equivalents). This trapping is independent of whether
6
fine-grained traps are enabled or not.
7
8
Implement these extra traps. (We don't implement DBGDTR_EL0,
9
DBGDTRRX_EL0 and DBGDTRTX_EL0.)
5
10
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
13
Tested-by: Fuad Tabba <tabba@google.com>
14
Message-id: 20230130182459.3309057-23-peter.maydell@linaro.org
15
Message-id: 20230127175507.2895013-23-peter.maydell@linaro.org
9
---
16
---
10
target/arm/helper-mve.h | 4 +++
17
target/arm/debug_helper.c | 35 +++++++++++++++++++++++++++++++----
11
target/arm/mve.decode | 17 +++++++++++++
18
1 file changed, 31 insertions(+), 4 deletions(-)
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
15
19
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
22
--- a/target/arm/debug_helper.c
19
+++ b/target/arm/helper-mve.h
23
+++ b/target/arm/debug_helper.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
25
return CP_ACCESS_OK;
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
}
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
28
+/*
29
+ * Check for traps to Debug Comms Channel registers. If FEAT_FGT
30
+ * is implemented then these are controlled by MDCR_EL2.TDCC for
31
+ * EL2 and MDCR_EL3.TDCC for EL3. They are also controlled by
32
+ * the general debug access trap bits MDCR_EL2.TDA and MDCR_EL3.TDA.
33
+ */
34
+static CPAccessResult access_tdcc(CPUARMState *env, const ARMCPRegInfo *ri,
35
+ bool isread)
36
+{
37
+ int el = arm_current_el(env);
38
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
39
+ bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
40
+ (arm_hcr_el2_eff(env) & HCR_TGE);
41
+ bool mdcr_el2_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
42
+ (mdcr_el2 & MDCR_TDCC);
43
+ bool mdcr_el3_tdcc = cpu_isar_feature(aa64_fgt, env_archcpu(env)) &&
44
+ (env->cp15.mdcr_el3 & MDCR_TDCC);
24
+
45
+
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
46
+ if (el < 2 && (mdcr_el2_tda || mdcr_el2_tdcc)) {
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
47
+ return CP_ACCESS_TRAP_EL2;
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
31
+++ b/target/arm/mve.decode
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
48
+ }
94
+
49
+ if (el < 3 && ((env->cp15.mdcr_el3 & MDCR_TDA) || mdcr_el3_tdcc)) {
95
+#define DO_MOVI(N, I) (I)
50
+ return CP_ACCESS_TRAP_EL3;
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
+ }
51
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
52
+ return CP_ACCESS_OK;
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
+}
53
+}
145
+
54
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
55
static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
147
+{
56
uint64_t value)
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
57
{
149
+ MVEGenOneOpImmFn *fn;
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
150
+
59
*/
151
+ if ((a->cmode & 1) && a->cmode < 12) {
60
{ .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
152
+ if (a->op) {
61
.opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
153
+ /*
62
- .access = PL0_R, .accessfn = access_tda,
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
63
+ .access = PL0_R, .accessfn = access_tdcc,
155
+ * so the VBIC becomes a logical AND operation.
64
.type = ARM_CP_CONST, .resetvalue = 0 },
156
+ */
65
/*
157
+ fn = gen_helper_mve_vandi;
66
* OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
158
+ } else {
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
159
+ fn = gen_helper_mve_vorri;
68
*/
160
+ }
69
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
161
+ } else {
70
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
162
+ /* There is one unallocated cmode/op combination in this space */
71
- .access = PL1_RW, .accessfn = access_tda,
163
+ if (a->cmode == 15 && a->op == 1) {
72
+ .access = PL1_RW, .accessfn = access_tdcc,
164
+ return false;
73
.type = ARM_CP_CONST, .resetvalue = 0 },
165
+ }
74
{ .name = "OSDTRTX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
75
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
167
+ fn = gen_helper_mve_vmovi;
76
- .access = PL1_RW, .accessfn = access_tda,
168
+ }
77
+ .access = PL1_RW, .accessfn = access_tdcc,
169
+ return do_1imm(s, a, fn);
78
.type = ARM_CP_CONST, .resetvalue = 0 },
170
+}
79
/*
80
* OSECCR_EL1 provides a mechanism for an operating system
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
82
*/
83
{ .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
84
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
85
- .access = PL1_RW, .accessfn = access_tda,
86
+ .access = PL1_RW, .accessfn = access_tdcc,
87
.type = ARM_CP_NOP },
88
/*
89
* Dummy DBGCLAIM registers.
171
--
90
--
172
2.20.1
91
2.34.1
173
174
diff view generated by jsdifflib
1
In do_ldst(), the calculation of the offset needs to be based on the
1
Update the ID registers for TCG's '-cpu max' to report the
2
size of the memory access, not the size of the elements in the
2
presence of FEAT_FGT Fine-Grained Traps support.
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
6
Tested-by: Fuad Tabba <tabba@google.com>
7
Message-id: 20230130182459.3309057-24-peter.maydell@linaro.org
8
Message-id: 20230127175507.2895013-24-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate-mve.c | 17 +++++++++--------
10
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 9 insertions(+), 8 deletions(-)
11
target/arm/cpu64.c | 1 +
12
2 files changed, 2 insertions(+)
12
13
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
14
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-mve.c
16
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/translate-mve.c
17
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
18
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
}
19
- FEAT_ETS (Enhanced Translation Synchronization)
19
}
20
- FEAT_EVT (Enhanced Virtualization Traps)
20
21
- FEAT_FCMA (Floating-point complex number instructions)
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
22
+- FEAT_FGT (Fine-Grained Traps)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
23
- FEAT_FHM (Floating-point half-precision multiplication instructions)
23
+ unsigned msize)
24
- FEAT_FP16 (Half-precision floating-point data processing)
24
{
25
- FEAT_FRINTTS (Floating-point to integer instructions)
25
TCGv_i32 addr;
26
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
uint32_t offset;
27
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
28
--- a/target/arm/cpu64.c
28
return true;
29
+++ b/target/arm/cpu64.c
29
}
30
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
30
31
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
31
- offset = a->imm << a->size;
32
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
32
+ offset = a->imm << msize;
33
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
33
if (!a->a) {
34
+ t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
34
offset = -offset;
35
cpu->isar.id_aa64mmfr0 = t;
35
}
36
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
t = cpu->isar.id_aa64mmfr1;
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
{
65
--
38
--
66
2.20.1
39
2.34.1
67
68
diff view generated by jsdifflib