1
As promised, another pullreq... This one's mostly RTH's patches.
1
The following changes since commit 61fee7f45955cd0bf9b79be9fa9c7ebabb5e6a85:
2
2
3
thanks
3
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/acceptance-testing-20200622' into staging (2020-06-22 20:50:10 +0100)
4
-- PMM
5
6
The following changes since commit 784c2e4f232adf5ef47a84a262ec72a07d068d6a:
7
8
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging (2018-10-19 15:30:40 +0100)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20181019
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200623
13
8
14
for you to fetch changes up to 88c9add25e7120e8622796c81ad3f3fb7f8d40e7:
9
for you to fetch changes up to 539533b85fbd269f777bed931de8ccae1dd837e9:
15
10
16
target/arm: Only flush tlb if ASID changes (2018-10-19 17:38:48 +0100)
11
arm/virt: Add memory hot remove support (2020-06-23 11:39:48 +0100)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* ssi-sd: Make devices picking up backends unavailable with -device
15
* util/oslib-posix : qemu_init_exec_dir implementation for Mac
21
* Add support for VCPU event states
16
* target/arm: Last parts of neon decodetree conversion
22
* Move towards making ID registers the source of truth for
17
* hw/arm/virt: Add 5.0 HW compat props
23
whether a guest CPU implements a feature, rather than having
18
* hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
24
parallel ID registers and feature bit flags
19
* mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices
25
* Implement various HCR hypervisor trap/config bits
20
* mps2: Add some unimplemented-device stubs for audio and GPIO
26
* Get IL bit correct for v7 syndrome values
21
* mps2-tz: Use the ARM SBCon two-wire serial bus interface
27
* Report correct syndrome for FP/SIMD traps to Hyp mode
22
* target/arm: Check supported KVM features globally (not per vCPU)
28
* hw/arm/boot: Increase compliance with kernel arm64 boot protocol
23
* tests/qtest/arm-cpu-features: Add feature setting tests
29
* Refactor A32 Neon to use generic vector infrastructure
24
* arm/virt: Add memory hot remove support
30
* Fix a bug in A32 VLD2 "(multiple 2-element structures)" insn
31
* net: cadence_gem: Report features correctly in ID register
32
* Avoid some unnecessary TLB flushes on TTBR register writes
33
25
34
----------------------------------------------------------------
26
----------------------------------------------------------------
35
Dongjiu Geng (1):
27
Andrew Jones (2):
36
target/arm: Add support for VCPU event states
28
hw/arm/virt: Add 5.0 HW compat props
29
tests/qtest/arm-cpu-features: Add feature setting tests
37
30
38
Edgar E. Iglesias (2):
31
David CARLIER (1):
39
net: cadence_gem: Announce availability of priority queues
32
util/oslib-posix : qemu_init_exec_dir implementation for Mac
40
net: cadence_gem: Announce 64bit addressing support
41
33
42
Markus Armbruster (1):
34
Peter Maydell (23):
43
ssi-sd: Make devices picking up backends unavailable with -device
35
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
36
target/arm: Convert Neon 2-reg-misc pairwise ops to decodetree
37
target/arm: Convert VZIP, VUZP to decodetree
38
target/arm: Convert Neon narrowing moves to decodetree
39
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
40
target/arm: Convert Neon VCVT f16/f32 insns to decodetree
41
target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree
42
target/arm: Convert Neon 2-reg-misc crypto operations to decodetree
43
target/arm: Rename NeonGenOneOpFn to NeonGenOne64OpFn
44
target/arm: Fix capitalization in NeonGenTwo{Single, Double}OPFn typedefs
45
target/arm: Make gen_swap_half() take separate src and dest
46
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
47
target/arm: Convert remaining simple 2-reg-misc Neon ops
48
target/arm: Convert Neon VQABS, VQNEG to decodetree
49
target/arm: Convert simple fp Neon 2-reg-misc insns
50
target/arm: Convert Neon 2-reg-misc fp-compare-with-zero insns to decodetree
51
target/arm: Convert Neon 2-reg-misc VRINT insns to decodetree
52
target/arm: Convert Neon 2-reg-misc VCVT insns to decodetree
53
target/arm: Convert Neon VSWP to decodetree
54
target/arm: Convert Neon VTRN to decodetree
55
target/arm: Move some functions used only in translate-neon.inc.c to that file
56
target/arm: Remove unnecessary gen_io_end() calls
57
target/arm: Remove dead code relating to SABA and UABA
44
58
45
Peter Maydell (10):
59
Philippe Mathieu-Daudé (15):
46
target/arm: Improve debug logging of AArch32 exception return
60
hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
47
target/arm: Make switch_mode() file-local
61
hw/i2c/versatile_i2c: Add definitions for register addresses
48
target/arm: Implement HCR.FB
62
hw/i2c/versatile_i2c: Add SCL/SDA definitions
49
target/arm: Implement HCR.DC
63
hw/i2c: Add header for ARM SBCon two-wire serial bus interface
50
target/arm: ISR_EL1 bits track virtual interrupts if IMO/FMO set
64
hw/arm: Use TYPE_VERSATILE_I2C instead of hardcoded string
51
target/arm: Implement HCR.VI and VF
65
hw/arm/mps2: Document CMSDK/FPGA APB subsystem sections
52
target/arm: Implement HCR.PTW
66
hw/arm/mps2: Rename CMSDK AHB peripheral region
53
target/arm: New utility function to extract EC from syndrome
67
hw/arm/mps2: Add CMSDK APB watchdog device
54
target/arm: Get IL bit correct for v7 syndrome values
68
hw/arm/mps2: Add CMSDK AHB GPIO peripherals as unimplemented devices
55
target/arm: Report correct syndrome for FP/SIMD traps to Hyp mode
69
hw/arm/mps2: Map the FPGA I/O block
70
hw/arm/mps2: Add SPI devices
71
hw/arm/mps2: Add I2C devices
72
hw/arm/mps2: Add audio I2S interface as unimplemented device
73
hw/arm/mps2-tz: Use the ARM SBCon two-wire serial bus interface
74
target/arm: Check supported KVM features globally (not per vCPU)
56
75
57
Richard Henderson (30):
76
Shameer Kolothum (1):
58
target/arm: Move some system registers into a substructure
77
arm/virt: Add memory hot remove support
59
target/arm: V8M should not imply V7VE
60
target/arm: Convert v8 extensions from feature bits to isar tests
61
target/arm: Convert division from feature bits to isar0 tests
62
target/arm: Convert jazelle from feature bit to isar1 test
63
target/arm: Convert t32ee from feature bit to isar3 test
64
target/arm: Convert sve from feature bit to aa64pfr0 test
65
target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test
66
target/arm: Hoist address increment for vector memory ops
67
target/arm: Don't call tcg_clear_temp_count
68
target/arm: Use tcg_gen_gvec_dup_i64 for LD[1-4]R
69
target/arm: Promote consecutive memory ops for aa64
70
target/arm: Mark some arrays const
71
target/arm: Use gvec for NEON VDUP
72
target/arm: Use gvec for NEON VMOV, VMVN, VBIC & VORR (immediate)
73
target/arm: Use gvec for NEON_3R_LOGIC insns
74
target/arm: Use gvec for NEON_3R_VADD_VSUB insns
75
target/arm: Use gvec for NEON_2RM_VMN, NEON_2RM_VNEG
76
target/arm: Use gvec for NEON_3R_VMUL
77
target/arm: Use gvec for VSHR, VSHL
78
target/arm: Use gvec for VSRA
79
target/arm: Use gvec for VSRI, VSLI
80
target/arm: Use gvec for NEON_3R_VML
81
target/arm: Use gvec for NEON_3R_VTST_VCEQ, NEON_3R_VCGT, NEON_3R_VCGE
82
target/arm: Use gvec for NEON VLD all lanes
83
target/arm: Reorg NEON VLD/VST all elements
84
target/arm: Promote consecutive memory ops for aa32
85
target/arm: Reorg NEON VLD/VST single element to one lane
86
target/arm: Remove writefn from TTBR0_EL3
87
target/arm: Only flush tlb if ASID changes
88
78
89
Stewart Hildebrand (1):
79
include/hw/i2c/arm_sbcon_i2c.h | 35 ++
90
hw/arm/boot: Increase compliance with kernel arm64 boot protocol
80
target/arm/cpu.h | 2 +-
81
target/arm/kvm_arm.h | 21 +-
82
target/arm/translate.h | 8 +-
83
target/arm/neon-dp.decode | 106 ++++
84
hw/acpi/generic_event_device.c | 29 +
85
hw/arm/mps2-tz.c | 23 +-
86
hw/arm/mps2.c | 65 ++-
87
hw/arm/realview.c | 3 +-
88
hw/arm/versatilepb.c | 3 +-
89
hw/arm/vexpress.c | 3 +-
90
hw/arm/virt.c | 63 +-
91
hw/i2c/versatile_i2c.c | 38 +-
92
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
93
target/arm/cpu.c | 2 +-
94
target/arm/cpu64.c | 10 +-
95
target/arm/kvm.c | 4 +-
96
target/arm/kvm64.c | 14 +-
97
target/arm/translate-a64.c | 20 +-
98
target/arm/translate-neon.inc.c | 1191 +++++++++++++++++++++++++++++++++++++-
99
target/arm/translate-vfp.inc.c | 7 +-
100
target/arm/translate.c | 1064 +---------------------------------
101
tests/qtest/arm-cpu-features.c | 38 +-
102
util/oslib-posix.c | 15 +
103
MAINTAINERS | 1 +
104
hw/arm/Kconfig | 8 +-
105
hw/watchdog/trace-events | 1 +
106
27 files changed, 1624 insertions(+), 1151 deletions(-)
107
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
91
108
92
target/arm/cpu.h | 227 ++++++-
93
target/arm/internals.h | 45 +-
94
target/arm/kvm_arm.h | 24 +
95
target/arm/translate.h | 21 +
96
hw/arm/boot.c | 18 +
97
hw/intc/armv7m_nvic.c | 12 +-
98
hw/net/cadence_gem.c | 9 +-
99
hw/sd/ssi-sd.c | 2 +
100
linux-user/aarch64/signal.c | 4 +-
101
linux-user/elfload.c | 60 +-
102
linux-user/syscall.c | 10 +-
103
target/arm/cpu.c | 242 ++++----
104
target/arm/cpu64.c | 148 +++--
105
target/arm/helper.c | 397 ++++++++----
106
target/arm/kvm.c | 60 ++
107
target/arm/kvm32.c | 13 +
108
target/arm/kvm64.c | 15 +-
109
target/arm/machine.c | 28 +-
110
target/arm/op_helper.c | 2 +-
111
target/arm/translate-a64.c | 715 ++++-----------------
112
target/arm/translate.c | 1451 ++++++++++++++++++++++++++++---------------
113
21 files changed, 2021 insertions(+), 1482 deletions(-)
114
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Since QEMU does not implement ASIDs, changes to the ASID must flush the
3
Cc: Cornelia Huck <cohuck@redhat.com>
4
tlb. However, if the ASID does not change there is no reason to flush.
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
5
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
In testing a boot of the Ubuntu installer to the first menu, this reduces
6
Message-id: 20200616140803.25515-1-drjones@redhat.com
7
the number of flushes by 30%, or nearly 600k instances.
8
9
Reviewed-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20181019015617.22583-3-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
8
---
16
target/arm/helper.c | 8 +++-----
9
hw/arm/virt.c | 1 +
17
1 file changed, 3 insertions(+), 5 deletions(-)
10
1 file changed, 1 insertion(+)
18
11
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
14
--- a/hw/arm/virt.c
22
+++ b/target/arm/helper.c
15
+++ b/hw/arm/virt.c
23
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
16
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
24
static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
17
static void virt_machine_5_0_options(MachineClass *mc)
25
uint64_t value)
26
{
18
{
27
- /* 64 bit accesses to the TTBRs can change the ASID and so we
19
virt_machine_5_1_options(mc);
28
- * must flush the TLB.
20
+ compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
29
- */
21
}
30
- if (cpreg_field_is_64bit(ri)) {
22
DEFINE_VIRT_MACHINE(5, 0)
31
+ /* If the ASID changes (with a 64-bit write), we must flush the TLB. */
23
32
+ if (cpreg_field_is_64bit(ri) &&
33
+ extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
34
ARMCPU *cpu = arm_env_get_cpu(env);
35
-
36
tlb_flush(CPU(cpu));
37
}
38
raw_write(env, ri, value);
39
--
24
--
40
2.19.1
25
2.20.1
41
26
42
27
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: David CARLIER <devnexen@gmail.com>
2
2
3
For a sequence of loads or stores from a single register,
3
From 3025a0ce3fdf7d3559fc35a52c659f635f5c750c Mon Sep 17 00:00:00 2001
4
little-endian operations can be promoted to an 8-byte op.
4
From: David Carlier <devnexen@gmail.com>
5
This can reduce the number of operations by a factor of 8.
5
Date: Tue, 26 May 2020 21:35:27 +0100
6
Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Using dyld API to get the full path of the current process.
8
Message-id: 20181011205206.3552-5-richard.henderson@linaro.org
9
10
Signed-off-by: David Carlier <devnexen@gmail.com>
11
Message-id: CA+XhMqxwC10XHVs4Z-JfE0-WLAU3ztDuU9QKVi31mjr59HWCxg@mail.gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/translate-a64.c | 66 +++++++++++++++++++++++---------------
15
util/oslib-posix.c | 15 +++++++++++++++
13
1 file changed, 40 insertions(+), 26 deletions(-)
16
1 file changed, 15 insertions(+)
14
17
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
20
--- a/util/oslib-posix.c
18
+++ b/target/arm/translate-a64.c
21
+++ b/util/oslib-posix.c
19
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
22
@@ -XXX,XX +XXX,XX @@
20
23
#include <lwp.h>
21
/* Store from vector register to memory */
24
#endif
22
static void do_vec_st(DisasContext *s, int srcidx, int element,
25
23
- TCGv_i64 tcg_addr, int size)
26
+#ifdef __APPLE__
24
+ TCGv_i64 tcg_addr, int size, TCGMemOp endian)
27
+#include <mach-o/dyld.h>
25
{
28
+#endif
26
- TCGMemOp memop = s->be_data + size;
27
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
28
29
read_vec_element(s, tcg_tmp, srcidx, element, size);
30
- tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
31
+ tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
32
33
tcg_temp_free_i64(tcg_tmp);
34
}
35
36
/* Load from memory to vector register */
37
static void do_vec_ld(DisasContext *s, int destidx, int element,
38
- TCGv_i64 tcg_addr, int size)
39
+ TCGv_i64 tcg_addr, int size, TCGMemOp endian)
40
{
41
- TCGMemOp memop = s->be_data + size;
42
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
43
44
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
45
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
46
write_vec_element(s, tcg_tmp, destidx, element, size);
47
48
tcg_temp_free_i64(tcg_tmp);
49
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
50
bool is_postidx = extract32(insn, 23, 1);
51
bool is_q = extract32(insn, 30, 1);
52
TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
53
+ TCGMemOp endian = s->be_data;
54
55
- int ebytes = 1 << size;
56
- int elements = (is_q ? 128 : 64) / (8 << size);
57
+ int ebytes; /* bytes per element */
58
+ int elements; /* elements per vector */
59
int rpt; /* num iterations */
60
int selem; /* structure elements */
61
int r;
62
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
63
gen_check_sp_alignment(s);
64
}
65
66
+ /* For our purposes, bytes are always little-endian. */
67
+ if (size == 0) {
68
+ endian = MO_LE;
69
+ }
70
+
29
+
71
+ /* Consecutive little-endian elements from a single register
30
#include "qemu/mmap-alloc.h"
72
+ * can be promoted to a larger little-endian operation.
31
73
+ */
32
#ifdef CONFIG_DEBUG_STACK_USAGE
74
+ if (selem == 1 && endian == MO_LE) {
33
@@ -XXX,XX +XXX,XX @@ void qemu_init_exec_dir(const char *argv0)
75
+ size = 3;
34
p = buf;
76
+ }
77
+ ebytes = 1 << size;
78
+ elements = (is_q ? 16 : 8) / ebytes;
79
+
80
tcg_rn = cpu_reg_sp(s, rn);
81
tcg_addr = tcg_temp_new_i64();
82
tcg_gen_mov_i64(tcg_addr, tcg_rn);
83
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
84
for (r = 0; r < rpt; r++) {
85
int e;
86
for (e = 0; e < elements; e++) {
87
- int tt = (rt + r) % 32;
88
int xs;
89
for (xs = 0; xs < selem; xs++) {
90
+ int tt = (rt + r + xs) % 32;
91
if (is_store) {
92
- do_vec_st(s, tt, e, tcg_addr, size);
93
+ do_vec_st(s, tt, e, tcg_addr, size, endian);
94
} else {
95
- do_vec_ld(s, tt, e, tcg_addr, size);
96
-
97
- /* For non-quad operations, setting a slice of the low
98
- * 64 bits of the register clears the high 64 bits (in
99
- * the ARM ARM pseudocode this is implicit in the fact
100
- * that 'rval' is a 64 bit wide variable).
101
- * For quad operations, we might still need to zero the
102
- * high bits of SVE. We optimize by noticing that we only
103
- * need to do this the first time we touch a register.
104
- */
105
- if (e == 0 && (r == 0 || xs == selem - 1)) {
106
- clear_vec_high(s, is_q, tt);
107
- }
108
+ do_vec_ld(s, tt, e, tcg_addr, size, endian);
109
}
110
tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
111
- tt = (tt + 1) % 32;
112
}
113
}
35
}
114
}
36
}
115
37
+#elif defined(__APPLE__)
116
+ if (!is_store) {
38
+ {
117
+ /* For non-quad operations, setting a slice of the low
39
+ char fpath[PATH_MAX];
118
+ * 64 bits of the register clears the high 64 bits (in
40
+ uint32_t len = sizeof(fpath);
119
+ * the ARM ARM pseudocode this is implicit in the fact
41
+ if (_NSGetExecutablePath(fpath, &len) == 0) {
120
+ * that 'rval' is a 64 bit wide variable).
42
+ p = realpath(fpath, buf);
121
+ * For quad operations, we might still need to zero the
43
+ if (!p) {
122
+ * high bits of SVE.
44
+ return;
123
+ */
45
+ }
124
+ for (r = 0; r < rpt * selem; r++) {
125
+ int tt = (rt + r) % 32;
126
+ clear_vec_high(s, is_q, tt);
127
+ }
46
+ }
128
+ }
47
+ }
129
+
48
#endif
130
if (is_postidx) {
49
/* If we don't have any way of figuring out the actual executable
131
int rm = extract32(insn, 16, 5);
50
location then try argv[0]. */
132
if (rm == 31) {
133
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
134
} else {
135
/* Load/store one element per register */
136
if (is_load) {
137
- do_vec_ld(s, rt, index, tcg_addr, scale);
138
+ do_vec_ld(s, rt, index, tcg_addr, scale, s->be_data);
139
} else {
140
- do_vec_st(s, rt, index, tcg_addr, scale);
141
+ do_vec_st(s, rt, index, tcg_addr, scale, s->be_data);
142
}
143
}
144
tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
145
--
51
--
146
2.19.1
52
2.20.1
147
53
148
54
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-12-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200616170844.13318-2-peter.maydell@linaro.org
7
---
6
---
8
target/arm/translate.c | 31 +++++++++++++++----------------
7
target/arm/neon-dp.decode | 12 ++++++++
9
1 file changed, 15 insertions(+), 16 deletions(-)
8
target/arm/translate-neon.inc.c | 50 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 24 ++--------------
10
3 files changed, 64 insertions(+), 22 deletions(-)
10
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
vm=%vm_dp vd=%vd_dp size=1
18
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
19
vm=%vm_dp vd=%vd_dp size=2
20
+
21
+ ##################################################################
22
+ # 2-reg-misc grouping:
23
+ # 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
24
+ ##################################################################
25
+
26
+ &2misc vd vm q size
27
+
28
+ @2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
29
+ &2misc vm=%vm_dp vd=%vd_dp
30
+
31
+ VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
32
]
33
34
# Subgroup for size != 0b11
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
40
a->q ? 16 : 8, a->q ? 16 : 8);
41
return true;
42
}
43
+
44
+static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
45
+{
46
+ int pass, half;
47
+
48
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vd | a->vm) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (a->size == 3) {
63
+ return false;
64
+ }
65
+
66
+ if (!vfp_access_check(s)) {
67
+ return true;
68
+ }
69
+
70
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
71
+ TCGv_i32 tmp[2];
72
+
73
+ for (half = 0; half < 2; half++) {
74
+ tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
75
+ switch (a->size) {
76
+ case 0:
77
+ tcg_gen_bswap32_i32(tmp[half], tmp[half]);
78
+ break;
79
+ case 1:
80
+ gen_swap_half(tmp[half]);
81
+ break;
82
+ case 2:
83
+ break;
84
+ default:
85
+ g_assert_not_reached();
86
+ }
87
+ }
88
+ neon_store_reg(a->vd, pass * 2, tmp[1]);
89
+ neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
90
+ }
91
+ return true;
92
+}
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
93
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
95
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
96
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
16
vec_size, vec_size);
98
}
17
}
99
switch (op) {
18
return 0;
100
case NEON_2RM_VREV64:
19
+
101
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
20
+ case NEON_3R_VMUL: /* VMUL */
102
- tmp = neon_load_reg(rm, pass * 2);
21
+ if (u) {
103
- tmp2 = neon_load_reg(rm, pass * 2 + 1);
22
+ /* Polynomial case allows only P8 and is handled below. */
104
- switch (size) {
23
+ if (size != 0) {
105
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
106
- case 1: gen_swap_half(tmp); break;
107
- case 2: /* no-op */ break;
108
- default: abort();
109
- }
110
- neon_store_reg(rd, pass * 2 + 1, tmp);
111
- if (size == 2) {
112
- neon_store_reg(rd, pass * 2, tmp2);
113
- } else {
114
- switch (size) {
115
- case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
116
- case 1: gen_swap_half(tmp2); break;
117
- default: abort();
118
- }
119
- neon_store_reg(rd, pass * 2, tmp2);
120
- }
121
- }
122
- break;
123
+ /* handled by decodetree */
24
+ return 1;
124
+ return 1;
25
+ }
125
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
26
+ } else {
126
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
27
+ tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
127
for (pass = 0; pass < q + 1; pass++) {
28
+ vec_size, vec_size);
29
+ return 0;
30
+ }
31
+ break;
32
}
33
if (size == 3) {
34
/* 64-bit element instructions. */
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
36
return 1;
37
}
38
break;
39
- case NEON_3R_VMUL:
40
- if (u && (size != 0)) {
41
- /* UNDEF on invalid size for polynomial subcase */
42
- return 1;
43
- }
44
- break;
45
case NEON_3R_VFM_VQRDMLSH:
46
if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
47
return 1;
48
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
49
}
50
break;
51
case NEON_3R_VMUL:
52
- if (u) { /* polynomial */
53
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
54
- } else { /* Integer */
55
- switch (size) {
56
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
57
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
58
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
59
- default: abort();
60
- }
61
- }
62
+ /* VMUL.P8; other cases already eliminated. */
63
+ gen_helper_neon_mul_p8(tmp, tmp, tmp2);
64
break;
65
case NEON_3R_VPMAX:
66
GEN_NEON_INTEGER_OP(pmax);
67
--
128
--
68
2.19.1
129
2.20.1
69
130
70
131
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the pairwise ops VPADDL and VPADAL in the 2-reg-misc grouping
2
2
to decodetree.
3
Instead of shifts and masks, use direct loads and stores from
3
4
the neon register file.
4
At this point we can get rid of the weird CPU_V001 #define that was
5
5
used to avoid having to explicitly list all the arguments being
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
passed to some TCG gen/helper functions.
7
Message-id: 20181011205206.3552-21-richard.henderson@linaro.org
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-3-peter.maydell@linaro.org
10
---
11
---
11
target/arm/translate.c | 92 +++++++++++++++++++++++-------------------
12
target/arm/neon-dp.decode | 6 ++
12
1 file changed, 50 insertions(+), 42 deletions(-)
13
target/arm/translate-neon.inc.c | 149 ++++++++++++++++++++++++++++++++
13
14
target/arm/translate.c | 35 +-------
15
3 files changed, 157 insertions(+), 33 deletions(-)
16
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
&2misc vm=%vm_dp vd=%vd_dp
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
25
+
26
+ VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
27
+ VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
28
+
29
+ VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
30
+ VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
31
]
32
33
# Subgroup for size != 0b11
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
39
}
40
return true;
41
}
42
+
43
+static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
44
+ NeonGenWidenFn *widenfn,
45
+ NeonGenTwo64OpFn *opfn,
46
+ NeonGenTwo64OpFn *accfn)
47
+{
48
+ /*
49
+ * Pairwise long operations: widen both halves of the pair,
50
+ * combine the pairs with the opfn, and then possibly accumulate
51
+ * into the destination with the accfn.
52
+ */
53
+ int pass;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if ((a->vd | a->vm) & a->q) {
66
+ return false;
67
+ }
68
+
69
+ if (!widenfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ for (pass = 0; pass < a->q + 1; pass++) {
78
+ TCGv_i32 tmp;
79
+ TCGv_i64 rm0_64, rm1_64, rd_64;
80
+
81
+ rm0_64 = tcg_temp_new_i64();
82
+ rm1_64 = tcg_temp_new_i64();
83
+ rd_64 = tcg_temp_new_i64();
84
+ tmp = neon_load_reg(a->vm, pass * 2);
85
+ widenfn(rm0_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ tmp = neon_load_reg(a->vm, pass * 2 + 1);
88
+ widenfn(rm1_64, tmp);
89
+ tcg_temp_free_i32(tmp);
90
+ opfn(rd_64, rm0_64, rm1_64);
91
+ tcg_temp_free_i64(rm0_64);
92
+ tcg_temp_free_i64(rm1_64);
93
+
94
+ if (accfn) {
95
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
96
+ neon_load_reg64(tmp64, a->vd + pass);
97
+ accfn(rd_64, tmp64, rd_64);
98
+ tcg_temp_free_i64(tmp64);
99
+ }
100
+ neon_store_reg64(rd_64, a->vd + pass);
101
+ tcg_temp_free_i64(rd_64);
102
+ }
103
+ return true;
104
+}
105
+
106
+static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a)
107
+{
108
+ static NeonGenWidenFn * const widenfn[] = {
109
+ gen_helper_neon_widen_s8,
110
+ gen_helper_neon_widen_s16,
111
+ tcg_gen_ext_i32_i64,
112
+ NULL,
113
+ };
114
+ static NeonGenTwo64OpFn * const opfn[] = {
115
+ gen_helper_neon_paddl_u16,
116
+ gen_helper_neon_paddl_u32,
117
+ tcg_gen_add_i64,
118
+ NULL,
119
+ };
120
+
121
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
122
+}
123
+
124
+static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a)
125
+{
126
+ static NeonGenWidenFn * const widenfn[] = {
127
+ gen_helper_neon_widen_u8,
128
+ gen_helper_neon_widen_u16,
129
+ tcg_gen_extu_i32_i64,
130
+ NULL,
131
+ };
132
+ static NeonGenTwo64OpFn * const opfn[] = {
133
+ gen_helper_neon_paddl_u16,
134
+ gen_helper_neon_paddl_u32,
135
+ tcg_gen_add_i64,
136
+ NULL,
137
+ };
138
+
139
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
140
+}
141
+
142
+static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a)
143
+{
144
+ static NeonGenWidenFn * const widenfn[] = {
145
+ gen_helper_neon_widen_s8,
146
+ gen_helper_neon_widen_s16,
147
+ tcg_gen_ext_i32_i64,
148
+ NULL,
149
+ };
150
+ static NeonGenTwo64OpFn * const opfn[] = {
151
+ gen_helper_neon_paddl_u16,
152
+ gen_helper_neon_paddl_u32,
153
+ tcg_gen_add_i64,
154
+ NULL,
155
+ };
156
+ static NeonGenTwo64OpFn * const accfn[] = {
157
+ gen_helper_neon_addl_u16,
158
+ gen_helper_neon_addl_u32,
159
+ tcg_gen_add_i64,
160
+ NULL,
161
+ };
162
+
163
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
164
+ accfn[a->size]);
165
+}
166
+
167
+static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
168
+{
169
+ static NeonGenWidenFn * const widenfn[] = {
170
+ gen_helper_neon_widen_u8,
171
+ gen_helper_neon_widen_u16,
172
+ tcg_gen_extu_i32_i64,
173
+ NULL,
174
+ };
175
+ static NeonGenTwo64OpFn * const opfn[] = {
176
+ gen_helper_neon_paddl_u16,
177
+ gen_helper_neon_paddl_u32,
178
+ tcg_gen_add_i64,
179
+ NULL,
180
+ };
181
+ static NeonGenTwo64OpFn * const accfn[] = {
182
+ gen_helper_neon_addl_u16,
183
+ gen_helper_neon_addl_u32,
184
+ tcg_gen_add_i64,
185
+ NULL,
186
+ };
187
+
188
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
189
+ accfn[a->size]);
190
+}
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
191
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
192
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
193
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
194
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
195
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
19
return tmp;
196
gen_rfe(s, pc, load_cpu_field(spsr));
20
}
197
}
21
198
22
+static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
199
-#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
23
+{
200
-
24
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
201
static int gen_neon_unzip(int rd, int rm, int size, int q)
25
+
26
+ switch (mop) {
27
+ case MO_UB:
28
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
29
+ break;
30
+ case MO_UW:
31
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
32
+ break;
33
+ case MO_UL:
34
+ tcg_gen_ld_i32(var, cpu_env, offset);
35
+ break;
36
+ default:
37
+ g_assert_not_reached();
38
+ }
39
+}
40
+
41
static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
42
{
202
{
43
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
203
TCGv_ptr pd, pm;
44
@@ -XXX,XX +XXX,XX @@ static void neon_store_reg(int reg, int pass, TCGv_i32 var)
204
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
45
tcg_temp_free_i32(var);
205
tcg_temp_free_i32(src);
46
}
206
}
47
207
48
+static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
208
-static inline void gen_neon_addl(int size)
49
+{
209
-{
50
+ long offset = neon_element_offset(reg, ele, size);
210
- switch (size) {
51
+
211
- case 0: gen_helper_neon_addl_u16(CPU_V001); break;
52
+ switch (size) {
212
- case 1: gen_helper_neon_addl_u32(CPU_V001); break;
53
+ case MO_8:
213
- case 2: tcg_gen_add_i64(CPU_V001); break;
54
+ tcg_gen_st8_i32(var, cpu_env, offset);
214
- default: abort();
55
+ break;
215
- }
56
+ case MO_16:
216
-}
57
+ tcg_gen_st16_i32(var, cpu_env, offset);
217
-
58
+ break;
218
static void gen_neon_narrow_op(int op, int u, int size,
59
+ case MO_32:
219
TCGv_i32 dest, TCGv_i64 src)
60
+ tcg_gen_st_i32(var, cpu_env, offset);
61
+ break;
62
+ default:
63
+ g_assert_not_reached();
64
+ }
65
+}
66
+
67
static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
68
{
220
{
69
long offset = neon_element_offset(reg, ele, size);
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
222
}
71
int stride;
223
switch (op) {
72
int size;
224
case NEON_2RM_VREV64:
73
int reg;
225
- /* handled by decodetree */
74
- int pass;
226
- return 1;
75
int load;
227
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
76
- int shift;
228
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
77
int n;
229
- for (pass = 0; pass < q + 1; pass++) {
78
int vec_size;
230
- tmp = neon_load_reg(rm, pass * 2);
79
int mmu_idx;
231
- gen_neon_widen(cpu_V0, tmp, size, op & 1);
80
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
232
- tmp = neon_load_reg(rm, pass * 2 + 1);
81
} else {
233
- gen_neon_widen(cpu_V1, tmp, size, op & 1);
82
/* Single element. */
234
- switch (size) {
83
int idx = (insn >> 4) & 0xf;
235
- case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
84
- pass = (insn >> 7) & 1;
236
- case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
85
+ int reg_idx;
237
- case 2: tcg_gen_add_i64(CPU_V001); break;
86
switch (size) {
238
- default: abort();
87
case 0:
239
- }
88
- shift = ((insn >> 5) & 3) * 8;
240
- if (op >= NEON_2RM_VPADAL) {
89
+ reg_idx = (insn >> 5) & 7;
241
- /* Accumulate. */
90
stride = 1;
242
- neon_load_reg64(cpu_V1, rd + pass);
91
break;
243
- gen_neon_addl(size);
92
case 1:
244
- }
93
- shift = ((insn >> 6) & 1) * 16;
245
- neon_store_reg64(cpu_V0, rd + pass);
94
+ reg_idx = (insn >> 6) & 3;
95
stride = (insn & (1 << 5)) ? 2 : 1;
96
break;
97
case 2:
98
- shift = 0;
99
+ reg_idx = (insn >> 7) & 1;
100
stride = (insn & (1 << 6)) ? 2 : 1;
101
break;
102
default:
103
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
104
*/
105
return 1;
106
}
107
+ tmp = tcg_temp_new_i32();
108
addr = tcg_temp_new_i32();
109
load_reg_var(s, addr, rn);
110
for (reg = 0; reg < nregs; reg++) {
111
if (load) {
112
- tmp = tcg_temp_new_i32();
113
- switch (size) {
114
- case 0:
115
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
116
- break;
117
- case 1:
118
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
119
- break;
120
- case 2:
121
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
122
- break;
123
- default: /* Avoid compiler warnings. */
124
- abort();
125
- }
246
- }
126
- if (size != 2) {
247
- break;
127
- tmp2 = neon_load_reg(rd, pass);
248
+ /* handled by decodetree */
128
- tcg_gen_deposit_i32(tmp, tmp2, tmp,
249
+ return 1;
129
- shift, size ? 16 : 8);
250
case NEON_2RM_VTRN:
130
- tcg_temp_free_i32(tmp2);
251
if (size == 2) {
131
- }
252
int n;
132
- neon_store_reg(rd, pass, tmp);
133
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
134
+ s->be_data | size);
135
+ neon_store_element(rd, reg_idx, size, tmp);
136
} else { /* Store */
137
- tmp = neon_load_reg(rd, pass);
138
- if (shift)
139
- tcg_gen_shri_i32(tmp, tmp, shift);
140
- switch (size) {
141
- case 0:
142
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
143
- break;
144
- case 1:
145
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
146
- break;
147
- case 2:
148
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
149
- break;
150
- }
151
- tcg_temp_free_i32(tmp);
152
+ neon_load_element(tmp, rd, reg_idx, size);
153
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
154
+ s->be_data | size);
155
}
156
rd += stride;
157
tcg_gen_addi_i32(addr, addr, 1 << size);
158
}
159
tcg_temp_free_i32(addr);
160
+ tcg_temp_free_i32(tmp);
161
stride = nregs * (1 << size);
162
}
163
}
164
--
253
--
165
2.19.1
254
2.20.1
166
255
167
256
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon VZIP and VUZP insns in the 2-reg-misc group to
2
2
decodetree.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
4
Message-id: 20181011205206.3552-18-richard.henderson@linaro.org
5
[PMM: added parens in ?: expression]
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-4-peter.maydell@linaro.org
8
---
7
---
9
target/arm/translate.c | 81 ++++++++++++++----------------------------
8
target/arm/neon-dp.decode | 3 ++
10
1 file changed, 26 insertions(+), 55 deletions(-)
9
target/arm/translate-neon.inc.c | 74 ++++++++++++++++++++++++++
11
10
target/arm/translate.c | 92 +--------------------------------
11
3 files changed, 79 insertions(+), 90 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
19
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
20
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
21
+
22
+ VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
23
+ VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
24
]
25
26
# Subgroup for size != 0b11
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
32
return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
33
accfn[a->size]);
34
}
35
+
36
+typedef void ZipFn(TCGv_ptr, TCGv_ptr);
37
+
38
+static bool do_zip_uzp(DisasContext *s, arg_2misc *a,
39
+ ZipFn *fn)
40
+{
41
+ TCGv_ptr pd, pm;
42
+
43
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
44
+ return false;
45
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vm) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!fn) {
58
+ /* Bad size or size/q combination */
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ pd = vfp_reg_ptr(true, a->vd);
67
+ pm = vfp_reg_ptr(true, a->vm);
68
+ fn(pd, pm);
69
+ tcg_temp_free_ptr(pd);
70
+ tcg_temp_free_ptr(pm);
71
+ return true;
72
+}
73
+
74
+static bool trans_VUZP(DisasContext *s, arg_2misc *a)
75
+{
76
+ static ZipFn * const fn[2][4] = {
77
+ {
78
+ gen_helper_neon_unzip8,
79
+ gen_helper_neon_unzip16,
80
+ NULL,
81
+ NULL,
82
+ }, {
83
+ gen_helper_neon_qunzip8,
84
+ gen_helper_neon_qunzip16,
85
+ gen_helper_neon_qunzip32,
86
+ NULL,
87
+ }
88
+ };
89
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
90
+}
91
+
92
+static bool trans_VZIP(DisasContext *s, arg_2misc *a)
93
+{
94
+ static ZipFn * const fn[2][4] = {
95
+ {
96
+ gen_helper_neon_zip8,
97
+ gen_helper_neon_zip16,
98
+ NULL,
99
+ NULL,
100
+ }, {
101
+ gen_helper_neon_qzip8,
102
+ gen_helper_neon_qzip16,
103
+ gen_helper_neon_qzip32,
104
+ NULL,
105
+ }
106
+ };
107
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
108
+}
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
109
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate.c
111
--- a/target/arm/translate.c
15
+++ b/target/arm/translate.c
112
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ static void gen_vfp_msr(TCGv_i32 tmp)
113
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
17
tcg_temp_free_i32(tmp);
114
gen_rfe(s, pc, load_cpu_field(spsr));
18
}
115
}
19
116
20
-static void gen_neon_dup_u8(TCGv_i32 var, int shift)
117
-static int gen_neon_unzip(int rd, int rm, int size, int q)
21
-{
118
-{
22
- TCGv_i32 tmp = tcg_temp_new_i32();
119
- TCGv_ptr pd, pm;
23
- if (shift)
120
-
24
- tcg_gen_shri_i32(var, var, shift);
121
- if (!q && size == 2) {
25
- tcg_gen_ext8u_i32(var, var);
122
- return 1;
26
- tcg_gen_shli_i32(tmp, var, 8);
123
- }
27
- tcg_gen_or_i32(var, var, tmp);
124
- pd = vfp_reg_ptr(true, rd);
28
- tcg_gen_shli_i32(tmp, var, 16);
125
- pm = vfp_reg_ptr(true, rm);
29
- tcg_gen_or_i32(var, var, tmp);
126
- if (q) {
30
- tcg_temp_free_i32(tmp);
127
- switch (size) {
128
- case 0:
129
- gen_helper_neon_qunzip8(pd, pm);
130
- break;
131
- case 1:
132
- gen_helper_neon_qunzip16(pd, pm);
133
- break;
134
- case 2:
135
- gen_helper_neon_qunzip32(pd, pm);
136
- break;
137
- default:
138
- abort();
139
- }
140
- } else {
141
- switch (size) {
142
- case 0:
143
- gen_helper_neon_unzip8(pd, pm);
144
- break;
145
- case 1:
146
- gen_helper_neon_unzip16(pd, pm);
147
- break;
148
- default:
149
- abort();
150
- }
151
- }
152
- tcg_temp_free_ptr(pd);
153
- tcg_temp_free_ptr(pm);
154
- return 0;
31
-}
155
-}
32
-
156
-
33
static void gen_neon_dup_low16(TCGv_i32 var)
157
-static int gen_neon_zip(int rd, int rm, int size, int q)
34
{
35
TCGv_i32 tmp = tcg_temp_new_i32();
36
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
37
tcg_temp_free_i32(tmp);
38
}
39
40
-static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
41
-{
158
-{
42
- /* Load a single Neon element and replicate into a 32 bit TCG reg */
159
- TCGv_ptr pd, pm;
43
- TCGv_i32 tmp = tcg_temp_new_i32();
160
-
44
- switch (size) {
161
- if (!q && size == 2) {
45
- case 0:
162
- return 1;
46
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
163
- }
47
- gen_neon_dup_u8(tmp, 0);
164
- pd = vfp_reg_ptr(true, rd);
48
- break;
165
- pm = vfp_reg_ptr(true, rm);
49
- case 1:
166
- if (q) {
50
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
167
- switch (size) {
51
- gen_neon_dup_low16(tmp);
168
- case 0:
52
- break;
169
- gen_helper_neon_qzip8(pd, pm);
53
- case 2:
170
- break;
54
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
171
- case 1:
55
- break;
172
- gen_helper_neon_qzip16(pd, pm);
56
- default: /* Avoid compiler warnings. */
173
- break;
57
- abort();
174
- case 2:
58
- }
175
- gen_helper_neon_qzip32(pd, pm);
59
- return tmp;
176
- break;
177
- default:
178
- abort();
179
- }
180
- } else {
181
- switch (size) {
182
- case 0:
183
- gen_helper_neon_zip8(pd, pm);
184
- break;
185
- case 1:
186
- gen_helper_neon_zip16(pd, pm);
187
- break;
188
- default:
189
- abort();
190
- }
191
- }
192
- tcg_temp_free_ptr(pd);
193
- tcg_temp_free_ptr(pm);
194
- return 0;
60
-}
195
-}
61
-
196
-
62
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
197
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
63
uint32_t dp)
64
{
198
{
65
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
199
TCGv_i32 rd, tmp;
66
int load;
200
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
67
int shift;
201
case NEON_2RM_VREV64:
68
int n;
202
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
69
+ int vec_size;
203
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
70
TCGv_i32 addr;
204
+ case NEON_2RM_VUZP:
71
TCGv_i32 tmp;
205
+ case NEON_2RM_VZIP:
72
TCGv_i32 tmp2;
206
/* handled by decodetree */
73
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
207
return 1;
74
}
208
case NEON_2RM_VTRN:
75
addr = tcg_temp_new_i32();
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
76
load_reg_var(s, addr, rn);
210
goto elementwise;
77
- if (nregs == 1) {
211
}
78
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
212
break;
79
- tmp = gen_load_and_replicate(s, addr, size);
213
- case NEON_2RM_VUZP:
80
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
214
- if (gen_neon_unzip(rd, rm, size, q)) {
81
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
215
- return 1;
82
- if (insn & (1 << 5)) {
216
- }
83
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
217
- break;
84
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
218
- case NEON_2RM_VZIP:
85
- }
219
- if (gen_neon_zip(rd, rm, size, q)) {
86
- tcg_temp_free_i32(tmp);
220
- return 1;
87
- } else {
221
- }
88
- /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
222
- break;
89
- stride = (insn & (1 << 5)) ? 2 : 1;
223
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
90
- for (reg = 0; reg < nregs; reg++) {
224
/* also VQMOVUN; op field and mnemonics don't line up */
91
- tmp = gen_load_and_replicate(s, addr, size);
225
if (rm & 1) {
92
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
93
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
94
- tcg_temp_free_i32(tmp);
95
- tcg_gen_addi_i32(addr, addr, 1 << size);
96
- rd += stride;
97
+
98
+ /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
99
+ * VLD2/3/4 to all lanes: bit 5 indicates register stride.
100
+ */
101
+ stride = (insn & (1 << 5)) ? 2 : 1;
102
+ vec_size = nregs == 1 ? stride * 8 : 8;
103
+
104
+ tmp = tcg_temp_new_i32();
105
+ for (reg = 0; reg < nregs; reg++) {
106
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
107
+ s->be_data | size);
108
+ if ((rd & 1) && vec_size == 16) {
109
+ /* We cannot write 16 bytes at once because the
110
+ * destination is unaligned.
111
+ */
112
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
113
+ 8, 8, tmp);
114
+ tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
115
+ neon_reg_offset(rd, 0), 8, 8);
116
+ } else {
117
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
118
+ vec_size, vec_size, tmp);
119
}
120
+ tcg_gen_addi_i32(addr, addr, 1 << size);
121
+ rd += stride;
122
}
123
+ tcg_temp_free_i32(tmp);
124
tcg_temp_free_i32(addr);
125
stride = (1 << size) * nregs;
126
} else {
127
--
226
--
128
2.19.1
227
2.20.1
129
228
130
229
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
2
2
group to decodetree.
3
Instead of shifts and masks, use direct loads and stores from the neon
3
4
register file. Mirror the iteration structure of the ARM pseudocode
5
more closely. Correct the parameters of the VLD2 A2 insn.
6
7
Note that this includes a bugfix for handling of the insn
8
"VLD2 (multiple 2-element structures)" -- we were using an
9
incorrect stride value.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20181011205206.3552-19-richard.henderson@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-5-peter.maydell@linaro.org
15
---
7
---
16
target/arm/translate.c | 170 ++++++++++++++++++-----------------------
8
target/arm/neon-dp.decode | 9 ++++
17
1 file changed, 74 insertions(+), 96 deletions(-)
9
target/arm/translate-neon.inc.c | 59 ++++++++++++++++++++++++
18
10
target/arm/translate.c | 81 +--------------------------------
11
3 files changed, 70 insertions(+), 79 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
19
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
20
&2misc vm=%vm_dp vd=%vd_dp
21
+ @2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
22
+ &2misc vm=%vm_dp vd=%vd_dp q=0
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
25
26
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
27
28
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
29
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
30
+
31
+ VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
32
+ # VQMOVUN: unsigned result (source is always signed)
33
+ VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
34
+ # VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
35
+ VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
36
+ VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
37
]
38
39
# Subgroup for size != 0b11
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.inc.c
43
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
45
};
46
return do_zip_uzp(s, a, fn[a->q][a->size]);
47
}
48
+
49
+static bool do_vmovn(DisasContext *s, arg_2misc *a,
50
+ NeonGenNarrowEnvFn *narrowfn)
51
+{
52
+ TCGv_i64 rm;
53
+ TCGv_i32 rd0, rd1;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if (a->vm & 1) {
66
+ return false;
67
+ }
68
+
69
+ if (!narrowfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ rm = tcg_temp_new_i64();
78
+ rd0 = tcg_temp_new_i32();
79
+ rd1 = tcg_temp_new_i32();
80
+
81
+ neon_load_reg64(rm, a->vm);
82
+ narrowfn(rd0, cpu_env, rm);
83
+ neon_load_reg64(rm, a->vm + 1);
84
+ narrowfn(rd1, cpu_env, rm);
85
+ neon_store_reg(a->vd, 0, rd0);
86
+ neon_store_reg(a->vd, 1, rd1);
87
+ tcg_temp_free_i64(rm);
88
+ return true;
89
+}
90
+
91
+#define DO_VMOVN(INSN, FUNC) \
92
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
93
+ { \
94
+ static NeonGenNarrowEnvFn * const narrowfn[] = { \
95
+ FUNC##8, \
96
+ FUNC##16, \
97
+ FUNC##32, \
98
+ NULL, \
99
+ }; \
100
+ return do_vmovn(s, a, narrowfn[a->size]); \
101
+ }
102
+
103
+DO_VMOVN(VMOVN, gen_neon_narrow_u)
104
+DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
105
+DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
106
+DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
108
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
109
--- a/target/arm/translate.c
22
+++ b/target/arm/translate.c
110
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
111
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
24
return tmp;
112
tcg_temp_free_i32(rd);
25
}
113
}
26
114
27
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
115
-static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
28
+{
116
-{
29
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
117
- switch (size) {
30
+
118
- case 0: gen_helper_neon_narrow_u8(dest, src); break;
31
+ switch (mop) {
119
- case 1: gen_helper_neon_narrow_u16(dest, src); break;
32
+ case MO_UB:
120
- case 2: tcg_gen_extrl_i64_i32(dest, src); break;
33
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
121
- default: abort();
34
+ break;
122
- }
35
+ case MO_UW:
123
-}
36
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
124
-
37
+ break;
125
-static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
38
+ case MO_UL:
126
-{
39
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
127
- switch (size) {
40
+ break;
128
- case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
41
+ case MO_Q:
129
- case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
42
+ tcg_gen_ld_i64(var, cpu_env, offset);
130
- case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
43
+ break;
131
- default: abort();
44
+ default:
132
- }
45
+ g_assert_not_reached();
133
-}
46
+ }
134
-
47
+}
135
-static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
48
+
136
-{
49
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
137
- switch (size) {
138
- case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
139
- case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
140
- case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
141
- default: abort();
142
- }
143
-}
144
-
145
-static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
146
-{
147
- switch (size) {
148
- case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
149
- case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
150
- case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
151
- default: abort();
152
- }
153
-}
154
-
155
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
50
{
156
{
51
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
157
if (u) {
52
tcg_temp_free_i32(var);
158
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
159
tcg_temp_free_i32(src);
53
}
160
}
54
161
55
+static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
162
-static void gen_neon_narrow_op(int op, int u, int size,
56
+{
163
- TCGv_i32 dest, TCGv_i64 src)
57
+ long offset = neon_element_offset(reg, ele, size);
164
-{
58
+
165
- if (op) {
59
+ switch (size) {
166
- if (u) {
60
+ case MO_8:
167
- gen_neon_unarrow_sats(size, dest, src);
61
+ tcg_gen_st8_i64(var, cpu_env, offset);
168
- } else {
62
+ break;
169
- gen_neon_narrow(size, dest, src);
63
+ case MO_16:
170
- }
64
+ tcg_gen_st16_i64(var, cpu_env, offset);
171
- } else {
65
+ break;
172
- if (u) {
66
+ case MO_32:
173
- gen_neon_narrow_satu(size, dest, src);
67
+ tcg_gen_st32_i64(var, cpu_env, offset);
174
- } else {
68
+ break;
175
- gen_neon_narrow_sats(size, dest, src);
69
+ case MO_64:
176
- }
70
+ tcg_gen_st_i64(var, cpu_env, offset);
177
- }
71
+ break;
178
-}
72
+ default:
179
-
73
+ g_assert_not_reached();
180
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
74
+ }
181
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
75
+}
182
* table A7-13.
76
+
183
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
static inline void neon_load_reg64(TCGv_i64 var, int reg)
184
!arm_dc_feature(s, ARM_FEATURE_V8)) {
78
{
185
return 1;
79
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
186
}
80
@@ -XXX,XX +XXX,XX @@ static struct {
187
- if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
81
int interleave;
188
- q && ((rm | rd) & 1)) {
82
int spacing;
189
+ if (q && ((rm | rd) & 1)) {
83
} const neon_ls_element_type[11] = {
190
return 1;
84
- {4, 4, 1},
191
}
85
- {4, 4, 2},
192
switch (op) {
86
+ {1, 4, 1},
193
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
87
+ {1, 4, 2},
194
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
88
{4, 1, 1},
195
case NEON_2RM_VUZP:
89
- {4, 2, 1},
196
case NEON_2RM_VZIP:
90
- {3, 3, 1},
197
+ case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
91
- {3, 3, 2},
198
/* handled by decodetree */
92
+ {2, 2, 2},
199
return 1;
93
+ {1, 3, 1},
200
case NEON_2RM_VTRN:
94
+ {1, 3, 2},
201
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
95
{3, 1, 1},
202
goto elementwise;
96
{1, 1, 1},
203
}
97
- {2, 2, 1},
204
break;
98
- {2, 2, 2},
205
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
99
+ {1, 2, 1},
206
- /* also VQMOVUN; op field and mnemonics don't line up */
100
+ {1, 2, 2},
207
- if (rm & 1) {
101
{2, 1, 1}
208
- return 1;
102
};
209
- }
103
210
- tmp2 = NULL;
104
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
211
- for (pass = 0; pass < 2; pass++) {
105
int shift;
212
- neon_load_reg64(cpu_V0, rm + pass);
106
int n;
213
- tmp = tcg_temp_new_i32();
107
int vec_size;
214
- gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
108
+ int mmu_idx;
215
- tmp, cpu_V0);
109
+ TCGMemOp endian;
216
- if (pass == 0) {
110
TCGv_i32 addr;
217
- tmp2 = tmp;
111
TCGv_i32 tmp;
112
TCGv_i32 tmp2;
113
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
114
rn = (insn >> 16) & 0xf;
115
rm = insn & 0xf;
116
load = (insn & (1 << 21)) != 0;
117
+ endian = s->be_data;
118
+ mmu_idx = get_mem_index(s);
119
if ((insn & (1 << 23)) == 0) {
120
/* Load store all elements. */
121
op = (insn >> 8) & 0xf;
122
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
123
nregs = neon_ls_element_type[op].nregs;
124
interleave = neon_ls_element_type[op].interleave;
125
spacing = neon_ls_element_type[op].spacing;
126
- if (size == 3 && (interleave | spacing) != 1)
127
+ if (size == 3 && (interleave | spacing) != 1) {
128
return 1;
129
+ }
130
+ tmp64 = tcg_temp_new_i64();
131
addr = tcg_temp_new_i32();
132
+ tmp2 = tcg_const_i32(1 << size);
133
load_reg_var(s, addr, rn);
134
- stride = (1 << size) * interleave;
135
for (reg = 0; reg < nregs; reg++) {
136
- if (interleave > 2 || (interleave == 2 && nregs == 2)) {
137
- load_reg_var(s, addr, rn);
138
- tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
139
- } else if (interleave == 2 && nregs == 4 && reg == 2) {
140
- load_reg_var(s, addr, rn);
141
- tcg_gen_addi_i32(addr, addr, 1 << size);
142
- }
143
- if (size == 3) {
144
- tmp64 = tcg_temp_new_i64();
145
- if (load) {
146
- gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
147
- neon_store_reg64(tmp64, rd);
148
- } else {
149
- neon_load_reg64(tmp64, rd);
150
- gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
151
- }
152
- tcg_temp_free_i64(tmp64);
153
- tcg_gen_addi_i32(addr, addr, stride);
154
- } else {
155
- for (pass = 0; pass < 2; pass++) {
156
- if (size == 2) {
157
- if (load) {
158
- tmp = tcg_temp_new_i32();
159
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
160
- neon_store_reg(rd, pass, tmp);
161
- } else {
218
- } else {
162
- tmp = neon_load_reg(rd, pass);
219
- neon_store_reg(rd, 0, tmp2);
163
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
220
- neon_store_reg(rd, 1, tmp);
164
- tcg_temp_free_i32(tmp);
165
- }
221
- }
166
- tcg_gen_addi_i32(addr, addr, stride);
222
- }
167
- } else if (size == 1) {
223
- break;
168
- if (load) {
224
case NEON_2RM_VSHLL:
169
- tmp = tcg_temp_new_i32();
225
if (q || (rd & 1)) {
170
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
226
return 1;
171
- tcg_gen_addi_i32(addr, addr, stride);
172
- tmp2 = tcg_temp_new_i32();
173
- gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
174
- tcg_gen_addi_i32(addr, addr, stride);
175
- tcg_gen_shli_i32(tmp2, tmp2, 16);
176
- tcg_gen_or_i32(tmp, tmp, tmp2);
177
- tcg_temp_free_i32(tmp2);
178
- neon_store_reg(rd, pass, tmp);
179
- } else {
180
- tmp = neon_load_reg(rd, pass);
181
- tmp2 = tcg_temp_new_i32();
182
- tcg_gen_shri_i32(tmp2, tmp, 16);
183
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
184
- tcg_temp_free_i32(tmp);
185
- tcg_gen_addi_i32(addr, addr, stride);
186
- gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
187
- tcg_temp_free_i32(tmp2);
188
- tcg_gen_addi_i32(addr, addr, stride);
189
- }
190
- } else /* size == 0 */ {
191
- if (load) {
192
- tmp2 = NULL;
193
- for (n = 0; n < 4; n++) {
194
- tmp = tcg_temp_new_i32();
195
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
196
- tcg_gen_addi_i32(addr, addr, stride);
197
- if (n == 0) {
198
- tmp2 = tmp;
199
- } else {
200
- tcg_gen_shli_i32(tmp, tmp, n * 8);
201
- tcg_gen_or_i32(tmp2, tmp2, tmp);
202
- tcg_temp_free_i32(tmp);
203
- }
204
- }
205
- neon_store_reg(rd, pass, tmp2);
206
- } else {
207
- tmp2 = neon_load_reg(rd, pass);
208
- for (n = 0; n < 4; n++) {
209
- tmp = tcg_temp_new_i32();
210
- if (n == 0) {
211
- tcg_gen_mov_i32(tmp, tmp2);
212
- } else {
213
- tcg_gen_shri_i32(tmp, tmp2, n * 8);
214
- }
215
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
216
- tcg_temp_free_i32(tmp);
217
- tcg_gen_addi_i32(addr, addr, stride);
218
- }
219
- tcg_temp_free_i32(tmp2);
220
- }
221
+ for (n = 0; n < 8 >> size; n++) {
222
+ int xs;
223
+ for (xs = 0; xs < interleave; xs++) {
224
+ int tt = rd + reg + spacing * xs;
225
+
226
+ if (load) {
227
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
228
+ neon_store_element64(tt, n, size, tmp64);
229
+ } else {
230
+ neon_load_element64(tmp64, tt, n, size);
231
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
232
}
233
+ tcg_gen_add_i32(addr, addr, tmp2);
234
}
235
}
236
- rd += spacing;
237
}
238
tcg_temp_free_i32(addr);
239
- stride = nregs * 8;
240
+ tcg_temp_free_i32(tmp2);
241
+ tcg_temp_free_i64(tmp64);
242
+ stride = nregs * interleave * 8;
243
} else {
244
size = (insn >> 10) & 3;
245
if (size == 3) {
246
--
227
--
247
2.19.1
228
2.20.1
248
229
249
230
diff view generated by jsdifflib
1
The HCR.DC virtualization configuration register bit has the
1
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree.
2
following effects:
3
* SCTLR.M behaves as if it is 0 for all purposes except
4
direct reads of the bit
5
* HCR.VM behaves as if it is 1 for all purposes except
6
direct reads of the bit
7
* the memory type produced by the first stage of the EL1&EL0
8
translation regime is Normal Non-Shareable,
9
Inner Write-Back Read-Allocate Write-Allocate,
10
Outer Write-Back Read-Allocate Write-Allocate.
11
12
Implement this behaviour.
13
2
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20181012144235.19646-5-peter.maydell@linaro.org
5
Message-id: 20200616170844.13318-6-peter.maydell@linaro.org
17
---
6
---
18
target/arm/helper.c | 23 +++++++++++++++++++++--
7
target/arm/neon-dp.decode | 2 ++
19
1 file changed, 21 insertions(+), 2 deletions(-)
8
target/arm/translate-neon.inc.c | 52 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 35 +---------------------
10
3 files changed, 55 insertions(+), 34 deletions(-)
20
11
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
14
--- a/target/arm/neon-dp.decode
24
+++ b/target/arm/helper.c
15
+++ b/target/arm/neon-dp.decode
25
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
26
* * The Non-secure TTBCR.EAE bit is set to 1
17
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
27
* * The implementation includes EL2, and the value of HCR.VM is 1
18
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
28
*
19
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
29
+ * (Note that HCR.DC makes HCR.VM behave as if it is 1.)
20
+
30
+ *
21
+ VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
31
* ATS1Hx always uses the 64bit format (not supported yet).
22
]
32
*/
23
33
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
24
# Subgroup for size != 0b11
34
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
if (arm_feature(env, ARM_FEATURE_EL2)) {
26
index XXXXXXX..XXXXXXX 100644
36
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
27
--- a/target/arm/translate-neon.inc.c
37
- format64 |= env->cp15.hcr_el2 & HCR_VM;
28
+++ b/target/arm/translate-neon.inc.c
38
+ format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
29
@@ -XXX,XX +XXX,XX @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
39
} else {
30
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
40
format64 |= arm_current_el(env) == 2;
31
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
41
}
32
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
42
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
33
+
43
}
34
+static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
44
35
+{
45
if (mmu_idx == ARMMMUIdx_S2NS) {
36
+ TCGv_i32 rm0, rm1;
46
- return (env->cp15.hcr_el2 & HCR_VM) == 0;
37
+ TCGv_i64 rd;
47
+ /* HCR.DC means HCR.VM behaves as 1 */
38
+ static NeonGenWidenFn * const widenfns[] = {
48
+ return (env->cp15.hcr_el2 & (HCR_DC | HCR_VM)) == 0;
39
+ gen_helper_neon_widen_u8,
49
}
40
+ gen_helper_neon_widen_u16,
50
41
+ tcg_gen_extu_i32_i64,
51
if (env->cp15.hcr_el2 & HCR_TGE) {
42
+ NULL,
52
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
43
+ };
53
}
44
+ NeonGenWidenFn *widenfn = widenfns[a->size];
54
}
45
+
55
46
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ if ((env->cp15.hcr_el2 & HCR_DC) &&
47
+ return false;
57
+ (mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1)) {
48
+ }
58
+ /* HCR.DC means SCTLR_EL1.M behaves as 0 */
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ ((a->vd | a->vm) & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & 1) {
57
+ return false;
58
+ }
59
+
60
+ if (!widenfn) {
61
+ return false;
62
+ }
63
+
64
+ if (!vfp_access_check(s)) {
59
+ return true;
65
+ return true;
60
+ }
66
+ }
61
+
67
+
62
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
68
+ rd = tcg_temp_new_i64();
69
+
70
+ rm0 = neon_load_reg(a->vm, 0);
71
+ rm1 = neon_load_reg(a->vm, 1);
72
+
73
+ widenfn(rd, rm0);
74
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
75
+ neon_store_reg64(rd, a->vd);
76
+ widenfn(rd, rm1);
77
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
78
+ neon_store_reg64(rd, a->vd + 1);
79
+
80
+ tcg_temp_free_i64(rd);
81
+ tcg_temp_free_i32(rm0);
82
+ tcg_temp_free_i32(rm1);
83
+ return true;
84
+}
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
90
tcg_temp_free_i32(rd);
63
}
91
}
64
92
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
93
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
66
94
-{
67
/* Combine the S1 and S2 cache attributes, if needed */
95
- if (u) {
68
if (!ret && cacheattrs != NULL) {
96
- switch (size) {
69
+ if (env->cp15.hcr_el2 & HCR_DC) {
97
- case 0: gen_helper_neon_widen_u8(dest, src); break;
70
+ /*
98
- case 1: gen_helper_neon_widen_u16(dest, src); break;
71
+ * HCR.DC forces the first stage attributes to
99
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
72
+ * Normal Non-Shareable,
100
- default: abort();
73
+ * Inner Write-Back Read-Allocate Write-Allocate,
101
- }
74
+ * Outer Write-Back Read-Allocate Write-Allocate.
102
- } else {
75
+ */
103
- switch (size) {
76
+ cacheattrs->attrs = 0xff;
104
- case 0: gen_helper_neon_widen_s8(dest, src); break;
77
+ cacheattrs->shareability = 0;
105
- case 1: gen_helper_neon_widen_s16(dest, src); break;
78
+ }
106
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
79
*cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
107
- default: abort();
80
}
108
- }
81
109
- }
110
- tcg_temp_free_i32(src);
111
-}
112
-
113
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
114
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
115
* table A7-13.
116
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
case NEON_2RM_VUZP:
118
case NEON_2RM_VZIP:
119
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
120
+ case NEON_2RM_VSHLL:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
goto elementwise;
126
}
127
break;
128
- case NEON_2RM_VSHLL:
129
- if (q || (rd & 1)) {
130
- return 1;
131
- }
132
- tmp = neon_load_reg(rm, 0);
133
- tmp2 = neon_load_reg(rm, 1);
134
- for (pass = 0; pass < 2; pass++) {
135
- if (pass == 1)
136
- tmp = tmp2;
137
- gen_neon_widen(cpu_V0, tmp, size, 1);
138
- tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
139
- neon_store_reg64(cpu_V0, rd + pass);
140
- }
141
- break;
142
case NEON_2RM_VCVT_F16_F32:
143
{
144
TCGv_ptr fpst;
82
--
145
--
83
2.19.1
146
2.20.1
84
147
85
148
diff view generated by jsdifflib
1
Create and use a utility function to extract the EC field
1
Convert the Neon insns in the 2-reg-misc group which are
2
from a syndrome, rather than open-coding the shift.
2
VCVT between f32 and f16 to decodetree.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181012144235.19646-9-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-7-peter.maydell@linaro.org
7
---
7
---
8
target/arm/internals.h | 5 +++++
8
target/arm/neon-dp.decode | 3 ++
9
target/arm/helper.c | 4 ++--
9
target/arm/translate-neon.inc.c | 96 +++++++++++++++++++++++++++++++++
10
target/arm/kvm64.c | 2 +-
10
target/arm/translate.c | 65 ++--------------------
11
target/arm/op_helper.c | 2 +-
11
3 files changed, 102 insertions(+), 62 deletions(-)
12
4 files changed, 9 insertions(+), 4 deletions(-)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
15
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/internals.h
16
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
19
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
18
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
20
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
19
21
20
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
22
+static inline uint32_t syn_get_ec(uint32_t syn)
21
+
22
+ VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
23
+ VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
24
]
25
26
# Subgroup for size != 0b11
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
32
tcg_temp_free_i32(rm1);
33
return true;
34
}
35
+
36
+static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
23
+{
37
+{
24
+ return syn >> ARM_EL_EC_SHIFT;
38
+ TCGv_ptr fpst;
39
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
40
+
41
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
42
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
43
+ return false;
44
+ }
45
+
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
48
+ ((a->vd | a->vm) & 0x10)) {
49
+ return false;
50
+ }
51
+
52
+ if ((a->vm & 1) || (a->size != 1)) {
53
+ return false;
54
+ }
55
+
56
+ if (!vfp_access_check(s)) {
57
+ return true;
58
+ }
59
+
60
+ fpst = get_fpstatus_ptr(true);
61
+ ahp = get_ahp_flag();
62
+ tmp = neon_load_reg(a->vm, 0);
63
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
64
+ tmp2 = neon_load_reg(a->vm, 1);
65
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
66
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
67
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
68
+ tcg_temp_free_i32(tmp);
69
+ tmp = neon_load_reg(a->vm, 2);
70
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
71
+ tmp3 = neon_load_reg(a->vm, 3);
72
+ neon_store_reg(a->vd, 0, tmp2);
73
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
74
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
75
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
76
+ neon_store_reg(a->vd, 1, tmp3);
77
+ tcg_temp_free_i32(tmp);
78
+ tcg_temp_free_i32(ahp);
79
+ tcg_temp_free_ptr(fpst);
80
+
81
+ return true;
25
+}
82
+}
26
+
83
+
27
/* Utility functions for constructing various kinds of syndrome value.
84
+static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
28
* Note that in general we follow the AArch64 syndrome values; in a
85
+{
29
* few cases the value in HSR for exceptions taken to AArch32 Hyp
86
+ TCGv_ptr fpst;
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
87
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
88
+
89
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
90
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
91
+ return false;
92
+ }
93
+
94
+ /* UNDEF accesses to D16-D31 if they don't exist. */
95
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
96
+ ((a->vd | a->vm) & 0x10)) {
97
+ return false;
98
+ }
99
+
100
+ if ((a->vd & 1) || (a->size != 1)) {
101
+ return false;
102
+ }
103
+
104
+ if (!vfp_access_check(s)) {
105
+ return true;
106
+ }
107
+
108
+ fpst = get_fpstatus_ptr(true);
109
+ ahp = get_ahp_flag();
110
+ tmp3 = tcg_temp_new_i32();
111
+ tmp = neon_load_reg(a->vm, 0);
112
+ tmp2 = neon_load_reg(a->vm, 1);
113
+ tcg_gen_ext16u_i32(tmp3, tmp);
114
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
115
+ neon_store_reg(a->vd, 0, tmp3);
116
+ tcg_gen_shri_i32(tmp, tmp, 16);
117
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
118
+ neon_store_reg(a->vd, 1, tmp);
119
+ tmp3 = tcg_temp_new_i32();
120
+ tcg_gen_ext16u_i32(tmp3, tmp2);
121
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
122
+ neon_store_reg(a->vd, 2, tmp3);
123
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
124
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
125
+ neon_store_reg(a->vd, 3, tmp2);
126
+ tcg_temp_free_i32(ahp);
127
+ tcg_temp_free_ptr(fpst);
128
+
129
+ return true;
130
+}
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
133
--- a/target/arm/translate.c
33
+++ b/target/arm/helper.c
134
+++ b/target/arm/translate.c
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
135
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
35
uint32_t moe;
136
int pass;
36
137
int u;
37
/* If this is a debug exception we must update the DBGDSCR.MOE bits */
138
int vec_size;
38
- switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) {
139
- TCGv_i32 tmp, tmp2, tmp3;
39
+ switch (syn_get_ec(env->exception.syndrome)) {
140
+ TCGv_i32 tmp, tmp2;
40
case EC_BREAKPOINT:
141
41
case EC_BREAKPOINT_SAME_EL:
142
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
42
moe = 1;
143
return 1;
43
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
44
if (qemu_loglevel_mask(CPU_LOG_INT)
145
case NEON_2RM_VZIP:
45
&& !excp_is_internal(cs->exception_index)) {
146
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
46
qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
147
case NEON_2RM_VSHLL:
47
- env->exception.syndrome >> ARM_EL_EC_SHIFT,
148
+ case NEON_2RM_VCVT_F16_F32:
48
+ syn_get_ec(env->exception.syndrome),
149
+ case NEON_2RM_VCVT_F32_F16:
49
env->exception.syndrome);
150
/* handled by decodetree */
50
}
151
return 1;
51
152
case NEON_2RM_VTRN:
52
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
53
index XXXXXXX..XXXXXXX 100644
154
goto elementwise;
54
--- a/target/arm/kvm64.c
155
}
55
+++ b/target/arm/kvm64.c
156
break;
56
@@ -XXX,XX +XXX,XX @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
157
- case NEON_2RM_VCVT_F16_F32:
57
158
- {
58
bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
159
- TCGv_ptr fpst;
59
{
160
- TCGv_i32 ahp;
60
- int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
161
-
61
+ int hsr_ec = syn_get_ec(debug_exit->hsr);
162
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
62
ARMCPU *cpu = ARM_CPU(cs);
163
- q || (rm & 1)) {
63
CPUClass *cc = CPU_GET_CLASS(cs);
164
- return 1;
64
CPUARMState *env = &cpu->env;
165
- }
65
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
166
- fpst = get_fpstatus_ptr(true);
66
index XXXXXXX..XXXXXXX 100644
167
- ahp = get_ahp_flag();
67
--- a/target/arm/op_helper.c
168
- tmp = neon_load_reg(rm, 0);
68
+++ b/target/arm/op_helper.c
169
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
69
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
170
- tmp2 = neon_load_reg(rm, 1);
70
* (see DDI0478C.a D1.10.4)
171
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
71
*/
172
- tcg_gen_shli_i32(tmp2, tmp2, 16);
72
target_el = 2;
173
- tcg_gen_or_i32(tmp2, tmp2, tmp);
73
- if (syndrome >> ARM_EL_EC_SHIFT == EC_ADVSIMDFPACCESSTRAP) {
174
- tcg_temp_free_i32(tmp);
74
+ if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
175
- tmp = neon_load_reg(rm, 2);
75
syndrome = syn_uncategorized();
176
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
76
}
177
- tmp3 = neon_load_reg(rm, 3);
77
}
178
- neon_store_reg(rd, 0, tmp2);
179
- gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
180
- tcg_gen_shli_i32(tmp3, tmp3, 16);
181
- tcg_gen_or_i32(tmp3, tmp3, tmp);
182
- neon_store_reg(rd, 1, tmp3);
183
- tcg_temp_free_i32(tmp);
184
- tcg_temp_free_i32(ahp);
185
- tcg_temp_free_ptr(fpst);
186
- break;
187
- }
188
- case NEON_2RM_VCVT_F32_F16:
189
- {
190
- TCGv_ptr fpst;
191
- TCGv_i32 ahp;
192
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
193
- q || (rd & 1)) {
194
- return 1;
195
- }
196
- fpst = get_fpstatus_ptr(true);
197
- ahp = get_ahp_flag();
198
- tmp3 = tcg_temp_new_i32();
199
- tmp = neon_load_reg(rm, 0);
200
- tmp2 = neon_load_reg(rm, 1);
201
- tcg_gen_ext16u_i32(tmp3, tmp);
202
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
203
- neon_store_reg(rd, 0, tmp3);
204
- tcg_gen_shri_i32(tmp, tmp, 16);
205
- gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
206
- neon_store_reg(rd, 1, tmp);
207
- tmp3 = tcg_temp_new_i32();
208
- tcg_gen_ext16u_i32(tmp3, tmp2);
209
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
210
- neon_store_reg(rd, 2, tmp3);
211
- tcg_gen_shri_i32(tmp2, tmp2, 16);
212
- gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
213
- neon_store_reg(rd, 3, tmp2);
214
- tcg_temp_free_i32(ahp);
215
- tcg_temp_free_ptr(fpst);
216
- break;
217
- }
218
case NEON_2RM_AESE: case NEON_2RM_AESMC:
219
if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
220
return 1;
78
--
221
--
79
2.19.1
222
2.20.1
80
223
81
224
diff view generated by jsdifflib
1
For traps of FP/SIMD instructions to AArch32 Hyp mode, the syndrome
1
Convert to decodetree the insns in the Neon 2-reg-misc grouping which
2
provided in HSR has more information than is reported to AArch64.
2
we implement using gvec.
3
Specifically, there are extra fields TA and coproc which indicate
4
whether the trapped instruction was FP or SIMD. Add this extra
5
information to the syndromes we construct, and mask it out when
6
taking the exception to AArch64.
7
3
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20181012144235.19646-11-peter.maydell@linaro.org
6
Message-id: 20200616170844.13318-8-peter.maydell@linaro.org
11
---
7
---
12
target/arm/internals.h | 14 +++++++++++++-
8
target/arm/neon-dp.decode | 11 +++++++
13
target/arm/helper.c | 9 +++++++++
9
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
14
target/arm/translate.c | 8 ++++----
10
target/arm/translate.c | 35 +++++----------------
15
3 files changed, 26 insertions(+), 5 deletions(-)
11
3 files changed, 74 insertions(+), 27 deletions(-)
16
12
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/internals.h
15
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/internals.h
16
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_get_ec(uint32_t syn)
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
* few cases the value in HSR for exceptions taken to AArch32 Hyp
18
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
23
* mode differs slightly, and we fix this up when populating HSR in
19
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
24
* arm_cpu_do_interrupt_aarch32_hyp().
20
25
+ * The exception is FP/SIMD access traps -- these report extra information
21
+ VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
26
+ * when taking an exception to AArch32. For those we include the extra coproc
22
+
27
+ * and TA fields, and mask them out when taking the exception to AArch64.
23
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
28
*/
24
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
29
static inline uint32_t syn_uncategorized(void)
25
30
{
26
+ VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
31
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
27
+ VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
32
28
+ VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
33
static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
29
+ VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
34
{
30
+ VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
35
+ /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
31
+
36
return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
32
+ VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
37
| (is_16bit ? 0 : ARM_EL_IL)
33
+ VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
38
- | (cv << 24) | (cond << 20);
34
+
39
+ | (cv << 24) | (cond << 20) | 0xa;
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
37
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-neon.inc.c
41
+++ b/target/arm/translate-neon.inc.c
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
43
44
return true;
45
}
46
+
47
+static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
48
+{
49
+ int vec_size = a->q ? 16 : 8;
50
+ int rd_ofs = neon_reg_offset(a->vd, 0);
51
+ int rm_ofs = neon_reg_offset(a->vm, 0);
52
+
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
+ return false;
55
+ }
56
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size == 3) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ fn(a->size, rd_ofs, rm_ofs, vec_size, vec_size);
76
+
77
+ return true;
40
+}
78
+}
41
+
79
+
42
+static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
80
+#define DO_2MISC_VEC(INSN, FN) \
81
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
82
+ { \
83
+ return do_2misc_vec(s, a, FN); \
84
+ }
85
+
86
+DO_2MISC_VEC(VNEG, tcg_gen_gvec_neg)
87
+DO_2MISC_VEC(VABS, tcg_gen_gvec_abs)
88
+DO_2MISC_VEC(VCEQ0, gen_gvec_ceq0)
89
+DO_2MISC_VEC(VCGT0, gen_gvec_cgt0)
90
+DO_2MISC_VEC(VCLE0, gen_gvec_cle0)
91
+DO_2MISC_VEC(VCGE0, gen_gvec_cge0)
92
+DO_2MISC_VEC(VCLT0, gen_gvec_clt0)
93
+
94
+static bool trans_VMVN(DisasContext *s, arg_2misc *a)
43
+{
95
+{
44
+ /* AArch32 SIMD trap: TA == 1 coproc == 0 */
96
+ if (a->size != 0) {
45
+ return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
97
+ return false;
46
+ | (is_16bit ? 0 : ARM_EL_IL)
98
+ }
47
+ | (cv << 24) | (cond << 20) | (1 << 5);
99
+ return do_2misc_vec(s, a, tcg_gen_gvec_not);
48
}
100
+}
49
50
static inline uint32_t syn_sve_access_trap(void)
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/helper.c
54
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
56
case EXCP_HVC:
57
case EXCP_HYP_TRAP:
58
case EXCP_SMC:
59
+ if (syn_get_ec(env->exception.syndrome) == EC_ADVSIMDFPACCESSTRAP) {
60
+ /*
61
+ * QEMU internal FP/SIMD syndromes from AArch32 include the
62
+ * TA and coproc fields which are only exposed if the exception
63
+ * is taken to AArch32 Hyp mode. Mask them out to get a valid
64
+ * AArch64 format syndrome.
65
+ */
66
+ env->exception.syndrome &= ~MAKE_64BIT_MASK(0, 20);
67
+ }
68
env->cp15.esr_el[new_el] = env->exception.syndrome;
69
break;
70
case EXCP_IRQ:
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
101
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
102
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
103
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
104
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
76
*/
77
if (s->fp_excp_el) {
78
gen_exception_insn(s, 4, EXCP_UDEF,
79
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
80
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
81
return 0;
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
105
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
85
*/
106
int size;
86
if (s->fp_excp_el) {
107
int pass;
87
gen_exception_insn(s, 4, EXCP_UDEF,
108
int u;
88
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
109
- int vec_size;
89
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
110
TCGv_i32 tmp, tmp2;
90
return 0;
111
91
}
112
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
92
113
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
93
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
114
VFP_DREG_D(rd, insn);
94
115
VFP_DREG_M(rm, insn);
95
if (s->fp_excp_el) {
116
size = (insn >> 20) & 3;
96
gen_exception_insn(s, 4, EXCP_UDEF,
117
- vec_size = q ? 16 : 8;
97
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
118
rd_ofs = neon_reg_offset(rd, 0);
98
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
119
rm_ofs = neon_reg_offset(rm, 0);
99
return 0;
120
100
}
121
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
if (!s->vfp_enabled) {
122
case NEON_2RM_VSHLL:
102
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
123
case NEON_2RM_VCVT_F16_F32:
103
124
case NEON_2RM_VCVT_F32_F16:
104
if (s->fp_excp_el) {
125
+ case NEON_2RM_VMVN:
105
gen_exception_insn(s, 4, EXCP_UDEF,
126
+ case NEON_2RM_VNEG:
106
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
127
+ case NEON_2RM_VABS:
107
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
128
+ case NEON_2RM_VCEQ0:
108
return 0;
129
+ case NEON_2RM_VCGT0:
109
}
130
+ case NEON_2RM_VCLE0:
110
if (!s->vfp_enabled) {
131
+ case NEON_2RM_VCGE0:
132
+ case NEON_2RM_VCLT0:
133
/* handled by decodetree */
134
return 1;
135
case NEON_2RM_VTRN:
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
q ? gen_helper_crypto_sha256su0
138
: gen_helper_crypto_sha1su1);
139
break;
140
- case NEON_2RM_VMVN:
141
- tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
142
- break;
143
- case NEON_2RM_VNEG:
144
- tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
145
- break;
146
- case NEON_2RM_VABS:
147
- tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
148
- break;
149
-
150
- case NEON_2RM_VCEQ0:
151
- gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
152
- break;
153
- case NEON_2RM_VCGT0:
154
- gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
155
- break;
156
- case NEON_2RM_VCLE0:
157
- gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
158
- break;
159
- case NEON_2RM_VCGE0:
160
- gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
161
- break;
162
- case NEON_2RM_VCLT0:
163
- gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
164
- break;
165
166
default:
167
elementwise:
111
--
168
--
112
2.19.1
169
2.20.1
113
170
114
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon-2-reg misc crypto ops (AESE, AESMC, SHA1H, SHA1SU1)
2
to decodetree.
2
3
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-10-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-9-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate.c | 29 ++++++++++-------------------
8
target/arm/neon-dp.decode | 12 ++++++++
9
1 file changed, 10 insertions(+), 19 deletions(-)
9
target/arm/translate-neon.inc.c | 42 ++++++++++++++++++++++++++
10
target/arm/translate.c | 52 +++------------------------------
11
3 files changed, 58 insertions(+), 48 deletions(-)
10
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
&2misc vm=%vm_dp vd=%vd_dp
19
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
20
&2misc vm=%vm_dp vd=%vd_dp q=0
21
+ @2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
22
+ &2misc vm=%vm_dp vd=%vd_dp q=1
23
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
25
26
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
27
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
28
29
+ AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
30
+ AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
31
+ AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
32
+ AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
33
+
34
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
35
36
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
37
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
38
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
39
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
40
41
+ SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
42
+
43
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
44
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
45
46
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
47
48
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
49
50
+ SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
51
+ SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
52
+
53
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
54
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
55
]
56
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-neon.inc.c
59
+++ b/target/arm/translate-neon.inc.c
60
@@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a)
61
}
62
return do_2misc_vec(s, a, tcg_gen_gvec_not);
63
}
64
+
65
+#define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \
66
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
67
+ uint32_t rm_ofs, uint32_t oprsz, \
68
+ uint32_t maxsz) \
69
+ { \
70
+ tcg_gen_gvec_3_ool(rd_ofs, rd_ofs, rm_ofs, oprsz, maxsz, \
71
+ DATA, FUNC); \
72
+ }
73
+
74
+#define WRAP_2M_2_OOL_FN(WRAPNAME, FUNC, DATA) \
75
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
76
+ uint32_t rm_ofs, uint32_t oprsz, \
77
+ uint32_t maxsz) \
78
+ { \
79
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, oprsz, maxsz, DATA, FUNC); \
80
+ }
81
+
82
+WRAP_2M_3_OOL_FN(gen_AESE, gen_helper_crypto_aese, 0)
83
+WRAP_2M_3_OOL_FN(gen_AESD, gen_helper_crypto_aese, 1)
84
+WRAP_2M_2_OOL_FN(gen_AESMC, gen_helper_crypto_aesmc, 0)
85
+WRAP_2M_2_OOL_FN(gen_AESIMC, gen_helper_crypto_aesmc, 1)
86
+WRAP_2M_2_OOL_FN(gen_SHA1H, gen_helper_crypto_sha1h, 0)
87
+WRAP_2M_2_OOL_FN(gen_SHA1SU1, gen_helper_crypto_sha1su1, 0)
88
+WRAP_2M_2_OOL_FN(gen_SHA256SU0, gen_helper_crypto_sha256su0, 0)
89
+
90
+#define DO_2M_CRYPTO(INSN, FEATURE, SIZE) \
91
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
92
+ { \
93
+ if (!dc_isar_feature(FEATURE, s) || a->size != SIZE) { \
94
+ return false; \
95
+ } \
96
+ return do_2misc_vec(s, a, gen_##INSN); \
97
+ }
98
+
99
+DO_2M_CRYPTO(AESE, aa32_aes, 0)
100
+DO_2M_CRYPTO(AESD, aa32_aes, 0)
101
+DO_2M_CRYPTO(AESMC, aa32_aes, 0)
102
+DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
103
+DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
104
+DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
105
+DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
106
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
108
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
109
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
110
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
16
break;
111
{
17
}
112
int op;
18
return 0;
113
int q;
19
+
114
- int rd, rm, rd_ofs, rm_ofs;
20
+ case NEON_3R_VADD_VSUB:
115
+ int rd, rm;
21
+ if (u) {
116
int size;
22
+ tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
117
int pass;
23
+ vec_size, vec_size);
118
int u;
24
+ } else {
25
+ tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
26
+ vec_size, vec_size);
27
+ }
28
+ return 0;
29
}
30
if (size == 3) {
31
/* 64-bit element instructions. */
32
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
33
cpu_V1, cpu_V0);
120
VFP_DREG_D(rd, insn);
121
VFP_DREG_M(rm, insn);
122
size = (insn >> 20) & 3;
123
- rd_ofs = neon_reg_offset(rd, 0);
124
- rm_ofs = neon_reg_offset(rm, 0);
125
126
if ((insn & (1 << 23)) == 0) {
127
/* Three register same length: handled by decodetree */
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
case NEON_2RM_VCLE0:
130
case NEON_2RM_VCGE0:
131
case NEON_2RM_VCLT0:
132
+ case NEON_2RM_AESE: case NEON_2RM_AESMC:
133
+ case NEON_2RM_SHA1H:
134
+ case NEON_2RM_SHA1SU1:
135
/* handled by decodetree */
136
return 1;
137
case NEON_2RM_VTRN:
138
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
goto elementwise;
34
}
140
}
35
break;
141
break;
36
- case NEON_3R_VADD_VSUB:
142
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
37
- if (u) {
143
- if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
38
- tcg_gen_sub_i64(CPU_V001);
144
- return 1;
145
- }
146
- /*
147
- * Bit 6 is the lowest opcode bit; it distinguishes
148
- * between encryption (AESE/AESMC) and decryption
149
- * (AESD/AESIMC).
150
- */
151
- if (op == NEON_2RM_AESE) {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
153
- vfp_reg_offset(true, rd),
154
- vfp_reg_offset(true, rm),
155
- 16, 16, extract32(insn, 6, 1),
156
- gen_helper_crypto_aese);
39
- } else {
157
- } else {
40
- tcg_gen_add_i64(CPU_V001);
158
- tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
159
- vfp_reg_offset(true, rm),
160
- 16, 16, extract32(insn, 6, 1),
161
- gen_helper_crypto_aesmc);
41
- }
162
- }
42
- break;
163
- break;
164
- case NEON_2RM_SHA1H:
165
- if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
166
- return 1;
167
- }
168
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
169
- gen_helper_crypto_sha1h);
170
- break;
171
- case NEON_2RM_SHA1SU1:
172
- if ((rm | rd) & 1) {
173
- return 1;
174
- }
175
- /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
176
- if (q) {
177
- if (!dc_isar_feature(aa32_sha2, s)) {
178
- return 1;
179
- }
180
- } else if (!dc_isar_feature(aa32_sha1, s)) {
181
- return 1;
182
- }
183
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
184
- q ? gen_helper_crypto_sha256su0
185
- : gen_helper_crypto_sha1su1);
186
- break;
187
43
default:
188
default:
44
abort();
189
elementwise:
45
}
46
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
47
tmp2 = neon_load_reg(rd, pass);
48
gen_neon_add(size, tmp, tmp2);
49
break;
50
- case NEON_3R_VADD_VSUB:
51
- if (!u) { /* VADD */
52
- gen_neon_add(size, tmp, tmp2);
53
- } else { /* VSUB */
54
- switch (size) {
55
- case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
56
- case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
57
- case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
58
- default: abort();
59
- }
60
- }
61
- break;
62
case NEON_3R_VTST_VCEQ:
63
if (!u) { /* VTST */
64
switch (size) {
65
--
190
--
66
2.19.1
191
2.20.1
67
192
68
193
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The NeonGenOneOpFn typedef breaks with the pattern of the other
2
NeonGen*Fn typedefs, because it is a TCGv_i64 -> TCGv_i64 operation
3
but it does not have '64' in its name. Rename it to NeonGenOne64OpFn,
4
so that the old name is available for a TCGv_i32 -> TCGv_i32 operation
5
(which we will need in a subsequent commit).
2
6
3
Move cmtst_op expanders from translate-a64.c.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-17-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-10-peter.maydell@linaro.org
9
---
10
---
10
target/arm/translate.h | 2 +
11
target/arm/translate.h | 2 +-
11
target/arm/translate-a64.c | 38 ------------------
12
target/arm/translate-a64.c | 4 ++--
12
target/arm/translate.c | 81 +++++++++++++++++++++++++++-----------
13
2 files changed, 3 insertions(+), 3 deletions(-)
13
3 files changed, 60 insertions(+), 61 deletions(-)
14
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 bit_op;
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
20
extern const GVecGen3 bif_op;
20
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
21
extern const GVecGen3 mla_op[4];
21
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
22
extern const GVecGen3 mls_op[4];
22
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
23
+extern const GVecGen3 cmtst_op[4];
23
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
24
extern const GVecGen2i ssra_op[4];
24
+typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
25
extern const GVecGen2i usra_op[4];
25
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
26
extern const GVecGen2i sri_op[4];
26
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
27
extern const GVecGen2i sli_op[4];
27
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
28
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
29
30
/*
31
* Forward to the isar_feature_* tests given a DisasContext pointer.
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
30
--- a/target/arm/translate-a64.c
35
+++ b/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
32
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
37
}
33
} else {
38
}
34
for (pass = 0; pass < maxpass; pass++) {
39
35
TCGv_i64 tcg_op = tcg_temp_new_i64();
40
-/* CMTST : test is "if (X & Y != 0)". */
36
- NeonGenOneOpFn *genfn;
41
-static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
37
- static NeonGenOneOpFn * const fns[2][2] = {
42
-{
38
+ NeonGenOne64OpFn *genfn;
43
- tcg_gen_and_i32(d, a, b);
39
+ static NeonGenOne64OpFn * const fns[2][2] = {
44
- tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
40
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
45
- tcg_gen_neg_i32(d, d);
41
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
46
-}
42
};
47
-
48
-static void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
49
-{
50
- tcg_gen_and_i64(d, a, b);
51
- tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
52
- tcg_gen_neg_i64(d, d);
53
-}
54
-
55
-static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
56
-{
57
- tcg_gen_and_vec(vece, d, a, b);
58
- tcg_gen_dupi_vec(vece, a, 0);
59
- tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
60
-}
61
-
62
static void handle_3same_64(DisasContext *s, int opcode, bool u,
63
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
64
{
65
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
66
/* Integer op subgroup of C3.6.16. */
67
static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
68
{
69
- static const GVecGen3 cmtst_op[4] = {
70
- { .fni4 = gen_helper_neon_tst_u8,
71
- .fniv = gen_cmtst_vec,
72
- .vece = MO_8 },
73
- { .fni4 = gen_helper_neon_tst_u16,
74
- .fniv = gen_cmtst_vec,
75
- .vece = MO_16 },
76
- { .fni4 = gen_cmtst_i32,
77
- .fniv = gen_cmtst_vec,
78
- .vece = MO_32 },
79
- { .fni8 = gen_cmtst_i64,
80
- .fniv = gen_cmtst_vec,
81
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
82
- .vece = MO_64 },
83
- };
84
-
85
int is_q = extract32(insn, 30, 1);
86
int u = extract32(insn, 29, 1);
87
int size = extract32(insn, 22, 2);
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate.c
91
+++ b/target/arm/translate.c
92
@@ -XXX,XX +XXX,XX @@ const GVecGen3 mls_op[4] = {
93
.vece = MO_64 },
94
};
95
96
+/* CMTST : test is "if (X & Y != 0)". */
97
+static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
98
+{
99
+ tcg_gen_and_i32(d, a, b);
100
+ tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
101
+ tcg_gen_neg_i32(d, d);
102
+}
103
+
104
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
105
+{
106
+ tcg_gen_and_i64(d, a, b);
107
+ tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
108
+ tcg_gen_neg_i64(d, d);
109
+}
110
+
111
+static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
112
+{
113
+ tcg_gen_and_vec(vece, d, a, b);
114
+ tcg_gen_dupi_vec(vece, a, 0);
115
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
116
+}
117
+
118
+const GVecGen3 cmtst_op[4] = {
119
+ { .fni4 = gen_helper_neon_tst_u8,
120
+ .fniv = gen_cmtst_vec,
121
+ .vece = MO_8 },
122
+ { .fni4 = gen_helper_neon_tst_u16,
123
+ .fniv = gen_cmtst_vec,
124
+ .vece = MO_16 },
125
+ { .fni4 = gen_cmtst_i32,
126
+ .fniv = gen_cmtst_vec,
127
+ .vece = MO_32 },
128
+ { .fni8 = gen_cmtst_i64,
129
+ .fniv = gen_cmtst_vec,
130
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
131
+ .vece = MO_64 },
132
+};
133
+
134
/* Translate a NEON data processing instruction. Return nonzero if the
135
instruction is invalid.
136
We process data in a mixture of 32-bit and 64-bit chunks.
137
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
138
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
139
u ? &mls_op[size] : &mla_op[size]);
140
return 0;
141
+
142
+ case NEON_3R_VTST_VCEQ:
143
+ if (u) { /* VCEQ */
144
+ tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
145
+ vec_size, vec_size);
146
+ } else { /* VTST */
147
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
148
+ vec_size, vec_size, &cmtst_op[size]);
149
+ }
150
+ return 0;
151
+
152
+ case NEON_3R_VCGT:
153
+ tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
154
+ rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
155
+ return 0;
156
+
157
+ case NEON_3R_VCGE:
158
+ tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
159
+ rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
160
+ return 0;
161
}
162
163
if (size == 3) {
164
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
165
case NEON_3R_VQSUB:
166
GEN_NEON_INTEGER_OP_ENV(qsub);
167
break;
168
- case NEON_3R_VCGT:
169
- GEN_NEON_INTEGER_OP(cgt);
170
- break;
171
- case NEON_3R_VCGE:
172
- GEN_NEON_INTEGER_OP(cge);
173
- break;
174
case NEON_3R_VSHL:
175
GEN_NEON_INTEGER_OP(shl);
176
break;
177
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
178
tmp2 = neon_load_reg(rd, pass);
179
gen_neon_add(size, tmp, tmp2);
180
break;
181
- case NEON_3R_VTST_VCEQ:
182
- if (!u) { /* VTST */
183
- switch (size) {
184
- case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
185
- case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
186
- case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
187
- default: abort();
188
- }
189
- } else { /* VCEQ */
190
- switch (size) {
191
- case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
192
- case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
193
- case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
194
- default: abort();
195
- }
196
- }
197
- break;
198
case NEON_3R_VMUL:
199
/* VMUL.P8; other cases already eliminated. */
200
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
201
--
43
--
202
2.19.1
44
2.20.1
203
45
204
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
All the other typedefs like these spell "Op" with a lowercase 'p';
2
remane the NeonGenTwoSingleOPFn and NeonGenTwoDoubleOPFn typedefs to
3
match.
2
4
3
Move mla_op and mls_op expanders from translate-a64.c.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-16-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-11-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate.h | 2 +
9
target/arm/translate.h | 4 ++--
11
target/arm/translate-a64.c | 106 -----------------------------
10
target/arm/translate-a64.c | 4 ++--
12
target/arm/translate.c | 134 ++++++++++++++++++++++++++++++++-----
11
target/arm/translate-neon.inc.c | 2 +-
13
3 files changed, 120 insertions(+), 122 deletions(-)
12
3 files changed, 5 insertions(+), 5 deletions(-)
14
13
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
16
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
17
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
20
extern const GVecGen3 bsl_op;
19
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
21
extern const GVecGen3 bit_op;
20
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
22
extern const GVecGen3 bif_op;
21
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
23
+extern const GVecGen3 mla_op[4];
22
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
24
+extern const GVecGen3 mls_op[4];
23
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
25
extern const GVecGen2i ssra_op[4];
24
+typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
26
extern const GVecGen2i usra_op[4];
25
+typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
27
extern const GVecGen2i sri_op[4];
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
27
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
28
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
33
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
33
}
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
35
TCGv_i64 tcg_zero = tcg_const_i64(0);
36
TCGv_i64 tcg_res = tcg_temp_new_i64();
37
- NeonGenTwoDoubleOPFn *genfn;
38
+ NeonGenTwoDoubleOpFn *genfn;
39
bool swap = false;
40
int pass;
41
42
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
43
TCGv_i32 tcg_op = tcg_temp_new_i32();
44
TCGv_i32 tcg_zero = tcg_const_i32(0);
45
TCGv_i32 tcg_res = tcg_temp_new_i32();
46
- NeonGenTwoSingleOPFn *genfn;
47
+ NeonGenTwoSingleOpFn *genfn;
48
bool swap = false;
49
int pass, maxpasses;
50
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
54
+++ b/target/arm/translate-neon.inc.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
34
}
56
}
35
57
36
-static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
58
static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
37
-{
59
- NeonGenTwoSingleOPFn *fn)
38
- gen_helper_neon_mul_u8(a, a, b);
60
+ NeonGenTwoSingleOpFn *fn)
39
- gen_helper_neon_add_u8(d, d, a);
40
-}
41
-
42
-static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
43
-{
44
- gen_helper_neon_mul_u16(a, a, b);
45
- gen_helper_neon_add_u16(d, d, a);
46
-}
47
-
48
-static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
49
-{
50
- tcg_gen_mul_i32(a, a, b);
51
- tcg_gen_add_i32(d, d, a);
52
-}
53
-
54
-static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
55
-{
56
- tcg_gen_mul_i64(a, a, b);
57
- tcg_gen_add_i64(d, d, a);
58
-}
59
-
60
-static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
61
-{
62
- tcg_gen_mul_vec(vece, a, a, b);
63
- tcg_gen_add_vec(vece, d, d, a);
64
-}
65
-
66
-static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
67
-{
68
- gen_helper_neon_mul_u8(a, a, b);
69
- gen_helper_neon_sub_u8(d, d, a);
70
-}
71
-
72
-static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
73
-{
74
- gen_helper_neon_mul_u16(a, a, b);
75
- gen_helper_neon_sub_u16(d, d, a);
76
-}
77
-
78
-static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
79
-{
80
- tcg_gen_mul_i32(a, a, b);
81
- tcg_gen_sub_i32(d, d, a);
82
-}
83
-
84
-static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
85
-{
86
- tcg_gen_mul_i64(a, a, b);
87
- tcg_gen_sub_i64(d, d, a);
88
-}
89
-
90
-static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
91
-{
92
- tcg_gen_mul_vec(vece, a, a, b);
93
- tcg_gen_sub_vec(vece, d, d, a);
94
-}
95
-
96
/* Integer op subgroup of C3.6.16. */
97
static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
98
{
61
{
99
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
62
/* FP operations in 2-reg-and-shift group */
100
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
63
TCGv_i32 tmp, shiftv;
101
.vece = MO_64 },
102
};
103
- static const GVecGen3 mla_op[4] = {
104
- { .fni4 = gen_mla8_i32,
105
- .fniv = gen_mla_vec,
106
- .opc = INDEX_op_mul_vec,
107
- .load_dest = true,
108
- .vece = MO_8 },
109
- { .fni4 = gen_mla16_i32,
110
- .fniv = gen_mla_vec,
111
- .opc = INDEX_op_mul_vec,
112
- .load_dest = true,
113
- .vece = MO_16 },
114
- { .fni4 = gen_mla32_i32,
115
- .fniv = gen_mla_vec,
116
- .opc = INDEX_op_mul_vec,
117
- .load_dest = true,
118
- .vece = MO_32 },
119
- { .fni8 = gen_mla64_i64,
120
- .fniv = gen_mla_vec,
121
- .opc = INDEX_op_mul_vec,
122
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
123
- .load_dest = true,
124
- .vece = MO_64 },
125
- };
126
- static const GVecGen3 mls_op[4] = {
127
- { .fni4 = gen_mls8_i32,
128
- .fniv = gen_mls_vec,
129
- .opc = INDEX_op_mul_vec,
130
- .load_dest = true,
131
- .vece = MO_8 },
132
- { .fni4 = gen_mls16_i32,
133
- .fniv = gen_mls_vec,
134
- .opc = INDEX_op_mul_vec,
135
- .load_dest = true,
136
- .vece = MO_16 },
137
- { .fni4 = gen_mls32_i32,
138
- .fniv = gen_mls_vec,
139
- .opc = INDEX_op_mul_vec,
140
- .load_dest = true,
141
- .vece = MO_32 },
142
- { .fni8 = gen_mls64_i64,
143
- .fniv = gen_mls_vec,
144
- .opc = INDEX_op_mul_vec,
145
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
146
- .load_dest = true,
147
- .vece = MO_64 },
148
- };
149
150
int is_q = extract32(insn, 30, 1);
151
int u = extract32(insn, 29, 1);
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ static void gen_neon_narrow_op(int op, int u, int size,
157
#define NEON_3R_VABA 15
158
#define NEON_3R_VADD_VSUB 16
159
#define NEON_3R_VTST_VCEQ 17
160
-#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
161
+#define NEON_3R_VML 18 /* VMLA, VMLS */
162
#define NEON_3R_VMUL 19
163
#define NEON_3R_VPMAX 20
164
#define NEON_3R_VPMIN 21
165
@@ -XXX,XX +XXX,XX @@ const GVecGen2i sli_op[4] = {
166
.vece = MO_64 },
167
};
168
169
+static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
170
+{
171
+ gen_helper_neon_mul_u8(a, a, b);
172
+ gen_helper_neon_add_u8(d, d, a);
173
+}
174
+
175
+static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
176
+{
177
+ gen_helper_neon_mul_u8(a, a, b);
178
+ gen_helper_neon_sub_u8(d, d, a);
179
+}
180
+
181
+static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
182
+{
183
+ gen_helper_neon_mul_u16(a, a, b);
184
+ gen_helper_neon_add_u16(d, d, a);
185
+}
186
+
187
+static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
188
+{
189
+ gen_helper_neon_mul_u16(a, a, b);
190
+ gen_helper_neon_sub_u16(d, d, a);
191
+}
192
+
193
+static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
194
+{
195
+ tcg_gen_mul_i32(a, a, b);
196
+ tcg_gen_add_i32(d, d, a);
197
+}
198
+
199
+static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
200
+{
201
+ tcg_gen_mul_i32(a, a, b);
202
+ tcg_gen_sub_i32(d, d, a);
203
+}
204
+
205
+static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
206
+{
207
+ tcg_gen_mul_i64(a, a, b);
208
+ tcg_gen_add_i64(d, d, a);
209
+}
210
+
211
+static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
212
+{
213
+ tcg_gen_mul_i64(a, a, b);
214
+ tcg_gen_sub_i64(d, d, a);
215
+}
216
+
217
+static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
218
+{
219
+ tcg_gen_mul_vec(vece, a, a, b);
220
+ tcg_gen_add_vec(vece, d, d, a);
221
+}
222
+
223
+static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
224
+{
225
+ tcg_gen_mul_vec(vece, a, a, b);
226
+ tcg_gen_sub_vec(vece, d, d, a);
227
+}
228
+
229
+/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
230
+ * these tables are shared with AArch64 which does support them.
231
+ */
232
+const GVecGen3 mla_op[4] = {
233
+ { .fni4 = gen_mla8_i32,
234
+ .fniv = gen_mla_vec,
235
+ .opc = INDEX_op_mul_vec,
236
+ .load_dest = true,
237
+ .vece = MO_8 },
238
+ { .fni4 = gen_mla16_i32,
239
+ .fniv = gen_mla_vec,
240
+ .opc = INDEX_op_mul_vec,
241
+ .load_dest = true,
242
+ .vece = MO_16 },
243
+ { .fni4 = gen_mla32_i32,
244
+ .fniv = gen_mla_vec,
245
+ .opc = INDEX_op_mul_vec,
246
+ .load_dest = true,
247
+ .vece = MO_32 },
248
+ { .fni8 = gen_mla64_i64,
249
+ .fniv = gen_mla_vec,
250
+ .opc = INDEX_op_mul_vec,
251
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
252
+ .load_dest = true,
253
+ .vece = MO_64 },
254
+};
255
+
256
+const GVecGen3 mls_op[4] = {
257
+ { .fni4 = gen_mls8_i32,
258
+ .fniv = gen_mls_vec,
259
+ .opc = INDEX_op_mul_vec,
260
+ .load_dest = true,
261
+ .vece = MO_8 },
262
+ { .fni4 = gen_mls16_i32,
263
+ .fniv = gen_mls_vec,
264
+ .opc = INDEX_op_mul_vec,
265
+ .load_dest = true,
266
+ .vece = MO_16 },
267
+ { .fni4 = gen_mls32_i32,
268
+ .fniv = gen_mls_vec,
269
+ .opc = INDEX_op_mul_vec,
270
+ .load_dest = true,
271
+ .vece = MO_32 },
272
+ { .fni8 = gen_mls64_i64,
273
+ .fniv = gen_mls_vec,
274
+ .opc = INDEX_op_mul_vec,
275
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
276
+ .load_dest = true,
277
+ .vece = MO_64 },
278
+};
279
+
280
/* Translate a NEON data processing instruction. Return nonzero if the
281
instruction is invalid.
282
We process data in a mixture of 32-bit and 64-bit chunks.
283
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
284
return 0;
285
}
286
break;
287
+
288
+ case NEON_3R_VML: /* VMLA, VMLS */
289
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
290
+ u ? &mls_op[size] : &mla_op[size]);
291
+ return 0;
292
}
293
+
294
if (size == 3) {
295
/* 64-bit element instructions. */
296
for (pass = 0; pass < (q ? 2 : 1); pass++) {
297
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
298
}
299
}
300
break;
301
- case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
302
- switch (size) {
303
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
304
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
305
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
306
- default: abort();
307
- }
308
- tcg_temp_free_i32(tmp2);
309
- tmp2 = neon_load_reg(rd, pass);
310
- if (u) { /* VMLS */
311
- gen_neon_rsb(size, tmp, tmp2);
312
- } else { /* VMLA */
313
- gen_neon_add(size, tmp, tmp2);
314
- }
315
- break;
316
case NEON_3R_VMUL:
317
/* VMUL.P8; other cases already eliminated. */
318
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
319
--
64
--
320
2.19.1
65
2.20.1
321
66
322
67
diff view generated by jsdifflib
1
The switch_mode() function is defined in target/arm/helper.c and used
1
Make gen_swap_half() take a source and destination TCGv_i32 rather
2
only in that file and nowhere else, so we can make it file-local
2
than modifying the input TCGv_i32; we're going to want to be able to
3
rather than global.
3
use it with the more flexible function signature, and this also
4
brings it into line with other functions like gen_rev16() and
5
gen_revsh().
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20181012144235.19646-3-peter.maydell@linaro.org
9
Message-id: 20200616170844.13318-12-peter.maydell@linaro.org
8
---
10
---
9
target/arm/internals.h | 1 -
11
target/arm/translate-neon.inc.c | 2 +-
10
target/arm/helper.c | 6 ++++--
12
target/arm/translate.c | 10 +++++-----
11
2 files changed, 4 insertions(+), 3 deletions(-)
13
2 files changed, 6 insertions(+), 6 deletions(-)
12
14
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
17
--- a/target/arm/translate-neon.inc.c
16
+++ b/target/arm/internals.h
18
+++ b/target/arm/translate-neon.inc.c
17
@@ -XXX,XX +XXX,XX @@ static inline int bank_number(int mode)
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
18
g_assert_not_reached();
20
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
21
break;
22
case 1:
23
- gen_swap_half(tmp[half]);
24
+ gen_swap_half(tmp[half], tmp[half]);
25
break;
26
case 2:
27
break;
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.c
31
+++ b/target/arm/translate.c
32
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
19
}
33
}
20
34
21
-void switch_mode(CPUARMState *, int);
35
/* Swap low and high halfwords. */
22
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
36
-static void gen_swap_half(TCGv_i32 var)
23
void arm_translate_init(void);
37
+static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
24
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
28
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
30
V8M_SAttributes *sattrs);
31
#endif
32
33
+static void switch_mode(CPUARMState *env, int mode);
34
+
35
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
36
{
38
{
37
int nregs;
39
- tcg_gen_rotri_i32(var, var, 16);
38
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
40
+ tcg_gen_rotri_i32(dest, var, 16);
39
return 0;
40
}
41
}
41
42
42
-void switch_mode(CPUARMState *env, int mode)
43
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
43
+static void switch_mode(CPUARMState *env, int mode)
44
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
44
{
45
case NEON_2RM_VREV32:
45
ARMCPU *cpu = arm_env_get_cpu(env);
46
switch (size) {
46
47
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
47
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
48
- case 1: gen_swap_half(tmp); break;
48
49
+ case 1: gen_swap_half(tmp, tmp); break;
49
#else
50
default: abort();
50
51
}
51
-void switch_mode(CPUARMState *env, int mode)
52
break;
52
+static void switch_mode(CPUARMState *env, int mode)
53
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
53
{
54
t1 = load_reg(s, a->rn);
54
int old_mode;
55
t2 = load_reg(s, a->rm);
55
int i;
56
if (m_swap) {
57
- gen_swap_half(t2);
58
+ gen_swap_half(t2, t2);
59
}
60
gen_smul_dual(t1, t2);
61
62
@@ -XXX,XX +XXX,XX @@ static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
63
t1 = load_reg(s, a->rn);
64
t2 = load_reg(s, a->rm);
65
if (m_swap) {
66
- gen_swap_half(t2);
67
+ gen_swap_half(t2, t2);
68
}
69
gen_smul_dual(t1, t2);
70
56
--
71
--
57
2.19.1
72
2.20.1
58
73
59
74
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group
2
to decodetree.
2
3
3
Move shi_op and sli_op expanders from translate-a64.c.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-15-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate.h | 2 +
8
target/arm/translate.h | 1 +
11
target/arm/translate-a64.c | 152 +----------------------
9
target/arm/neon-dp.decode | 2 ++
12
target/arm/translate.c | 244 ++++++++++++++++++++++++++-----------
10
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
13
3 files changed, 179 insertions(+), 219 deletions(-)
11
target/arm/translate.c | 12 ++-----
12
4 files changed, 60 insertions(+), 10 deletions(-)
14
13
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
16
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
17
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 bit_op;
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
20
extern const GVecGen3 bif_op;
19
uint32_t, uint32_t, uint32_t);
21
extern const GVecGen2i ssra_op[4];
20
22
extern const GVecGen2i usra_op[4];
21
/* Function prototype for gen_ functions for calling Neon helpers */
23
+extern const GVecGen2i sri_op[4];
22
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
24
+extern const GVecGen2i sli_op[4];
23
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
25
24
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
26
/*
25
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
27
* Forward to the isar_feature_* tests given a DisasContext pointer.
26
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
28
--- a/target/arm/neon-dp.decode
31
+++ b/target/arm/translate-a64.c
29
+++ b/target/arm/neon-dp.decode
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
30
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
33
}
31
&2misc vm=%vm_dp vd=%vd_dp q=1
34
}
32
35
33
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
36
-static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
34
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
37
-{
35
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
38
- uint64_t mask = dup_const(MO_8, 0xff >> shift);
36
39
- TCGv_i64 t = tcg_temp_new_i64();
37
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
40
-
38
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
41
- tcg_gen_shri_i64(t, a, shift);
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
42
- tcg_gen_andi_i64(t, t, mask);
40
index XXXXXXX..XXXXXXX 100644
43
- tcg_gen_andi_i64(d, d, ~mask);
41
--- a/target/arm/translate-neon.inc.c
44
- tcg_gen_or_i64(d, d, t);
42
+++ b/target/arm/translate-neon.inc.c
45
- tcg_temp_free_i64(t);
43
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
46
-}
44
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
47
-
45
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
48
-static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
46
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
49
-{
47
+
50
- uint64_t mask = dup_const(MO_16, 0xffff >> shift);
48
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
51
- TCGv_i64 t = tcg_temp_new_i64();
49
+{
52
-
50
+ int pass;
53
- tcg_gen_shri_i64(t, a, shift);
51
+
54
- tcg_gen_andi_i64(t, t, mask);
52
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
55
- tcg_gen_andi_i64(d, d, ~mask);
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
- tcg_gen_or_i64(d, d, t);
54
+ return false;
57
- tcg_temp_free_i64(t);
55
+ }
58
-}
56
+
59
-
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
-static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
-{
59
+ ((a->vd | a->vm) & 0x10)) {
62
- tcg_gen_shri_i32(a, a, shift);
60
+ return false;
63
- tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
61
+ }
64
-}
62
+
65
-
63
+ if (!fn) {
66
-static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
64
+ return false;
67
-{
65
+ }
68
- tcg_gen_shri_i64(a, a, shift);
66
+
69
- tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
67
+ if ((a->vd | a->vm) & a->q) {
70
-}
68
+ return false;
71
-
69
+ }
72
-static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
70
+
73
-{
71
+ if (!vfp_access_check(s)) {
74
- uint64_t mask = (2ull << ((8 << vece) - 1)) - 1;
72
+ return true;
75
- TCGv_vec t = tcg_temp_new_vec_matching(d);
73
+ }
76
- TCGv_vec m = tcg_temp_new_vec_matching(d);
74
+
77
-
75
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
78
- tcg_gen_dupi_vec(vece, m, mask ^ (mask >> sh));
76
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
79
- tcg_gen_shri_vec(vece, t, a, sh);
77
+ fn(tmp, tmp);
80
- tcg_gen_and_vec(vece, d, d, m);
78
+ neon_store_reg(a->vd, pass, tmp);
81
- tcg_gen_or_vec(vece, d, d, t);
79
+ }
82
-
80
+
83
- tcg_temp_free_vec(t);
81
+ return true;
84
- tcg_temp_free_vec(m);
82
+}
85
-}
83
+
86
-
84
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
87
/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
85
+{
88
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
86
+ static NeonGenOneOpFn * const fn[] = {
89
int immh, int immb, int opcode, int rn, int rd)
87
+ tcg_gen_bswap32_i32,
90
{
88
+ gen_swap_half,
91
- static const GVecGen2i sri_op[4] = {
89
+ NULL,
92
- { .fni8 = gen_shr8_ins_i64,
90
+ NULL,
93
- .fniv = gen_shr_ins_vec,
91
+ };
94
- .load_dest = true,
92
+ return do_2misc(s, a, fn[a->size]);
95
- .opc = INDEX_op_shri_vec,
93
+}
96
- .vece = MO_8 },
94
+
97
- { .fni8 = gen_shr16_ins_i64,
95
+static bool trans_VREV16(DisasContext *s, arg_2misc *a)
98
- .fniv = gen_shr_ins_vec,
96
+{
99
- .load_dest = true,
97
+ if (a->size != 0) {
100
- .opc = INDEX_op_shri_vec,
98
+ return false;
101
- .vece = MO_16 },
99
+ }
102
- { .fni4 = gen_shr32_ins_i32,
100
+ return do_2misc(s, a, gen_rev16);
103
- .fniv = gen_shr_ins_vec,
101
+}
104
- .load_dest = true,
105
- .opc = INDEX_op_shri_vec,
106
- .vece = MO_32 },
107
- { .fni8 = gen_shr64_ins_i64,
108
- .fniv = gen_shr_ins_vec,
109
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
110
- .load_dest = true,
111
- .opc = INDEX_op_shri_vec,
112
- .vece = MO_64 },
113
- };
114
-
115
int size = 32 - clz32(immh) - 1;
116
int immhb = immh << 3 | immb;
117
int shift = 2 * (8 << size) - immhb;
118
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
119
clear_vec_high(s, is_q, rd);
120
}
121
122
-static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
123
-{
124
- uint64_t mask = dup_const(MO_8, 0xff << shift);
125
- TCGv_i64 t = tcg_temp_new_i64();
126
-
127
- tcg_gen_shli_i64(t, a, shift);
128
- tcg_gen_andi_i64(t, t, mask);
129
- tcg_gen_andi_i64(d, d, ~mask);
130
- tcg_gen_or_i64(d, d, t);
131
- tcg_temp_free_i64(t);
132
-}
133
-
134
-static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
135
-{
136
- uint64_t mask = dup_const(MO_16, 0xffff << shift);
137
- TCGv_i64 t = tcg_temp_new_i64();
138
-
139
- tcg_gen_shli_i64(t, a, shift);
140
- tcg_gen_andi_i64(t, t, mask);
141
- tcg_gen_andi_i64(d, d, ~mask);
142
- tcg_gen_or_i64(d, d, t);
143
- tcg_temp_free_i64(t);
144
-}
145
-
146
-static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
147
-{
148
- tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
149
-}
150
-
151
-static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
152
-{
153
- tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
154
-}
155
-
156
-static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
157
-{
158
- uint64_t mask = (1ull << sh) - 1;
159
- TCGv_vec t = tcg_temp_new_vec_matching(d);
160
- TCGv_vec m = tcg_temp_new_vec_matching(d);
161
-
162
- tcg_gen_dupi_vec(vece, m, mask);
163
- tcg_gen_shli_vec(vece, t, a, sh);
164
- tcg_gen_and_vec(vece, d, d, m);
165
- tcg_gen_or_vec(vece, d, d, t);
166
-
167
- tcg_temp_free_vec(t);
168
- tcg_temp_free_vec(m);
169
-}
170
-
171
/* SHL/SLI - Vector shift left */
172
static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
173
int immh, int immb, int opcode, int rn, int rd)
174
{
175
- static const GVecGen2i shi_op[4] = {
176
- { .fni8 = gen_shl8_ins_i64,
177
- .fniv = gen_shl_ins_vec,
178
- .opc = INDEX_op_shli_vec,
179
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
180
- .load_dest = true,
181
- .vece = MO_8 },
182
- { .fni8 = gen_shl16_ins_i64,
183
- .fniv = gen_shl_ins_vec,
184
- .opc = INDEX_op_shli_vec,
185
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
186
- .load_dest = true,
187
- .vece = MO_16 },
188
- { .fni4 = gen_shl32_ins_i32,
189
- .fniv = gen_shl_ins_vec,
190
- .opc = INDEX_op_shli_vec,
191
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
192
- .load_dest = true,
193
- .vece = MO_32 },
194
- { .fni8 = gen_shl64_ins_i64,
195
- .fniv = gen_shl_ins_vec,
196
- .opc = INDEX_op_shli_vec,
197
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
198
- .load_dest = true,
199
- .vece = MO_64 },
200
- };
201
int size = 32 - clz32(immh) - 1;
202
int immhb = immh << 3 | immb;
203
int shift = immhb - (8 << size);
204
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
205
}
206
207
if (insert) {
208
- gen_gvec_op2i(s, is_q, rd, rn, shift, &shi_op[size]);
209
+ gen_gvec_op2i(s, is_q, rd, rn, shift, &sli_op[size]);
210
} else {
211
gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shli, size);
212
}
213
diff --git a/target/arm/translate.c b/target/arm/translate.c
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
214
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
215
--- a/target/arm/translate.c
104
--- a/target/arm/translate.c
216
+++ b/target/arm/translate.c
105
+++ b/target/arm/translate.c
217
@@ -XXX,XX +XXX,XX @@ const GVecGen2i usra_op[4] = {
218
.vece = MO_64, },
219
};
220
221
+static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
222
+{
223
+ uint64_t mask = dup_const(MO_8, 0xff >> shift);
224
+ TCGv_i64 t = tcg_temp_new_i64();
225
+
226
+ tcg_gen_shri_i64(t, a, shift);
227
+ tcg_gen_andi_i64(t, t, mask);
228
+ tcg_gen_andi_i64(d, d, ~mask);
229
+ tcg_gen_or_i64(d, d, t);
230
+ tcg_temp_free_i64(t);
231
+}
232
+
233
+static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
234
+{
235
+ uint64_t mask = dup_const(MO_16, 0xffff >> shift);
236
+ TCGv_i64 t = tcg_temp_new_i64();
237
+
238
+ tcg_gen_shri_i64(t, a, shift);
239
+ tcg_gen_andi_i64(t, t, mask);
240
+ tcg_gen_andi_i64(d, d, ~mask);
241
+ tcg_gen_or_i64(d, d, t);
242
+ tcg_temp_free_i64(t);
243
+}
244
+
245
+static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
246
+{
247
+ tcg_gen_shri_i32(a, a, shift);
248
+ tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
249
+}
250
+
251
+static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
252
+{
253
+ tcg_gen_shri_i64(a, a, shift);
254
+ tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
255
+}
256
+
257
+static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
258
+{
259
+ if (sh == 0) {
260
+ tcg_gen_mov_vec(d, a);
261
+ } else {
262
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
263
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
264
+
265
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
266
+ tcg_gen_shri_vec(vece, t, a, sh);
267
+ tcg_gen_and_vec(vece, d, d, m);
268
+ tcg_gen_or_vec(vece, d, d, t);
269
+
270
+ tcg_temp_free_vec(t);
271
+ tcg_temp_free_vec(m);
272
+ }
273
+}
274
+
275
+const GVecGen2i sri_op[4] = {
276
+ { .fni8 = gen_shr8_ins_i64,
277
+ .fniv = gen_shr_ins_vec,
278
+ .load_dest = true,
279
+ .opc = INDEX_op_shri_vec,
280
+ .vece = MO_8 },
281
+ { .fni8 = gen_shr16_ins_i64,
282
+ .fniv = gen_shr_ins_vec,
283
+ .load_dest = true,
284
+ .opc = INDEX_op_shri_vec,
285
+ .vece = MO_16 },
286
+ { .fni4 = gen_shr32_ins_i32,
287
+ .fniv = gen_shr_ins_vec,
288
+ .load_dest = true,
289
+ .opc = INDEX_op_shri_vec,
290
+ .vece = MO_32 },
291
+ { .fni8 = gen_shr64_ins_i64,
292
+ .fniv = gen_shr_ins_vec,
293
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
294
+ .load_dest = true,
295
+ .opc = INDEX_op_shri_vec,
296
+ .vece = MO_64 },
297
+};
298
+
299
+static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
300
+{
301
+ uint64_t mask = dup_const(MO_8, 0xff << shift);
302
+ TCGv_i64 t = tcg_temp_new_i64();
303
+
304
+ tcg_gen_shli_i64(t, a, shift);
305
+ tcg_gen_andi_i64(t, t, mask);
306
+ tcg_gen_andi_i64(d, d, ~mask);
307
+ tcg_gen_or_i64(d, d, t);
308
+ tcg_temp_free_i64(t);
309
+}
310
+
311
+static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
312
+{
313
+ uint64_t mask = dup_const(MO_16, 0xffff << shift);
314
+ TCGv_i64 t = tcg_temp_new_i64();
315
+
316
+ tcg_gen_shli_i64(t, a, shift);
317
+ tcg_gen_andi_i64(t, t, mask);
318
+ tcg_gen_andi_i64(d, d, ~mask);
319
+ tcg_gen_or_i64(d, d, t);
320
+ tcg_temp_free_i64(t);
321
+}
322
+
323
+static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
324
+{
325
+ tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
326
+}
327
+
328
+static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
329
+{
330
+ tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
331
+}
332
+
333
+static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
334
+{
335
+ if (sh == 0) {
336
+ tcg_gen_mov_vec(d, a);
337
+ } else {
338
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
339
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
340
+
341
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
342
+ tcg_gen_shli_vec(vece, t, a, sh);
343
+ tcg_gen_and_vec(vece, d, d, m);
344
+ tcg_gen_or_vec(vece, d, d, t);
345
+
346
+ tcg_temp_free_vec(t);
347
+ tcg_temp_free_vec(m);
348
+ }
349
+}
350
+
351
+const GVecGen2i sli_op[4] = {
352
+ { .fni8 = gen_shl8_ins_i64,
353
+ .fniv = gen_shl_ins_vec,
354
+ .load_dest = true,
355
+ .opc = INDEX_op_shli_vec,
356
+ .vece = MO_8 },
357
+ { .fni8 = gen_shl16_ins_i64,
358
+ .fniv = gen_shl_ins_vec,
359
+ .load_dest = true,
360
+ .opc = INDEX_op_shli_vec,
361
+ .vece = MO_16 },
362
+ { .fni4 = gen_shl32_ins_i32,
363
+ .fniv = gen_shl_ins_vec,
364
+ .load_dest = true,
365
+ .opc = INDEX_op_shli_vec,
366
+ .vece = MO_32 },
367
+ { .fni8 = gen_shl64_ins_i64,
368
+ .fniv = gen_shl_ins_vec,
369
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
370
+ .load_dest = true,
371
+ .opc = INDEX_op_shli_vec,
372
+ .vece = MO_64 },
373
+};
374
+
375
/* Translate a NEON data processing instruction. Return nonzero if the
376
instruction is invalid.
377
We process data in a mixture of 32-bit and 64-bit chunks.
378
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
379
int pairwise;
107
case NEON_2RM_AESE: case NEON_2RM_AESMC:
380
int u;
108
case NEON_2RM_SHA1H:
381
int vec_size;
109
case NEON_2RM_SHA1SU1:
382
- uint32_t imm, mask;
110
+ case NEON_2RM_VREV32:
383
+ uint32_t imm;
111
+ case NEON_2RM_VREV16:
384
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
112
/* handled by decodetree */
385
TCGv_ptr ptr1, ptr2, ptr3;
113
return 1;
386
TCGv_i64 tmp64;
114
case NEON_2RM_VTRN:
387
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
388
}
116
for (pass = 0; pass < (q ? 4 : 2); pass++) {
389
return 0;
117
tmp = neon_load_reg(rm, pass);
390
118
switch (op) {
391
+ case 4: /* VSRI */
119
- case NEON_2RM_VREV32:
392
+ if (!u) {
393
+ return 1;
394
+ }
395
+ /* Right shift comes here negative. */
396
+ shift = -shift;
397
+ /* Shift out of range leaves destination unchanged. */
398
+ if (shift < 8 << size) {
399
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
400
+ shift, &sri_op[size]);
401
+ }
402
+ return 0;
403
+
404
case 5: /* VSHL, VSLI */
405
- if (!u) { /* VSHL */
406
+ if (u) { /* VSLI */
407
+ /* Shift out of range leaves destination unchanged. */
408
+ if (shift < 8 << size) {
409
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
410
+ vec_size, shift, &sli_op[size]);
411
+ }
412
+ } else { /* VSHL */
413
/* Shifts larger than the element size are
414
* architecturally valid and results in zero.
415
*/
416
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
417
tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
418
vec_size, vec_size);
419
}
420
- return 0;
421
}
422
- break;
423
+ return 0;
424
}
425
426
if (size == 3) {
427
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
428
else
429
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
430
break;
431
- case 4: /* VSRI */
432
- case 5: /* VSHL, VSLI */
433
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
434
- break;
435
case 6: /* VQSHLU */
436
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
437
cpu_V0, cpu_V1);
438
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
439
/* Accumulate. */
440
neon_load_reg64(cpu_V1, rd + pass);
441
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
442
- } else if (op == 4 || (op == 5 && u)) {
443
- /* Insert */
444
- neon_load_reg64(cpu_V1, rd + pass);
445
- uint64_t mask;
446
- if (shift < -63 || shift > 63) {
447
- mask = 0;
448
- } else {
449
- if (op == 4) {
450
- mask = 0xffffffffffffffffull >> -shift;
451
- } else {
452
- mask = 0xffffffffffffffffull << shift;
453
- }
454
- }
455
- tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
456
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
457
}
458
neon_store_reg64(cpu_V0, rd + pass);
459
} else { /* size < 3 */
460
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
461
case 3: /* VRSRA */
462
GEN_NEON_INTEGER_OP(rshl);
463
break;
464
- case 4: /* VSRI */
465
- case 5: /* VSHL, VSLI */
466
- switch (size) {
120
- switch (size) {
467
- case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
121
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
468
- case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
122
- case 1: gen_swap_half(tmp, tmp); break;
469
- case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
470
- default: abort();
123
- default: abort();
471
- }
124
- }
472
- break;
125
- break;
473
case 6: /* VQSHLU */
126
- case NEON_2RM_VREV16:
127
- gen_rev16(tmp, tmp);
128
- break;
129
case NEON_2RM_VCLS:
474
switch (size) {
130
switch (size) {
475
case 0:
131
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
476
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
477
tmp2 = neon_load_reg(rd, pass);
478
gen_neon_add(size, tmp, tmp2);
479
tcg_temp_free_i32(tmp2);
480
- } else if (op == 4 || (op == 5 && u)) {
481
- /* Insert */
482
- switch (size) {
483
- case 0:
484
- if (op == 4)
485
- mask = 0xff >> -shift;
486
- else
487
- mask = (uint8_t)(0xff << shift);
488
- mask |= mask << 8;
489
- mask |= mask << 16;
490
- break;
491
- case 1:
492
- if (op == 4)
493
- mask = 0xffff >> -shift;
494
- else
495
- mask = (uint16_t)(0xffff << shift);
496
- mask |= mask << 16;
497
- break;
498
- case 2:
499
- if (shift < -31 || shift > 31) {
500
- mask = 0;
501
- } else {
502
- if (op == 4)
503
- mask = 0xffffffffu >> -shift;
504
- else
505
- mask = 0xffffffffu << shift;
506
- }
507
- break;
508
- default:
509
- abort();
510
- }
511
- tmp2 = neon_load_reg(rd, pass);
512
- tcg_gen_andi_i32(tmp, tmp, mask);
513
- tcg_gen_andi_i32(tmp2, tmp2, ~mask);
514
- tcg_gen_or_i32(tmp, tmp, tmp2);
515
- tcg_temp_free_i32(tmp2);
516
}
517
neon_store_reg(rd, pass, tmp);
518
}
519
--
132
--
520
2.19.1
133
2.20.1
521
134
522
135
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the remaining ops in the Neon 2-reg-misc group which
2
can be implemented simply with our do_2misc() helper.
2
3
3
Most of the v8 extensions are self-contained within the ISAR
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
registers and are not implied by other feature bits, which
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
makes them the easiest to convert.
6
Message-id: 20200616170844.13318-14-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 10 +++++
9
target/arm/translate-neon.inc.c | 69 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 38 ++++--------------
11
3 files changed, 86 insertions(+), 31 deletions(-)
6
12
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181016223115.24100-4-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 131 +++++++++++++++++++++++++++++++++----
14
target/arm/translate.h | 7 ++
15
linux-user/elfload.c | 46 ++++++++-----
16
target/arm/cpu.c | 27 +++++---
17
target/arm/cpu64.c | 57 +++++++++-------
18
target/arm/translate-a64.c | 101 ++++++++++++++--------------
19
target/arm/translate.c | 36 +++++-----
20
7 files changed, 273 insertions(+), 132 deletions(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
25
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
26
@@ -XXX,XX +XXX,XX @@ typedef enum ARMPSCIState {
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
27
PSCI_ON_PENDING = 2
18
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
28
} ARMPSCIState;
19
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
29
20
30
+typedef struct ARMISARegisters ARMISARegisters;
21
+ VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
22
+ VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
23
+ VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
31
+
24
+
32
/**
25
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
33
* ARMCPU:
26
34
* @env: #CPUARMState
27
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
35
@@ -XXX,XX +XXX,XX @@ enum arm_features {
28
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
36
ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
29
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
37
ARM_FEATURE_V8,
30
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
38
ARM_FEATURE_AARCH64, /* supports 64 bit mode */
31
39
- ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
32
+ VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
40
ARM_FEATURE_CBAR, /* has cp15 CBAR */
33
+ VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
41
ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
34
+
42
ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
43
ARM_FEATURE_EL2, /* has EL2 Virtualization support */
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
44
ARM_FEATURE_EL3, /* has EL3 Secure monitor support */
37
45
- ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */
38
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
46
- ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
39
47
- ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
40
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
48
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
41
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
49
ARM_FEATURE_PMU, /* has PMU support */
42
+
50
ARM_FEATURE_VBAR, /* has cp15 VBAR */
43
+ VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
51
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
44
+ VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
52
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
45
]
53
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
46
54
- ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
47
# Subgroup for size != 0b11
55
- ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
48
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
56
- ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
49
index XXXXXXX..XXXXXXX 100644
57
- ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
50
--- a/target/arm/translate-neon.inc.c
58
- ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
51
+++ b/target/arm/translate-neon.inc.c
59
- ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a)
60
- ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
53
}
61
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
54
return do_2misc(s, a, gen_rev16);
62
- ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
55
}
63
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
56
+
64
};
57
+static bool trans_VCLS(DisasContext *s, arg_2misc *a)
65
66
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
67
/* Shared between translate-sve.c and sve_helper.c. */
68
extern const uint64_t pred_esz_masks[4];
69
70
+/*
71
+ * 32-bit feature tests via id registers.
72
+ */
73
+static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
74
+{
58
+{
75
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
59
+ static NeonGenOneOpFn * const fn[] = {
60
+ gen_helper_neon_cls_s8,
61
+ gen_helper_neon_cls_s16,
62
+ gen_helper_neon_cls_s32,
63
+ NULL,
64
+ };
65
+ return do_2misc(s, a, fn[a->size]);
76
+}
66
+}
77
+
67
+
78
+static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
68
+static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm)
79
+{
69
+{
80
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
70
+ tcg_gen_clzi_i32(rd, rm, 32);
81
+}
71
+}
82
+
72
+
83
+static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
73
+static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
84
+{
74
+{
85
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
75
+ static NeonGenOneOpFn * const fn[] = {
76
+ gen_helper_neon_clz_u8,
77
+ gen_helper_neon_clz_u16,
78
+ do_VCLZ_32,
79
+ NULL,
80
+ };
81
+ return do_2misc(s, a, fn[a->size]);
86
+}
82
+}
87
+
83
+
88
+static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
84
+static bool trans_VCNT(DisasContext *s, arg_2misc *a)
89
+{
85
+{
90
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
86
+ if (a->size != 0) {
87
+ return false;
88
+ }
89
+ return do_2misc(s, a, gen_helper_neon_cnt_u8);
91
+}
90
+}
92
+
91
+
93
+static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
92
+static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
94
+{
93
+{
95
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
94
+ if (a->size != 2) {
95
+ return false;
96
+ }
97
+ /* TODO: FP16 : size == 1 */
98
+ return do_2misc(s, a, gen_helper_vfp_abss);
96
+}
99
+}
97
+
100
+
98
+static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
101
+static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
99
+{
102
+{
100
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
103
+ if (a->size != 2) {
104
+ return false;
105
+ }
106
+ /* TODO: FP16 : size == 1 */
107
+ return do_2misc(s, a, gen_helper_vfp_negs);
101
+}
108
+}
102
+
109
+
103
+static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
110
+static bool trans_VRECPE(DisasContext *s, arg_2misc *a)
104
+{
111
+{
105
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
112
+ if (a->size != 2) {
113
+ return false;
114
+ }
115
+ return do_2misc(s, a, gen_helper_recpe_u32);
106
+}
116
+}
107
+
117
+
108
+static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
118
+static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
109
+{
119
+{
110
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
120
+ if (a->size != 2) {
121
+ return false;
122
+ }
123
+ return do_2misc(s, a, gen_helper_rsqrte_u32);
111
+}
124
+}
112
+
113
+/*
114
+ * 64-bit feature tests via id registers.
115
+ */
116
+static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
117
+{
118
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
119
+}
120
+
121
+static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
122
+{
123
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
124
+}
125
+
126
+static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
127
+{
128
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
129
+}
130
+
131
+static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
132
+{
133
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
134
+}
135
+
136
+static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
137
+{
138
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
139
+}
140
+
141
+static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
142
+{
143
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
144
+}
145
+
146
+static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
147
+{
148
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
149
+}
150
+
151
+static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
152
+{
153
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
154
+}
155
+
156
+static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
157
+{
158
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
159
+}
160
+
161
+static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
162
+{
163
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
164
+}
165
+
166
+static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
167
+{
168
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
169
+}
170
+
171
+static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
172
+{
173
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
174
+}
175
+
176
+static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
177
+{
178
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
179
+}
180
+
181
+/*
182
+ * Forward to the above feature tests given an ARMCPU pointer.
183
+ */
184
+#define cpu_isar_feature(name, cpu) \
185
+ ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
186
+
187
#endif
188
diff --git a/target/arm/translate.h b/target/arm/translate.h
189
index XXXXXXX..XXXXXXX 100644
190
--- a/target/arm/translate.h
191
+++ b/target/arm/translate.h
192
@@ -XXX,XX +XXX,XX @@
193
/* internal defines */
194
typedef struct DisasContext {
195
DisasContextBase base;
196
+ const ARMISARegisters *isar;
197
198
target_ulong pc;
199
target_ulong page_start;
200
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
201
return ret;
202
}
203
204
+/*
205
+ * Forward to the isar_feature_* tests given a DisasContext pointer.
206
+ */
207
+#define dc_isar_feature(name, ctx) \
208
+ ({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
209
+
210
#endif /* TARGET_ARM_TRANSLATE_H */
211
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/linux-user/elfload.c
214
+++ b/linux-user/elfload.c
215
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
216
/* probe for the extra features */
217
#define GET_FEATURE(feat, hwcap) \
218
do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
219
+
220
+#define GET_FEATURE_ID(feat, hwcap) \
221
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
222
+
223
/* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
224
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
225
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
226
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
227
ARMCPU *cpu = ARM_CPU(thread_cpu);
228
uint32_t hwcaps = 0;
229
230
- GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES);
231
- GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP2_ARM_PMULL);
232
- GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP2_ARM_SHA1);
233
- GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP2_ARM_SHA2);
234
- GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32);
235
+ GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
236
+ GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
237
+ GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
238
+ GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
239
+ GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
240
return hwcaps;
241
}
242
243
#undef GET_FEATURE
244
+#undef GET_FEATURE_ID
245
246
#else
247
/* 64 bit ARM definitions */
248
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
249
/* probe for the extra features */
250
#define GET_FEATURE(feat, hwcap) \
251
do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
252
- GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_AES);
253
- GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP_A64_PMULL);
254
- GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1);
255
- GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2);
256
- GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32);
257
- GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3);
258
- GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
259
- GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
260
- GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
261
+#define GET_FEATURE_ID(feat, hwcap) \
262
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
263
+
264
+ GET_FEATURE_ID(aa64_aes, ARM_HWCAP_A64_AES);
265
+ GET_FEATURE_ID(aa64_pmull, ARM_HWCAP_A64_PMULL);
266
+ GET_FEATURE_ID(aa64_sha1, ARM_HWCAP_A64_SHA1);
267
+ GET_FEATURE_ID(aa64_sha256, ARM_HWCAP_A64_SHA2);
268
+ GET_FEATURE_ID(aa64_sha512, ARM_HWCAP_A64_SHA512);
269
+ GET_FEATURE_ID(aa64_crc32, ARM_HWCAP_A64_CRC32);
270
+ GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
271
+ GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
272
+ GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
273
GET_FEATURE(ARM_FEATURE_V8_FP16,
274
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
275
- GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
276
- GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
277
- GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
278
- GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
279
+ GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
280
+ GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
281
+ GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
282
+ GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
283
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
284
+
285
#undef GET_FEATURE
286
+#undef GET_FEATURE_ID
287
288
return hwcaps;
289
}
290
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
291
index XXXXXXX..XXXXXXX 100644
292
--- a/target/arm/cpu.c
293
+++ b/target/arm/cpu.c
294
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
295
cortex_a15_initfn(obj);
296
#ifdef CONFIG_USER_ONLY
297
/* We don't set these in system emulation mode for the moment,
298
- * since we don't correctly set the ID registers to advertise them,
299
+ * since we don't correctly set (all of) the ID registers to
300
+ * advertise them.
301
*/
302
set_feature(&cpu->env, ARM_FEATURE_V8);
303
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
304
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
305
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
306
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
307
- set_feature(&cpu->env, ARM_FEATURE_CRC);
308
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
309
- set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
310
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
311
+ {
312
+ uint32_t t;
313
+
314
+ t = cpu->isar.id_isar5;
315
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
316
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
317
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
318
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
319
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
320
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
321
+ cpu->isar.id_isar5 = t;
322
+
323
+ t = cpu->isar.id_isar6;
324
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
325
+ cpu->isar.id_isar6 = t;
326
+ }
327
#endif
328
}
329
}
330
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
331
index XXXXXXX..XXXXXXX 100644
332
--- a/target/arm/cpu64.c
333
+++ b/target/arm/cpu64.c
334
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
335
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
336
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
337
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
338
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
339
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
340
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
341
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
342
- set_feature(&cpu->env, ARM_FEATURE_CRC);
343
set_feature(&cpu->env, ARM_FEATURE_EL2);
344
set_feature(&cpu->env, ARM_FEATURE_EL3);
345
set_feature(&cpu->env, ARM_FEATURE_PMU);
346
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
347
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
348
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
349
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
350
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
351
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
352
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
353
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
354
- set_feature(&cpu->env, ARM_FEATURE_CRC);
355
set_feature(&cpu->env, ARM_FEATURE_EL2);
356
set_feature(&cpu->env, ARM_FEATURE_EL3);
357
set_feature(&cpu->env, ARM_FEATURE_PMU);
358
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
359
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
360
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
361
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
362
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
363
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
364
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
365
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
366
- set_feature(&cpu->env, ARM_FEATURE_CRC);
367
set_feature(&cpu->env, ARM_FEATURE_EL2);
368
set_feature(&cpu->env, ARM_FEATURE_EL3);
369
set_feature(&cpu->env, ARM_FEATURE_PMU);
370
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
371
if (kvm_enabled()) {
372
kvm_arm_set_cpu_features_from_host(cpu);
373
} else {
374
+ uint64_t t;
375
+ uint32_t u;
376
aarch64_a57_initfn(obj);
377
+
378
+ t = cpu->isar.id_aa64isar0;
379
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
380
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
381
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
382
+ t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
383
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
384
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
385
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
386
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
387
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
388
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
389
+ cpu->isar.id_aa64isar0 = t;
390
+
391
+ t = cpu->isar.id_aa64isar1;
392
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
393
+ cpu->isar.id_aa64isar1 = t;
394
+
395
+ /* Replicate the same data to the 32-bit id registers. */
396
+ u = cpu->isar.id_isar5;
397
+ u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
398
+ u = FIELD_DP32(u, ID_ISAR5, SHA1, 1);
399
+ u = FIELD_DP32(u, ID_ISAR5, SHA2, 1);
400
+ u = FIELD_DP32(u, ID_ISAR5, CRC32, 1);
401
+ u = FIELD_DP32(u, ID_ISAR5, RDM, 1);
402
+ u = FIELD_DP32(u, ID_ISAR5, VCMA, 1);
403
+ cpu->isar.id_isar5 = u;
404
+
405
+ u = cpu->isar.id_isar6;
406
+ u = FIELD_DP32(u, ID_ISAR6, DP, 1);
407
+ cpu->isar.id_isar6 = u;
408
+
409
#ifdef CONFIG_USER_ONLY
410
/* We don't set these in system emulation mode for the moment,
411
* since we don't correctly set the ID registers to advertise them,
412
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
413
* whereas the architecture requires them to be present in both if
414
* present in either.
415
*/
416
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
417
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
418
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
419
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
420
- set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
421
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
422
- set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
423
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
424
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
425
set_feature(&cpu->env, ARM_FEATURE_SVE);
426
/* For usermode -cpu max we can use a larger and more efficient DCZ
427
* blocksize since we don't have to follow what the hardware does.
428
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
429
index XXXXXXX..XXXXXXX 100644
430
--- a/target/arm/translate-a64.c
431
+++ b/target/arm/translate-a64.c
432
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
433
}
434
if (rt2 == 31
435
&& ((rt | rs) & 1) == 0
436
- && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
437
+ && dc_isar_feature(aa64_atomics, s)) {
438
/* CASP / CASPL */
439
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
440
return;
441
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
442
}
443
if (rt2 == 31
444
&& ((rt | rs) & 1) == 0
445
- && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
446
+ && dc_isar_feature(aa64_atomics, s)) {
447
/* CASPA / CASPAL */
448
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
449
return;
450
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
451
case 0xb: /* CASL */
452
case 0xe: /* CASA */
453
case 0xf: /* CASAL */
454
- if (rt2 == 31 && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
455
+ if (rt2 == 31 && dc_isar_feature(aa64_atomics, s)) {
456
gen_compare_and_swap(s, rs, rt, rn, size);
457
return;
458
}
459
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
460
int rs = extract32(insn, 16, 5);
461
int rn = extract32(insn, 5, 5);
462
int o3_opc = extract32(insn, 12, 4);
463
- int feature = ARM_FEATURE_V8_ATOMICS;
464
TCGv_i64 tcg_rn, tcg_rs;
465
AtomicThreeOpFn *fn;
466
467
- if (is_vector) {
468
+ if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
469
unallocated_encoding(s);
470
return;
471
}
472
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
473
unallocated_encoding(s);
474
return;
475
}
476
- if (!arm_dc_feature(s, feature)) {
477
- unallocated_encoding(s);
478
- return;
479
- }
480
481
if (rn == 31) {
482
gen_check_sp_alignment(s);
483
@@ -XXX,XX +XXX,XX @@ static void handle_crc32(DisasContext *s,
484
TCGv_i64 tcg_acc, tcg_val;
485
TCGv_i32 tcg_bytes;
486
487
- if (!arm_dc_feature(s, ARM_FEATURE_CRC)
488
+ if (!dc_isar_feature(aa64_crc32, s)
489
|| (sf == 1 && sz != 3)
490
|| (sf == 0 && sz == 3)) {
491
unallocated_encoding(s);
492
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
493
bool u = extract32(insn, 29, 1);
494
TCGv_i32 ele1, ele2, ele3;
495
TCGv_i64 res;
496
- int feature;
497
+ bool feature;
498
499
switch (u * 16 + opcode) {
500
case 0x10: /* SQRDMLAH (vector) */
501
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
502
unallocated_encoding(s);
503
return;
504
}
505
- feature = ARM_FEATURE_V8_RDM;
506
+ feature = dc_isar_feature(aa64_rdm, s);
507
break;
508
default:
509
unallocated_encoding(s);
510
return;
511
}
512
- if (!arm_dc_feature(s, feature)) {
513
+ if (!feature) {
514
unallocated_encoding(s);
515
return;
516
}
517
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
518
return;
519
}
520
if (size == 3) {
521
- if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
522
+ if (!dc_isar_feature(aa64_pmull, s)) {
523
unallocated_encoding(s);
524
return;
525
}
526
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
527
int size = extract32(insn, 22, 2);
528
bool u = extract32(insn, 29, 1);
529
bool is_q = extract32(insn, 30, 1);
530
- int feature, rot;
531
+ bool feature;
532
+ int rot;
533
534
switch (u * 16 + opcode) {
535
case 0x10: /* SQRDMLAH (vector) */
536
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
537
unallocated_encoding(s);
538
return;
539
}
540
- feature = ARM_FEATURE_V8_RDM;
541
+ feature = dc_isar_feature(aa64_rdm, s);
542
break;
543
case 0x02: /* SDOT (vector) */
544
case 0x12: /* UDOT (vector) */
545
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
546
unallocated_encoding(s);
547
return;
548
}
549
- feature = ARM_FEATURE_V8_DOTPROD;
550
+ feature = dc_isar_feature(aa64_dp, s);
551
break;
552
case 0x18: /* FCMLA, #0 */
553
case 0x19: /* FCMLA, #90 */
554
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
555
unallocated_encoding(s);
556
return;
557
}
558
- feature = ARM_FEATURE_V8_FCMA;
559
+ feature = dc_isar_feature(aa64_fcma, s);
560
break;
561
default:
562
unallocated_encoding(s);
563
return;
564
}
565
- if (!arm_dc_feature(s, feature)) {
566
+ if (!feature) {
567
unallocated_encoding(s);
568
return;
569
}
570
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
571
break;
572
case 0x1d: /* SQRDMLAH */
573
case 0x1f: /* SQRDMLSH */
574
- if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
575
+ if (!dc_isar_feature(aa64_rdm, s)) {
576
unallocated_encoding(s);
577
return;
578
}
579
break;
580
case 0x0e: /* SDOT */
581
case 0x1e: /* UDOT */
582
- if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
583
+ if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
584
unallocated_encoding(s);
585
return;
586
}
587
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
588
case 0x13: /* FCMLA #90 */
589
case 0x15: /* FCMLA #180 */
590
case 0x17: /* FCMLA #270 */
591
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
592
+ if (!dc_isar_feature(aa64_fcma, s)) {
593
unallocated_encoding(s);
594
return;
595
}
596
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
597
TCGv_i32 tcg_decrypt;
598
CryptoThreeOpIntFn *genfn;
599
600
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
601
- || size != 0) {
602
+ if (!dc_isar_feature(aa64_aes, s) || size != 0) {
603
unallocated_encoding(s);
604
return;
605
}
606
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
607
int rd = extract32(insn, 0, 5);
608
CryptoThreeOpFn *genfn;
609
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
610
- int feature = ARM_FEATURE_V8_SHA256;
611
+ bool feature;
612
613
if (size != 0) {
614
unallocated_encoding(s);
615
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
616
case 2: /* SHA1M */
617
case 3: /* SHA1SU0 */
618
genfn = NULL;
619
- feature = ARM_FEATURE_V8_SHA1;
620
+ feature = dc_isar_feature(aa64_sha1, s);
621
break;
622
case 4: /* SHA256H */
623
genfn = gen_helper_crypto_sha256h;
624
+ feature = dc_isar_feature(aa64_sha256, s);
625
break;
626
case 5: /* SHA256H2 */
627
genfn = gen_helper_crypto_sha256h2;
628
+ feature = dc_isar_feature(aa64_sha256, s);
629
break;
630
case 6: /* SHA256SU1 */
631
genfn = gen_helper_crypto_sha256su1;
632
+ feature = dc_isar_feature(aa64_sha256, s);
633
break;
634
default:
635
unallocated_encoding(s);
636
return;
637
}
638
639
- if (!arm_dc_feature(s, feature)) {
640
+ if (!feature) {
641
unallocated_encoding(s);
642
return;
643
}
644
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
645
int rn = extract32(insn, 5, 5);
646
int rd = extract32(insn, 0, 5);
647
CryptoTwoOpFn *genfn;
648
- int feature;
649
+ bool feature;
650
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
651
652
if (size != 0) {
653
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
654
655
switch (opcode) {
656
case 0: /* SHA1H */
657
- feature = ARM_FEATURE_V8_SHA1;
658
+ feature = dc_isar_feature(aa64_sha1, s);
659
genfn = gen_helper_crypto_sha1h;
660
break;
661
case 1: /* SHA1SU1 */
662
- feature = ARM_FEATURE_V8_SHA1;
663
+ feature = dc_isar_feature(aa64_sha1, s);
664
genfn = gen_helper_crypto_sha1su1;
665
break;
666
case 2: /* SHA256SU0 */
667
- feature = ARM_FEATURE_V8_SHA256;
668
+ feature = dc_isar_feature(aa64_sha256, s);
669
genfn = gen_helper_crypto_sha256su0;
670
break;
671
default:
672
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
673
return;
674
}
675
676
- if (!arm_dc_feature(s, feature)) {
677
+ if (!feature) {
678
unallocated_encoding(s);
679
return;
680
}
681
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
682
int rm = extract32(insn, 16, 5);
683
int rn = extract32(insn, 5, 5);
684
int rd = extract32(insn, 0, 5);
685
- int feature;
686
+ bool feature;
687
CryptoThreeOpFn *genfn;
688
689
if (o == 0) {
690
switch (opcode) {
691
case 0: /* SHA512H */
692
- feature = ARM_FEATURE_V8_SHA512;
693
+ feature = dc_isar_feature(aa64_sha512, s);
694
genfn = gen_helper_crypto_sha512h;
695
break;
696
case 1: /* SHA512H2 */
697
- feature = ARM_FEATURE_V8_SHA512;
698
+ feature = dc_isar_feature(aa64_sha512, s);
699
genfn = gen_helper_crypto_sha512h2;
700
break;
701
case 2: /* SHA512SU1 */
702
- feature = ARM_FEATURE_V8_SHA512;
703
+ feature = dc_isar_feature(aa64_sha512, s);
704
genfn = gen_helper_crypto_sha512su1;
705
break;
706
case 3: /* RAX1 */
707
- feature = ARM_FEATURE_V8_SHA3;
708
+ feature = dc_isar_feature(aa64_sha3, s);
709
genfn = NULL;
710
break;
711
}
712
} else {
713
switch (opcode) {
714
case 0: /* SM3PARTW1 */
715
- feature = ARM_FEATURE_V8_SM3;
716
+ feature = dc_isar_feature(aa64_sm3, s);
717
genfn = gen_helper_crypto_sm3partw1;
718
break;
719
case 1: /* SM3PARTW2 */
720
- feature = ARM_FEATURE_V8_SM3;
721
+ feature = dc_isar_feature(aa64_sm3, s);
722
genfn = gen_helper_crypto_sm3partw2;
723
break;
724
case 2: /* SM4EKEY */
725
- feature = ARM_FEATURE_V8_SM4;
726
+ feature = dc_isar_feature(aa64_sm4, s);
727
genfn = gen_helper_crypto_sm4ekey;
728
break;
729
default:
730
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
731
}
732
}
733
734
- if (!arm_dc_feature(s, feature)) {
735
+ if (!feature) {
736
unallocated_encoding(s);
737
return;
738
}
739
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
740
int rn = extract32(insn, 5, 5);
741
int rd = extract32(insn, 0, 5);
742
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
743
- int feature;
744
+ bool feature;
745
CryptoTwoOpFn *genfn;
746
747
switch (opcode) {
748
case 0: /* SHA512SU0 */
749
- feature = ARM_FEATURE_V8_SHA512;
750
+ feature = dc_isar_feature(aa64_sha512, s);
751
genfn = gen_helper_crypto_sha512su0;
752
break;
753
case 1: /* SM4E */
754
- feature = ARM_FEATURE_V8_SM4;
755
+ feature = dc_isar_feature(aa64_sm4, s);
756
genfn = gen_helper_crypto_sm4e;
757
break;
758
default:
759
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
760
return;
761
}
762
763
- if (!arm_dc_feature(s, feature)) {
764
+ if (!feature) {
765
unallocated_encoding(s);
766
return;
767
}
768
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
769
int ra = extract32(insn, 10, 5);
770
int rn = extract32(insn, 5, 5);
771
int rd = extract32(insn, 0, 5);
772
- int feature;
773
+ bool feature;
774
775
switch (op0) {
776
case 0: /* EOR3 */
777
case 1: /* BCAX */
778
- feature = ARM_FEATURE_V8_SHA3;
779
+ feature = dc_isar_feature(aa64_sha3, s);
780
break;
781
case 2: /* SM3SS1 */
782
- feature = ARM_FEATURE_V8_SM3;
783
+ feature = dc_isar_feature(aa64_sm3, s);
784
break;
785
default:
786
unallocated_encoding(s);
787
return;
788
}
789
790
- if (!arm_dc_feature(s, feature)) {
791
+ if (!feature) {
792
unallocated_encoding(s);
793
return;
794
}
795
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
796
TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
797
int pass;
798
799
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) {
800
+ if (!dc_isar_feature(aa64_sha3, s)) {
801
unallocated_encoding(s);
802
return;
803
}
804
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
805
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
806
TCGv_i32 tcg_imm2, tcg_opcode;
807
808
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) {
809
+ if (!dc_isar_feature(aa64_sm3, s)) {
810
unallocated_encoding(s);
811
return;
812
}
813
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
814
ARMCPU *arm_cpu = arm_env_get_cpu(env);
815
int bound;
816
817
+ dc->isar = &arm_cpu->isar;
818
dc->pc = dc->base.pc_first;
819
dc->condjmp = 0;
820
821
diff --git a/target/arm/translate.c b/target/arm/translate.c
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
822
index XXXXXXX..XXXXXXX 100644
126
index XXXXXXX..XXXXXXX 100644
823
--- a/target/arm/translate.c
127
--- a/target/arm/translate.c
824
+++ b/target/arm/translate.c
128
+++ b/target/arm/translate.c
825
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_2rm_sizes[] = {
826
static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
827
int q, int rd, int rn, int rm)
828
{
829
- if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
830
+ if (dc_isar_feature(aa32_rdm, s)) {
831
int opr_sz = (1 + q) * 8;
832
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
833
vfp_reg_offset(1, rn),
834
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
835
return 1;
130
case NEON_2RM_SHA1SU1:
836
}
131
case NEON_2RM_VREV32:
837
if (!u) { /* SHA-1 */
132
case NEON_2RM_VREV16:
838
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
133
+ case NEON_2RM_VCLS:
839
+ if (!dc_isar_feature(aa32_sha1, s)) {
134
+ case NEON_2RM_VCLZ:
135
+ case NEON_2RM_VCNT:
136
+ case NEON_2RM_VABS_F:
137
+ case NEON_2RM_VNEG_F:
138
+ case NEON_2RM_VRECPE:
139
+ case NEON_2RM_VRSQRTE:
140
/* handled by decodetree */
840
return 1;
141
return 1;
841
}
142
case NEON_2RM_VTRN:
842
ptr1 = vfp_reg_ptr(true, rd);
843
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
143
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
844
gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
144
for (pass = 0; pass < (q ? 4 : 2); pass++) {
845
tcg_temp_free_i32(tmp4);
145
tmp = neon_load_reg(rm, pass);
846
} else { /* SHA-256 */
146
switch (op) {
847
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
147
- case NEON_2RM_VCLS:
848
+ if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
148
- switch (size) {
849
return 1;
149
- case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
850
}
150
- case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
851
ptr1 = vfp_reg_ptr(true, rd);
151
- case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
152
- default: abort();
153
- }
154
- break;
155
- case NEON_2RM_VCLZ:
156
- switch (size) {
157
- case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
158
- case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
159
- case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
160
- default: abort();
161
- }
162
- break;
163
- case NEON_2RM_VCNT:
164
- gen_helper_neon_cnt_u8(tmp, tmp);
165
- break;
166
case NEON_2RM_VQABS:
167
switch (size) {
168
case 0:
852
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
169
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
853
if (op == 14 && size == 2) {
170
tcg_temp_free_ptr(fpstatus);
854
TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
171
break;
855
172
}
856
- if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
173
- case NEON_2RM_VABS_F:
857
+ if (!dc_isar_feature(aa32_pmull, s)) {
174
- gen_helper_vfp_abss(tmp, tmp);
858
return 1;
175
- break;
859
}
176
- case NEON_2RM_VNEG_F:
860
tcg_rn = tcg_temp_new_i64();
177
- gen_helper_vfp_negs(tmp, tmp);
178
- break;
179
case NEON_2RM_VSWP:
180
tmp2 = neon_load_reg(rd, pass);
181
neon_store_reg(rm, pass, tmp2);
861
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
182
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
862
{
183
tcg_temp_free_ptr(fpst);
863
NeonGenThreeOpEnvFn *fn;
184
break;
864
865
- if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
866
+ if (!dc_isar_feature(aa32_rdm, s)) {
867
return 1;
868
}
185
}
869
if (u && ((rd | rn) & 1)) {
186
- case NEON_2RM_VRECPE:
870
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
187
- gen_helper_recpe_u32(tmp, tmp);
871
break;
188
- break;
872
}
189
- case NEON_2RM_VRSQRTE:
873
case NEON_2RM_AESE: case NEON_2RM_AESMC:
190
- gen_helper_rsqrte_u32(tmp, tmp);
874
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
191
- break;
875
- || ((rm | rd) & 1)) {
192
case NEON_2RM_VRECPE_F:
876
+ if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
193
{
877
return 1;
194
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
878
}
879
ptr1 = vfp_reg_ptr(true, rd);
880
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
881
tcg_temp_free_i32(tmp3);
882
break;
883
case NEON_2RM_SHA1H:
884
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
885
- || ((rm | rd) & 1)) {
886
+ if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
887
return 1;
888
}
889
ptr1 = vfp_reg_ptr(true, rd);
890
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
891
}
892
/* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
893
if (q) {
894
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
895
+ if (!dc_isar_feature(aa32_sha2, s)) {
896
return 1;
897
}
898
- } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
899
+ } else if (!dc_isar_feature(aa32_sha1, s)) {
900
return 1;
901
}
902
ptr1 = vfp_reg_ptr(true, rd);
903
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
904
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
905
int size = extract32(insn, 20, 1);
906
data = extract32(insn, 23, 2); /* rot */
907
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
908
+ if (!dc_isar_feature(aa32_vcma, s)
909
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
910
return 1;
911
}
912
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
913
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
914
int size = extract32(insn, 20, 1);
915
data = extract32(insn, 24, 1); /* rot */
916
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
917
+ if (!dc_isar_feature(aa32_vcma, s)
918
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
919
return 1;
920
}
921
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
922
} else if ((insn & 0xfeb00f00) == 0xfc200d00) {
923
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
924
bool u = extract32(insn, 4, 1);
925
- if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
926
+ if (!dc_isar_feature(aa32_dp, s)) {
927
return 1;
928
}
929
fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
930
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
931
int size = extract32(insn, 23, 1);
932
int index;
933
934
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
935
+ if (!dc_isar_feature(aa32_vcma, s)) {
936
return 1;
937
}
938
if (size == 0) {
939
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
940
} else if ((insn & 0xffb00f00) == 0xfe200d00) {
941
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
942
int u = extract32(insn, 4, 1);
943
- if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
944
+ if (!dc_isar_feature(aa32_dp, s)) {
945
return 1;
946
}
947
fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
948
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
949
* op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
950
* Bits 8, 10 and 11 should be zero.
951
*/
952
- if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
953
- (c & 0xd) != 0) {
954
+ if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
955
goto illegal_op;
956
}
957
958
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
959
case 0x28:
960
case 0x29:
961
case 0x2a:
962
- if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
963
+ if (!dc_isar_feature(aa32_crc32, s)) {
964
goto illegal_op;
965
}
966
break;
967
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
968
CPUARMState *env = cs->env_ptr;
969
ARMCPU *cpu = arm_env_get_cpu(env);
970
971
+ dc->isar = &cpu->isar;
972
dc->pc = dc->base.pc_first;
973
dc->condjmp = 0;
974
975
--
195
--
976
2.19.1
196
2.20.1
977
197
978
198
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon VQABS and VQNEG insns to decodetree.
2
Since these are the only ones which need cpu_env passing to
3
the helper, we wrap the helper rather than creating a whole
4
new do_2misc_env() function.
2
5
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-11-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-15-peter.maydell@linaro.org
7
---
9
---
8
target/arm/translate.c | 16 ++++++++--------
10
target/arm/neon-dp.decode | 3 +++
9
1 file changed, 8 insertions(+), 8 deletions(-)
11
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 30 ++--------------------------
13
3 files changed, 40 insertions(+), 28 deletions(-)
10
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
18
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
21
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
22
23
+ VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
24
+ VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
25
+
26
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
27
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
28
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
29
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-neon.inc.c
32
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
34
}
35
return do_2misc(s, a, gen_helper_rsqrte_u32);
36
}
37
+
38
+#define WRAP_1OP_ENV_FN(WRAPNAME, FUNC) \
39
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m) \
40
+ { \
41
+ FUNC(d, cpu_env, m); \
42
+ }
43
+
44
+WRAP_1OP_ENV_FN(gen_VQABS_s8, gen_helper_neon_qabs_s8)
45
+WRAP_1OP_ENV_FN(gen_VQABS_s16, gen_helper_neon_qabs_s16)
46
+WRAP_1OP_ENV_FN(gen_VQABS_s32, gen_helper_neon_qabs_s32)
47
+WRAP_1OP_ENV_FN(gen_VQNEG_s8, gen_helper_neon_qneg_s8)
48
+WRAP_1OP_ENV_FN(gen_VQNEG_s16, gen_helper_neon_qneg_s16)
49
+WRAP_1OP_ENV_FN(gen_VQNEG_s32, gen_helper_neon_qneg_s32)
50
+
51
+static bool trans_VQABS(DisasContext *s, arg_2misc *a)
52
+{
53
+ static NeonGenOneOpFn * const fn[] = {
54
+ gen_VQABS_s8,
55
+ gen_VQABS_s16,
56
+ gen_VQABS_s32,
57
+ NULL,
58
+ };
59
+ return do_2misc(s, a, fn[a->size]);
60
+}
61
+
62
+static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
63
+{
64
+ static NeonGenOneOpFn * const fn[] = {
65
+ gen_VQNEG_s8,
66
+ gen_VQNEG_s16,
67
+ gen_VQNEG_s32,
68
+ NULL,
69
+ };
70
+ return do_2misc(s, a, fn[a->size]);
71
+}
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
74
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
75
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
16
tcg_temp_free_ptr(ptr1);
77
case NEON_2RM_VNEG_F:
17
tcg_temp_free_ptr(ptr2);
78
case NEON_2RM_VRECPE:
18
break;
79
case NEON_2RM_VRSQRTE:
19
+
80
+ case NEON_2RM_VQABS:
20
+ case NEON_2RM_VMVN:
81
+ case NEON_2RM_VQNEG:
21
+ tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
82
/* handled by decodetree */
22
+ break;
83
return 1;
23
+ case NEON_2RM_VNEG:
84
case NEON_2RM_VTRN:
24
+ tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
85
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
25
+ break;
26
+
27
default:
28
elementwise:
29
for (pass = 0; pass < (q ? 4 : 2); pass++) {
86
for (pass = 0; pass < (q ? 4 : 2); pass++) {
30
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
87
tmp = neon_load_reg(rm, pass);
31
case NEON_2RM_VCNT:
88
switch (op) {
32
gen_helper_neon_cnt_u8(tmp, tmp);
89
- case NEON_2RM_VQABS:
33
break;
90
- switch (size) {
34
- case NEON_2RM_VMVN:
91
- case 0:
35
- tcg_gen_not_i32(tmp, tmp);
92
- gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
93
- break;
94
- case 1:
95
- gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
96
- break;
97
- case 2:
98
- gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
99
- break;
100
- default: abort();
101
- }
36
- break;
102
- break;
37
case NEON_2RM_VQABS:
103
- case NEON_2RM_VQNEG:
38
switch (size) {
104
- switch (size) {
39
case 0:
105
- case 0:
40
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
106
- gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
41
default: abort();
107
- break;
42
}
108
- case 1:
43
break;
109
- gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
44
- case NEON_2RM_VNEG:
110
- break;
45
- tmp2 = tcg_const_i32(0);
111
- case 2:
46
- gen_neon_rsb(size, tmp, tmp2);
112
- gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
47
- tcg_temp_free_i32(tmp2);
113
- break;
114
- default: abort();
115
- }
48
- break;
116
- break;
49
case NEON_2RM_VCGT0_F:
117
case NEON_2RM_VCGT0_F:
50
{
118
{
51
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
119
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
52
--
120
--
53
2.19.1
121
2.20.1
54
122
55
123
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon 2-reg-misc insns which are implemented with
2
2
simple calls to functions that take the input, output and
3
Move ssra_op and usra_op expanders from translate-a64.c.
3
fpstatus pointer.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-14-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-16-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate.h | 2 +
9
target/arm/translate.h | 1 +
11
target/arm/translate-a64.c | 106 ----------------------------
10
target/arm/neon-dp.decode | 8 +++++
12
target/arm/translate.c | 139 ++++++++++++++++++++++++++++++++++---
11
target/arm/translate-neon.inc.c | 62 +++++++++++++++++++++++++++++++++
13
3 files changed, 130 insertions(+), 117 deletions(-)
12
target/arm/translate.c | 56 ++++-------------------------
13
4 files changed, 78 insertions(+), 49 deletions(-)
14
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
18
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
20
extern const GVecGen3 bsl_op;
20
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
21
extern const GVecGen3 bit_op;
21
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
22
extern const GVecGen3 bif_op;
22
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
23
+extern const GVecGen2i ssra_op[4];
23
+typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
24
+extern const GVecGen2i usra_op[4];
24
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
25
25
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
26
/*
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
27
* Forward to the isar_feature_* tests given a DisasContext pointer.
27
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
28
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/neon-dp.decode
30
--- a/target/arm/translate-a64.c
30
+++ b/target/arm/neon-dp.decode
31
+++ b/target/arm/translate-a64.c
31
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
32
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
33
}
33
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
34
35
+ VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
36
+
37
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
38
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
39
40
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
41
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
42
+ VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
43
+ VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
44
+ VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
45
+ VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
46
+ VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
47
+ VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
48
]
49
50
# Subgroup for size != 0b11
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
54
+++ b/target/arm/translate-neon.inc.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
56
};
57
return do_2misc(s, a, fn[a->size]);
34
}
58
}
35
59
+
36
-static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
60
+static bool do_2misc_fp(DisasContext *s, arg_2misc *a,
37
-{
61
+ NeonGenOneSingleOpFn *fn)
38
- tcg_gen_vec_sar8i_i64(a, a, shift);
62
+{
39
- tcg_gen_vec_add8_i64(d, d, a);
63
+ int pass;
40
-}
64
+ TCGv_ptr fpst;
41
-
65
+
42
-static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
66
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
43
-{
67
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
44
- tcg_gen_vec_sar16i_i64(a, a, shift);
68
+ return false;
45
- tcg_gen_vec_add16_i64(d, d, a);
69
+ }
46
-}
70
+
47
-
71
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
-static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
72
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
-{
73
+ ((a->vd | a->vm) & 0x10)) {
50
- tcg_gen_sari_i32(a, a, shift);
74
+ return false;
51
- tcg_gen_add_i32(d, d, a);
75
+ }
52
-}
76
+
53
-
77
+ if (a->size != 2) {
54
-static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
78
+ /* TODO: FP16 will be the size == 1 case */
55
-{
79
+ return false;
56
- tcg_gen_sari_i64(a, a, shift);
80
+ }
57
- tcg_gen_add_i64(d, d, a);
81
+
58
-}
82
+ if ((a->vd | a->vm) & a->q) {
59
-
83
+ return false;
60
-static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
84
+ }
61
-{
85
+
62
- tcg_gen_sari_vec(vece, a, a, sh);
86
+ if (!vfp_access_check(s)) {
63
- tcg_gen_add_vec(vece, d, d, a);
87
+ return true;
64
-}
88
+ }
65
-
89
+
66
-static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
90
+ fpst = get_fpstatus_ptr(1);
67
-{
91
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
68
- tcg_gen_vec_shr8i_i64(a, a, shift);
92
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
69
- tcg_gen_vec_add8_i64(d, d, a);
93
+ fn(tmp, tmp, fpst);
70
-}
94
+ neon_store_reg(a->vd, pass, tmp);
71
-
95
+ }
72
-static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
96
+ tcg_temp_free_ptr(fpst);
73
-{
97
+
74
- tcg_gen_vec_shr16i_i64(a, a, shift);
98
+ return true;
75
- tcg_gen_vec_add16_i64(d, d, a);
99
+}
76
-}
100
+
77
-
101
+#define DO_2MISC_FP(INSN, FUNC) \
78
-static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
102
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
79
-{
103
+ { \
80
- tcg_gen_shri_i32(a, a, shift);
104
+ return do_2misc_fp(s, a, FUNC); \
81
- tcg_gen_add_i32(d, d, a);
105
+ }
82
-}
106
+
83
-
107
+DO_2MISC_FP(VRECPE_F, gen_helper_recpe_f32)
84
-static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
108
+DO_2MISC_FP(VRSQRTE_F, gen_helper_rsqrte_f32)
85
-{
109
+DO_2MISC_FP(VCVT_FS, gen_helper_vfp_sitos)
86
- tcg_gen_shri_i64(a, a, shift);
110
+DO_2MISC_FP(VCVT_FU, gen_helper_vfp_uitos)
87
- tcg_gen_add_i64(d, d, a);
111
+DO_2MISC_FP(VCVT_SF, gen_helper_vfp_tosizs)
88
-}
112
+DO_2MISC_FP(VCVT_UF, gen_helper_vfp_touizs)
89
-
113
+
90
-static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
114
+static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
91
-{
115
+{
92
- tcg_gen_shri_vec(vece, a, a, sh);
116
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
93
- tcg_gen_add_vec(vece, d, d, a);
117
+ return false;
94
-}
118
+ }
95
-
119
+ return do_2misc_fp(s, a, gen_helper_rints_exact);
96
static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
120
+}
97
{
98
uint64_t mask = dup_const(MO_8, 0xff >> shift);
99
@@ -XXX,XX +XXX,XX @@ static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
100
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
101
int immh, int immb, int opcode, int rn, int rd)
102
{
103
- static const GVecGen2i ssra_op[4] = {
104
- { .fni8 = gen_ssra8_i64,
105
- .fniv = gen_ssra_vec,
106
- .load_dest = true,
107
- .opc = INDEX_op_sari_vec,
108
- .vece = MO_8 },
109
- { .fni8 = gen_ssra16_i64,
110
- .fniv = gen_ssra_vec,
111
- .load_dest = true,
112
- .opc = INDEX_op_sari_vec,
113
- .vece = MO_16 },
114
- { .fni4 = gen_ssra32_i32,
115
- .fniv = gen_ssra_vec,
116
- .load_dest = true,
117
- .opc = INDEX_op_sari_vec,
118
- .vece = MO_32 },
119
- { .fni8 = gen_ssra64_i64,
120
- .fniv = gen_ssra_vec,
121
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
122
- .load_dest = true,
123
- .opc = INDEX_op_sari_vec,
124
- .vece = MO_64 },
125
- };
126
- static const GVecGen2i usra_op[4] = {
127
- { .fni8 = gen_usra8_i64,
128
- .fniv = gen_usra_vec,
129
- .load_dest = true,
130
- .opc = INDEX_op_shri_vec,
131
- .vece = MO_8, },
132
- { .fni8 = gen_usra16_i64,
133
- .fniv = gen_usra_vec,
134
- .load_dest = true,
135
- .opc = INDEX_op_shri_vec,
136
- .vece = MO_16, },
137
- { .fni4 = gen_usra32_i32,
138
- .fniv = gen_usra_vec,
139
- .load_dest = true,
140
- .opc = INDEX_op_shri_vec,
141
- .vece = MO_32, },
142
- { .fni8 = gen_usra64_i64,
143
- .fniv = gen_usra_vec,
144
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
145
- .load_dest = true,
146
- .opc = INDEX_op_shri_vec,
147
- .vece = MO_64, },
148
- };
149
static const GVecGen2i sri_op[4] = {
150
{ .fni8 = gen_shr8_ins_i64,
151
.fniv = gen_shr_ins_vec,
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
121
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
122
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
123
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
124
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ const GVecGen3 bif_op = {
157
.load_dest = true
158
};
159
160
+static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
161
+{
162
+ tcg_gen_vec_sar8i_i64(a, a, shift);
163
+ tcg_gen_vec_add8_i64(d, d, a);
164
+}
165
+
166
+static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
167
+{
168
+ tcg_gen_vec_sar16i_i64(a, a, shift);
169
+ tcg_gen_vec_add16_i64(d, d, a);
170
+}
171
+
172
+static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
173
+{
174
+ tcg_gen_sari_i32(a, a, shift);
175
+ tcg_gen_add_i32(d, d, a);
176
+}
177
+
178
+static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
179
+{
180
+ tcg_gen_sari_i64(a, a, shift);
181
+ tcg_gen_add_i64(d, d, a);
182
+}
183
+
184
+static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
185
+{
186
+ tcg_gen_sari_vec(vece, a, a, sh);
187
+ tcg_gen_add_vec(vece, d, d, a);
188
+}
189
+
190
+const GVecGen2i ssra_op[4] = {
191
+ { .fni8 = gen_ssra8_i64,
192
+ .fniv = gen_ssra_vec,
193
+ .load_dest = true,
194
+ .opc = INDEX_op_sari_vec,
195
+ .vece = MO_8 },
196
+ { .fni8 = gen_ssra16_i64,
197
+ .fniv = gen_ssra_vec,
198
+ .load_dest = true,
199
+ .opc = INDEX_op_sari_vec,
200
+ .vece = MO_16 },
201
+ { .fni4 = gen_ssra32_i32,
202
+ .fniv = gen_ssra_vec,
203
+ .load_dest = true,
204
+ .opc = INDEX_op_sari_vec,
205
+ .vece = MO_32 },
206
+ { .fni8 = gen_ssra64_i64,
207
+ .fniv = gen_ssra_vec,
208
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
209
+ .load_dest = true,
210
+ .opc = INDEX_op_sari_vec,
211
+ .vece = MO_64 },
212
+};
213
+
214
+static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
215
+{
216
+ tcg_gen_vec_shr8i_i64(a, a, shift);
217
+ tcg_gen_vec_add8_i64(d, d, a);
218
+}
219
+
220
+static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
221
+{
222
+ tcg_gen_vec_shr16i_i64(a, a, shift);
223
+ tcg_gen_vec_add16_i64(d, d, a);
224
+}
225
+
226
+static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
227
+{
228
+ tcg_gen_shri_i32(a, a, shift);
229
+ tcg_gen_add_i32(d, d, a);
230
+}
231
+
232
+static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
233
+{
234
+ tcg_gen_shri_i64(a, a, shift);
235
+ tcg_gen_add_i64(d, d, a);
236
+}
237
+
238
+static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
239
+{
240
+ tcg_gen_shri_vec(vece, a, a, sh);
241
+ tcg_gen_add_vec(vece, d, d, a);
242
+}
243
+
244
+const GVecGen2i usra_op[4] = {
245
+ { .fni8 = gen_usra8_i64,
246
+ .fniv = gen_usra_vec,
247
+ .load_dest = true,
248
+ .opc = INDEX_op_shri_vec,
249
+ .vece = MO_8, },
250
+ { .fni8 = gen_usra16_i64,
251
+ .fniv = gen_usra_vec,
252
+ .load_dest = true,
253
+ .opc = INDEX_op_shri_vec,
254
+ .vece = MO_16, },
255
+ { .fni4 = gen_usra32_i32,
256
+ .fniv = gen_usra_vec,
257
+ .load_dest = true,
258
+ .opc = INDEX_op_shri_vec,
259
+ .vece = MO_32, },
260
+ { .fni8 = gen_usra64_i64,
261
+ .fniv = gen_usra_vec,
262
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
263
+ .load_dest = true,
264
+ .opc = INDEX_op_shri_vec,
265
+ .vece = MO_64, },
266
+};
267
268
/* Translate a NEON data processing instruction. Return nonzero if the
269
instruction is invalid.
270
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
271
}
126
case NEON_2RM_VRSQRTE:
272
return 0;
127
case NEON_2RM_VQABS:
273
128
case NEON_2RM_VQNEG:
274
+ case 1: /* VSRA */
129
+ case NEON_2RM_VRECPE_F:
275
+ /* Right shift comes here negative. */
130
+ case NEON_2RM_VRSQRTE_F:
276
+ shift = -shift;
131
+ case NEON_2RM_VCVT_FS:
277
+ /* Shifts larger than the element size are architecturally
132
+ case NEON_2RM_VCVT_FU:
278
+ * valid. Unsigned results in all zeros; signed results
133
+ case NEON_2RM_VCVT_SF:
279
+ * in all sign bits.
134
+ case NEON_2RM_VCVT_UF:
280
+ */
135
+ case NEON_2RM_VRINTX:
281
+ if (!u) {
136
/* handled by decodetree */
282
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
137
return 1;
283
+ MIN(shift, (8 << size) - 1),
138
case NEON_2RM_VTRN:
284
+ &ssra_op[size]);
285
+ } else if (shift >= 8 << size) {
286
+ /* rd += 0 */
287
+ } else {
288
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
289
+ shift, &usra_op[size]);
290
+ }
291
+ return 0;
292
+
293
case 5: /* VSHL, VSLI */
294
if (!u) { /* VSHL */
295
/* Shifts larger than the element size are
296
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
297
neon_load_reg64(cpu_V0, rm + pass);
140
tcg_temp_free_i32(tcg_rmode);
298
tcg_gen_movi_i64(cpu_V1, imm);
141
break;
299
switch (op) {
142
}
300
- case 1: /* VSRA */
143
- case NEON_2RM_VRINTX:
301
- if (u)
144
- {
302
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
145
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
303
- else
146
- gen_helper_rints_exact(tmp, tmp, fpstatus);
304
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
147
- tcg_temp_free_ptr(fpstatus);
305
- break;
148
- break;
306
case 2: /* VRSHR */
149
- }
307
case 3: /* VRSRA */
150
case NEON_2RM_VCVTAU:
308
if (u)
151
case NEON_2RM_VCVTAS:
152
case NEON_2RM_VCVTNU:
309
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
154
tcg_temp_free_ptr(fpst);
155
break;
156
}
157
- case NEON_2RM_VRECPE_F:
158
- {
159
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
160
- gen_helper_recpe_f32(tmp, tmp, fpstatus);
161
- tcg_temp_free_ptr(fpstatus);
162
- break;
163
- }
164
- case NEON_2RM_VRSQRTE_F:
165
- {
166
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
167
- gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
168
- tcg_temp_free_ptr(fpstatus);
169
- break;
170
- }
171
- case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
172
- {
173
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
174
- gen_helper_vfp_sitos(tmp, tmp, fpstatus);
175
- tcg_temp_free_ptr(fpstatus);
176
- break;
177
- }
178
- case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
179
- {
180
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
181
- gen_helper_vfp_uitos(tmp, tmp, fpstatus);
182
- tcg_temp_free_ptr(fpstatus);
183
- break;
184
- }
185
- case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
186
- {
187
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
188
- gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
189
- tcg_temp_free_ptr(fpstatus);
190
- break;
191
- }
192
- case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
193
- {
194
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
- gen_helper_vfp_touizs(tmp, tmp, fpstatus);
196
- tcg_temp_free_ptr(fpstatus);
197
- break;
198
- }
310
default:
199
default:
311
g_assert_not_reached();
200
/* Reserved op values were caught by the
312
}
201
* neon_2rm_sizes[] check earlier.
313
- if (op == 1 || op == 3) {
314
+ if (op == 3) {
315
/* Accumulate. */
316
neon_load_reg64(cpu_V1, rd + pass);
317
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
318
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
319
tmp2 = tcg_temp_new_i32();
320
tcg_gen_movi_i32(tmp2, imm);
321
switch (op) {
322
- case 1: /* VSRA */
323
- GEN_NEON_INTEGER_OP(shl);
324
- break;
325
case 2: /* VRSHR */
326
case 3: /* VRSRA */
327
GEN_NEON_INTEGER_OP(rshl);
328
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
329
}
330
tcg_temp_free_i32(tmp2);
331
332
- if (op == 1 || op == 3) {
333
+ if (op == 3) {
334
/* Accumulate. */
335
tmp2 = neon_load_reg(rd, pass);
336
gen_neon_add(size, tmp, tmp2);
337
--
202
--
338
2.19.1
203
2.20.1
339
204
340
205
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the fp-compare-with-zero insns in the Neon 2-reg-misc group to
2
decodetree.
2
3
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-13-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-17-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate.c | 70 +++++++++++++++++++++++++++++-------------
8
target/arm/neon-dp.decode | 6 ++++
9
1 file changed, 48 insertions(+), 22 deletions(-)
9
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++
10
target/arm/translate.c | 50 ++++-----------------------------
11
3 files changed, 39 insertions(+), 45 deletions(-)
10
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
19
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
20
21
+ VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
22
+ VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
23
+ VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
24
+ VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
25
+ VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
26
+
27
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
28
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
35
}
36
return do_2misc_fp(s, a, gen_helper_rints_exact);
37
}
38
+
39
+#define WRAP_FP_CMP0_FWD(WRAPNAME, FUNC) \
40
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
41
+ { \
42
+ TCGv_i32 zero = tcg_const_i32(0); \
43
+ FUNC(d, m, zero, fpst); \
44
+ tcg_temp_free_i32(zero); \
45
+ }
46
+#define WRAP_FP_CMP0_REV(WRAPNAME, FUNC) \
47
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
48
+ { \
49
+ TCGv_i32 zero = tcg_const_i32(0); \
50
+ FUNC(d, zero, m, fpst); \
51
+ tcg_temp_free_i32(zero); \
52
+ }
53
+
54
+#define DO_FP_CMP0(INSN, FUNC, REV) \
55
+ WRAP_FP_CMP0_##REV(gen_##INSN, FUNC) \
56
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
57
+ { \
58
+ return do_2misc_fp(s, a, gen_##INSN); \
59
+ }
60
+
61
+DO_FP_CMP0(VCGT0_F, gen_helper_neon_cgt_f32, FWD)
62
+DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
63
+DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
64
+DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
65
+DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
68
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
69
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
16
size--;
71
case NEON_2RM_VCVT_SF:
17
}
72
case NEON_2RM_VCVT_UF:
18
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
73
case NEON_2RM_VRINTX:
19
- /* To avoid excessive duplication of ops we implement shift
74
+ case NEON_2RM_VCGT0_F:
20
- by immediate using the variable shift operations. */
75
+ case NEON_2RM_VCGE0_F:
21
if (op < 8) {
76
+ case NEON_2RM_VCEQ0_F:
22
/* Shift by immediate:
77
+ case NEON_2RM_VCLE0_F:
23
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
78
+ case NEON_2RM_VCLT0_F:
79
/* handled by decodetree */
80
return 1;
81
case NEON_2RM_VTRN:
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
82
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
25
}
83
for (pass = 0; pass < (q ? 4 : 2); pass++) {
26
/* Right shifts are encoded as N - shift, where N is the
84
tmp = neon_load_reg(rm, pass);
27
element size in bits. */
28
- if (op <= 4)
29
+ if (op <= 4) {
30
shift = shift - (1 << (size + 3));
31
+ }
32
+
33
+ switch (op) {
34
+ case 0: /* VSHR */
35
+ /* Right shift comes here negative. */
36
+ shift = -shift;
37
+ /* Shifts larger than the element size are architecturally
38
+ * valid. Unsigned results in all zeros; signed results
39
+ * in all sign bits.
40
+ */
41
+ if (!u) {
42
+ tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
43
+ MIN(shift, (8 << size) - 1),
44
+ vec_size, vec_size);
45
+ } else if (shift >= 8 << size) {
46
+ tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
47
+ } else {
48
+ tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
49
+ vec_size, vec_size);
50
+ }
51
+ return 0;
52
+
53
+ case 5: /* VSHL, VSLI */
54
+ if (!u) { /* VSHL */
55
+ /* Shifts larger than the element size are
56
+ * architecturally valid and results in zero.
57
+ */
58
+ if (shift >= 8 << size) {
59
+ tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
60
+ } else {
61
+ tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
62
+ vec_size, vec_size);
63
+ }
64
+ return 0;
65
+ }
66
+ break;
67
+ }
68
+
69
if (size == 3) {
70
count = q + 1;
71
} else {
72
count = q ? 4: 2;
73
}
74
- switch (size) {
75
- case 0:
76
- imm = (uint8_t) shift;
77
- imm |= imm << 8;
78
- imm |= imm << 16;
79
- break;
80
- case 1:
81
- imm = (uint16_t) shift;
82
- imm |= imm << 16;
83
- break;
84
- case 2:
85
- case 3:
86
- imm = shift;
87
- break;
88
- default:
89
- abort();
90
- }
91
+
92
+ /* To avoid excessive duplication of ops we implement shift
93
+ * by immediate using the variable shift operations.
94
+ */
95
+ imm = dup_const(size, shift);
96
97
for (pass = 0; pass < count; pass++) {
98
if (size == 3) {
99
neon_load_reg64(cpu_V0, rm + pass);
100
tcg_gen_movi_i64(cpu_V1, imm);
101
switch (op) {
85
switch (op) {
102
- case 0: /* VSHR */
86
- case NEON_2RM_VCGT0_F:
103
case 1: /* VSRA */
87
- {
104
if (u)
88
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
105
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
89
- tmp2 = tcg_const_i32(0);
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
107
cpu_V0, cpu_V1);
91
- tcg_temp_free_i32(tmp2);
108
}
92
- tcg_temp_free_ptr(fpstatus);
109
break;
93
- break;
110
+ default:
94
- }
111
+ g_assert_not_reached();
95
- case NEON_2RM_VCGE0_F:
112
}
96
- {
113
if (op == 1 || op == 3) {
97
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
114
/* Accumulate. */
98
- tmp2 = tcg_const_i32(0);
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
99
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
116
tmp2 = tcg_temp_new_i32();
100
- tcg_temp_free_i32(tmp2);
117
tcg_gen_movi_i32(tmp2, imm);
101
- tcg_temp_free_ptr(fpstatus);
118
switch (op) {
102
- break;
119
- case 0: /* VSHR */
103
- }
120
case 1: /* VSRA */
104
- case NEON_2RM_VCEQ0_F:
121
GEN_NEON_INTEGER_OP(shl);
105
- {
122
break;
106
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
123
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
107
- tmp2 = tcg_const_i32(0);
124
case 7: /* VQSHL */
108
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
125
GEN_NEON_INTEGER_OP_ENV(qshl);
109
- tcg_temp_free_i32(tmp2);
126
break;
110
- tcg_temp_free_ptr(fpstatus);
127
+ default:
111
- break;
128
+ g_assert_not_reached();
112
- }
129
}
113
- case NEON_2RM_VCLE0_F:
130
tcg_temp_free_i32(tmp2);
114
- {
131
115
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
116
- tmp2 = tcg_const_i32(0);
117
- gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
118
- tcg_temp_free_i32(tmp2);
119
- tcg_temp_free_ptr(fpstatus);
120
- break;
121
- }
122
- case NEON_2RM_VCLT0_F:
123
- {
124
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
125
- tmp2 = tcg_const_i32(0);
126
- gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
127
- tcg_temp_free_i32(tmp2);
128
- tcg_temp_free_ptr(fpstatus);
129
- break;
130
- }
131
case NEON_2RM_VSWP:
132
tmp2 = neon_load_reg(rd, pass);
133
neon_store_reg(rm, pass, tmp2);
132
--
134
--
133
2.19.1
135
2.20.1
134
136
135
137
diff view generated by jsdifflib
1
The HCR_EL2 VI and VF bits are supposed to track whether there is
1
Convert the Neon 2-reg-misc VRINT insns to decodetree.
2
a pending virtual IRQ or virtual FIQ. For QEMU we store the
2
Giving these insns their own do_vrint() function allows us
3
pending VIRQ/VFIQ status in cs->interrupt_request, so this means:
3
to change the rounding mode just once at the start and end
4
* if the register is read we must get these bit values from
4
rather than doing it for every element in the vector.
5
cs->interrupt_request
6
* if the register is written then we must write the bit
7
values back into cs->interrupt_request
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181012144235.19646-7-peter.maydell@linaro.org
8
Message-id: 20200616170844.13318-18-peter.maydell@linaro.org
12
---
9
---
13
target/arm/helper.c | 47 +++++++++++++++++++++++++++++++++++++++++----
10
target/arm/neon-dp.decode | 8 +++++
14
1 file changed, 43 insertions(+), 4 deletions(-)
11
target/arm/translate-neon.inc.c | 61 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 31 +++--------------
13
3 files changed, 74 insertions(+), 26 deletions(-)
15
14
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
17
--- a/target/arm/neon-dp.decode
19
+++ b/target/arm/helper.c
18
+++ b/target/arm/neon-dp.decode
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
20
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
22
{
21
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
23
ARMCPU *cpu = arm_env_get_cpu(env);
22
24
+ CPUState *cs = ENV_GET_CPU(env);
23
+ VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
25
uint64_t valid_mask = HCR_MASK;
24
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
26
25
+ VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
27
if (arm_feature(env, ARM_FEATURE_EL3)) {
26
+ VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
28
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
27
29
/* Clear RES0 bits. */
28
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
30
value &= valid_mask;
29
+
31
30
+ VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
31
+
32
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
33
34
+ VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
35
+
36
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
37
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
38
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-neon.inc.c
42
+++ b/target/arm/translate-neon.inc.c
43
@@ -XXX,XX +XXX,XX @@ DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
44
DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
45
DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
46
DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
47
+
48
+static bool do_vrint(DisasContext *s, arg_2misc *a, int rmode)
49
+{
32
+ /*
50
+ /*
33
+ * VI and VF are kept in cs->interrupt_request. Modifying that
51
+ * Handle a VRINT* operation by iterating 32 bits at a time,
34
+ * requires that we have the iothread lock, which is done by
52
+ * with a specified rounding mode in operation.
35
+ * marking the reginfo structs as ARM_CP_IO.
36
+ * Note that if a write to HCR pends a VIRQ or VFIQ it is never
37
+ * possible for it to be taken immediately, because VIRQ and
38
+ * VFIQ are masked unless running at EL0 or EL1, and HCR
39
+ * can only be written at EL2.
40
+ */
53
+ */
41
+ g_assert(qemu_mutex_iothread_locked());
54
+ int pass;
42
+ if (value & HCR_VI) {
55
+ TCGv_ptr fpst;
43
+ cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
56
+ TCGv_i32 tcg_rmode;
44
+ } else {
57
+
45
+ cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
58
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
59
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
60
+ return false;
46
+ }
61
+ }
47
+ if (value & HCR_VF) {
62
+
48
+ cs->interrupt_request |= CPU_INTERRUPT_VFIQ;
63
+ /* UNDEF accesses to D16-D31 if they don't exist. */
49
+ } else {
64
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
50
+ cs->interrupt_request &= ~CPU_INTERRUPT_VFIQ;
65
+ ((a->vd | a->vm) & 0x10)) {
66
+ return false;
51
+ }
67
+ }
52
+ value &= ~(HCR_VI | HCR_VF);
53
+
68
+
54
/* These bits change the MMU setup:
69
+ if (a->size != 2) {
55
* HCR_VM enables stage 2 translation
70
+ /* TODO: FP16 will be the size == 1 case */
56
* HCR_PTW forbids certain page-table setups
71
+ return false;
57
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
72
+ }
58
hcr_write(env, NULL, value);
59
}
60
61
+static uint64_t hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
62
+{
63
+ /* The VI and VF bits live in cs->interrupt_request */
64
+ uint64_t ret = env->cp15.hcr_el2 & ~(HCR_VI | HCR_VF);
65
+ CPUState *cs = ENV_GET_CPU(env);
66
+
73
+
67
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
74
+ if ((a->vd | a->vm) & a->q) {
68
+ ret |= HCR_VI;
75
+ return false;
69
+ }
76
+ }
70
+ if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
77
+
71
+ ret |= HCR_VF;
78
+ if (!vfp_access_check(s)) {
79
+ return true;
72
+ }
80
+ }
73
+ return ret;
81
+
82
+ fpst = get_fpstatus_ptr(1);
83
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
84
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
85
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
86
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
87
+ gen_helper_rints(tmp, tmp, fpst);
88
+ neon_store_reg(a->vd, pass, tmp);
89
+ }
90
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ tcg_temp_free_i32(tcg_rmode);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
74
+}
95
+}
75
+
96
+
76
static const ARMCPRegInfo el2_cp_reginfo[] = {
97
+#define DO_VRINT(INSN, RMODE) \
77
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
78
+ .type = ARM_CP_IO,
99
+ { \
79
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
100
+ return do_vrint(s, a, RMODE); \
80
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
101
+ }
81
- .writefn = hcr_write },
102
+
82
+ .writefn = hcr_write, .readfn = hcr_read },
103
+DO_VRINT(VRINTN, FPROUNDING_TIEEVEN)
83
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
104
+DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
84
- .type = ARM_CP_ALIAS,
105
+DO_VRINT(VRINTZ, FPROUNDING_ZERO)
85
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
106
+DO_VRINT(VRINTM, FPROUNDING_NEGINF)
86
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
107
+DO_VRINT(VRINTP, FPROUNDING_POSINF)
87
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
108
diff --git a/target/arm/translate.c b/target/arm/translate.c
88
- .writefn = hcr_writelow },
109
index XXXXXXX..XXXXXXX 100644
89
+ .writefn = hcr_writelow, .readfn = hcr_read },
110
--- a/target/arm/translate.c
90
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
111
+++ b/target/arm/translate.c
91
.type = ARM_CP_ALIAS,
112
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
92
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
113
case NEON_2RM_VCEQ0_F:
93
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
114
case NEON_2RM_VCLE0_F:
94
115
case NEON_2RM_VCLT0_F:
95
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
116
+ case NEON_2RM_VRINTN:
96
{ .name = "HCR2", .state = ARM_CP_STATE_AA32,
117
+ case NEON_2RM_VRINTA:
97
- .type = ARM_CP_ALIAS,
118
+ case NEON_2RM_VRINTM:
98
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
119
+ case NEON_2RM_VRINTP:
99
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
120
+ case NEON_2RM_VRINTZ:
100
.access = PL2_RW,
121
/* handled by decodetree */
101
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
}
126
neon_store_reg(rm, pass, tmp2);
127
break;
128
- case NEON_2RM_VRINTN:
129
- case NEON_2RM_VRINTA:
130
- case NEON_2RM_VRINTM:
131
- case NEON_2RM_VRINTP:
132
- case NEON_2RM_VRINTZ:
133
- {
134
- TCGv_i32 tcg_rmode;
135
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
136
- int rmode;
137
-
138
- if (op == NEON_2RM_VRINTZ) {
139
- rmode = FPROUNDING_ZERO;
140
- } else {
141
- rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
142
- }
143
-
144
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
146
- cpu_env);
147
- gen_helper_rints(tmp, tmp, fpstatus);
148
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
149
- cpu_env);
150
- tcg_temp_free_ptr(fpstatus);
151
- tcg_temp_free_i32(tcg_rmode);
152
- break;
153
- }
154
case NEON_2RM_VCVTAU:
155
case NEON_2RM_VCVTAS:
156
case NEON_2RM_VCVTNU:
102
--
157
--
103
2.19.1
158
2.20.1
104
159
105
160
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the VCVT instructions in the 2-reg-misc grouping to
2
2
decodetree.
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20181016223115.24100-9-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-19-peter.maydell@linaro.org
8
---
7
---
9
target/arm/cpu.h | 17 +++++++++++++++-
8
target/arm/neon-dp.decode | 9 +++++
10
linux-user/elfload.c | 6 +-----
9
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
11
target/arm/cpu64.c | 16 ++++++++-------
10
target/arm/translate.c | 70 ++++-----------------------------
12
target/arm/helper.c | 2 +-
11
3 files changed, 87 insertions(+), 62 deletions(-)
13
target/arm/translate-a64.c | 40 +++++++++++++++++++-------------------
12
14
target/arm/translate.c | 6 +++---
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
6 files changed, 50 insertions(+), 37 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
ARM_FEATURE_PMU, /* has PMU support */
18
23
ARM_FEATURE_VBAR, /* has cp15 VBAR */
19
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
24
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
20
25
- ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
21
+ VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
26
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
22
+ VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
27
};
23
+ VCVTNS 1111 001 11 . 11 .. 11 .... 0 0010 . . 0 .... @2misc
28
24
+ VCVTNU 1111 001 11 . 11 .. 11 .... 0 0011 . . 0 .... @2misc
29
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
25
+ VCVTPS 1111 001 11 . 11 .. 11 .... 0 0100 . . 0 .... @2misc
30
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
26
+ VCVTPU 1111 001 11 . 11 .. 11 .... 0 0101 . . 0 .... @2misc
31
}
27
+ VCVTMS 1111 001 11 . 11 .. 11 .... 0 0110 . . 0 .... @2misc
32
28
+ VCVTMU 1111 001 11 . 11 .. 11 .... 0 0111 . . 0 .... @2misc
33
+static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
29
+
30
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
31
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
32
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
38
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
39
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
40
DO_VRINT(VRINTP, FPROUNDING_POSINF)
41
+
42
+static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed)
34
+{
43
+{
35
+ /*
44
+ /*
36
+ * This is a placeholder for use by VCMA until the rest of
45
+ * Handle a VCVT* operation by iterating 32 bits at a time,
37
+ * the ARMv8.2-FP16 extension is implemented for aa32 mode.
46
+ * with a specified rounding mode in operation.
38
+ * At which point we can properly set and check MVFR1.FPHP.
39
+ */
47
+ */
40
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
48
+ int pass;
49
+ TCGv_ptr fpst;
50
+ TCGv_i32 tcg_rmode, tcg_shift;
51
+
52
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
53
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
54
+ return false;
55
+ }
56
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size != 2) {
64
+ /* TODO: FP16 will be the size == 1 case */
65
+ return false;
66
+ }
67
+
68
+ if ((a->vd | a->vm) & a->q) {
69
+ return false;
70
+ }
71
+
72
+ if (!vfp_access_check(s)) {
73
+ return true;
74
+ }
75
+
76
+ fpst = get_fpstatus_ptr(1);
77
+ tcg_shift = tcg_const_i32(0);
78
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
79
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
80
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
81
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
82
+ if (is_signed) {
83
+ gen_helper_vfp_tosls(tmp, tmp, tcg_shift, fpst);
84
+ } else {
85
+ gen_helper_vfp_touls(tmp, tmp, tcg_shift, fpst);
86
+ }
87
+ neon_store_reg(a->vd, pass, tmp);
88
+ }
89
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
90
+ tcg_temp_free_i32(tcg_rmode);
91
+ tcg_temp_free_i32(tcg_shift);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
41
+}
95
+}
42
+
96
+
43
/*
97
+#define DO_VCVT(INSN, RMODE, SIGNED) \
44
* 64-bit feature tests via id registers.
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
45
*/
99
+ { \
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
100
+ return do_vcvt(s, a, RMODE, SIGNED); \
47
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
101
+ }
48
}
102
+
49
103
+DO_VCVT(VCVTAU, FPROUNDING_TIEAWAY, false)
50
+static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
104
+DO_VCVT(VCVTAS, FPROUNDING_TIEAWAY, true)
51
+{
105
+DO_VCVT(VCVTNU, FPROUNDING_TIEEVEN, false)
52
+ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
106
+DO_VCVT(VCVTNS, FPROUNDING_TIEEVEN, true)
53
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
107
+DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
54
+}
108
+DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
55
+
109
+DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
56
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
110
+DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
57
{
58
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
59
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/linux-user/elfload.c
62
+++ b/linux-user/elfload.c
63
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
64
hwcaps |= ARM_HWCAP_A64_ASIMD;
65
66
/* probe for the extra features */
67
-#define GET_FEATURE(feat, hwcap) \
68
- do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
69
#define GET_FEATURE_ID(feat, hwcap) \
70
do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
71
72
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
73
GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
74
GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
75
GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
76
- GET_FEATURE(ARM_FEATURE_V8_FP16,
77
- ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
78
+ GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
79
GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
80
GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
81
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
82
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
83
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
84
85
-#undef GET_FEATURE
86
#undef GET_FEATURE_ID
87
88
return hwcaps;
89
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/cpu64.c
92
+++ b/target/arm/cpu64.c
93
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
94
95
t = cpu->isar.id_aa64pfr0;
96
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
97
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
98
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
99
cpu->isar.id_aa64pfr0 = t;
100
101
/* Replicate the same data to the 32-bit id registers. */
102
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
103
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
104
cpu->isar.id_isar6 = u;
105
106
-#ifdef CONFIG_USER_ONLY
107
- /* We don't set these in system emulation mode for the moment,
108
- * since we don't correctly set the ID registers to advertise them,
109
- * and in some cases they're only available in AArch64 and not AArch32,
110
- * whereas the architecture requires them to be present in both if
111
- * present in either.
112
+ /*
113
+ * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
114
+ * so do not set MVFR1.FPHP. Strictly speaking this is not legal,
115
+ * but it is also not legal to enable SVE without support for FP16,
116
+ * and enabling SVE in system mode is more useful in the short term.
117
*/
118
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
119
+
120
+#ifdef CONFIG_USER_ONLY
121
/* For usermode -cpu max we can use a larger and more efficient DCZ
122
* blocksize since we don't have to follow what the hardware does.
123
*/
124
diff --git a/target/arm/helper.c b/target/arm/helper.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/helper.c
127
+++ b/target/arm/helper.c
128
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
129
uint32_t changed;
130
131
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
132
- if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
133
+ if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
134
val &= ~FPCR_FZ16;
135
}
136
137
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/translate-a64.c
140
+++ b/target/arm/translate-a64.c
141
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
142
break;
143
case 3:
144
size = MO_16;
145
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
146
+ if (dc_isar_feature(aa64_fp16, s)) {
147
break;
148
}
149
/* fallthru */
150
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
151
break;
152
case 3:
153
size = MO_16;
154
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
155
+ if (dc_isar_feature(aa64_fp16, s)) {
156
break;
157
}
158
/* fallthru */
159
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
160
break;
161
case 3:
162
sz = MO_16;
163
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
164
+ if (dc_isar_feature(aa64_fp16, s)) {
165
break;
166
}
167
/* fallthru */
168
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
169
handle_fp_1src_double(s, opcode, rd, rn);
170
break;
171
case 3:
172
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
173
+ if (!dc_isar_feature(aa64_fp16, s)) {
174
unallocated_encoding(s);
175
return;
176
}
177
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
178
handle_fp_2src_double(s, opcode, rd, rn, rm);
179
break;
180
case 3:
181
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
182
+ if (!dc_isar_feature(aa64_fp16, s)) {
183
unallocated_encoding(s);
184
return;
185
}
186
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
187
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
188
break;
189
case 3:
190
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
191
+ if (!dc_isar_feature(aa64_fp16, s)) {
192
unallocated_encoding(s);
193
return;
194
}
195
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
196
break;
197
case 3:
198
sz = MO_16;
199
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
200
+ if (dc_isar_feature(aa64_fp16, s)) {
201
break;
202
}
203
/* fallthru */
204
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
205
case 1: /* float64 */
206
break;
207
case 3: /* float16 */
208
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
209
+ if (dc_isar_feature(aa64_fp16, s)) {
210
break;
211
}
212
/* fallthru */
213
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
214
break;
215
case 0x6: /* 16-bit float, 32-bit int */
216
case 0xe: /* 16-bit float, 64-bit int */
217
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
218
+ if (dc_isar_feature(aa64_fp16, s)) {
219
break;
220
}
221
/* fallthru */
222
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
223
case 1: /* float64 */
224
break;
225
case 3: /* float16 */
226
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
227
+ if (dc_isar_feature(aa64_fp16, s)) {
228
break;
229
}
230
/* fallthru */
231
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
232
*/
233
is_min = extract32(size, 1, 1);
234
is_fp = true;
235
- if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
236
+ if (!is_u && dc_isar_feature(aa64_fp16, s)) {
237
size = 1;
238
} else if (!is_u || !is_q || extract32(size, 0, 1)) {
239
unallocated_encoding(s);
240
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
241
242
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
243
/* Check for FMOV (vector, immediate) - half-precision */
244
- if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
245
+ if (!(dc_isar_feature(aa64_fp16, s) && o2 && cmode == 0xf)) {
246
unallocated_encoding(s);
247
return;
248
}
249
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
250
case 0x2f: /* FMINP */
251
/* FP op, size[0] is 32 or 64 bit*/
252
if (!u) {
253
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
254
+ if (!dc_isar_feature(aa64_fp16, s)) {
255
unallocated_encoding(s);
256
return;
257
} else {
258
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
259
size = MO_32;
260
} else if (immh & 2) {
261
size = MO_16;
262
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
263
+ if (!dc_isar_feature(aa64_fp16, s)) {
264
unallocated_encoding(s);
265
return;
266
}
267
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
268
size = MO_32;
269
} else if (immh & 0x2) {
270
size = MO_16;
271
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
272
+ if (!dc_isar_feature(aa64_fp16, s)) {
273
unallocated_encoding(s);
274
return;
275
}
276
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
277
return;
278
}
279
280
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
281
+ if (!dc_isar_feature(aa64_fp16, s)) {
282
unallocated_encoding(s);
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
286
TCGv_ptr fpst;
287
bool pairwise = false;
288
289
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
290
+ if (!dc_isar_feature(aa64_fp16, s)) {
291
unallocated_encoding(s);
292
return;
293
}
294
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
295
case 0x1c: /* FCADD, #90 */
296
case 0x1e: /* FCADD, #270 */
297
if (size == 0
298
- || (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
299
+ || (size == 1 && !dc_isar_feature(aa64_fp16, s))
300
|| (size == 3 && !is_q)) {
301
unallocated_encoding(s);
302
return;
303
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
304
bool need_fpst = true;
305
int rmode;
306
307
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
308
+ if (!dc_isar_feature(aa64_fp16, s)) {
309
unallocated_encoding(s);
310
return;
311
}
312
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
313
}
314
break;
315
}
316
- if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
317
+ if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
318
unallocated_encoding(s);
319
return;
320
}
321
diff --git a/target/arm/translate.c b/target/arm/translate.c
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
322
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
323
--- a/target/arm/translate.c
113
--- a/target/arm/translate.c
324
+++ b/target/arm/translate.c
114
+++ b/target/arm/translate.c
325
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
115
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
326
int size = extract32(insn, 20, 1);
116
#define NEON_2RM_VCVT_SF 62
327
data = extract32(insn, 23, 2); /* rot */
117
#define NEON_2RM_VCVT_UF 63
328
if (!dc_isar_feature(aa32_vcma, s)
118
329
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
119
-static bool neon_2rm_is_v8_op(int op)
330
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
120
-{
331
return 1;
121
- /* Return true if this neon 2reg-misc op is ARMv8 and up */
332
}
122
- switch (op) {
333
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
123
- case NEON_2RM_VRINTN:
334
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
124
- case NEON_2RM_VRINTA:
335
int size = extract32(insn, 20, 1);
125
- case NEON_2RM_VRINTM:
336
data = extract32(insn, 24, 1); /* rot */
126
- case NEON_2RM_VRINTP:
337
if (!dc_isar_feature(aa32_vcma, s)
127
- case NEON_2RM_VRINTZ:
338
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
128
- case NEON_2RM_VRINTX:
339
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
129
- case NEON_2RM_VCVTAU:
340
return 1;
130
- case NEON_2RM_VCVTAS:
341
}
131
- case NEON_2RM_VCVTNU:
342
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
132
- case NEON_2RM_VCVTNS:
343
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
133
- case NEON_2RM_VCVTPU:
344
return 1;
134
- case NEON_2RM_VCVTPS:
345
}
135
- case NEON_2RM_VCVTMU:
346
if (size == 0) {
136
- case NEON_2RM_VCVTMS:
347
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
137
- return true;
348
+ if (!dc_isar_feature(aa32_fp16_arith, s)) {
138
- default:
349
return 1;
139
- return false;
350
}
140
- }
351
/* For fp16, rm is just Vm, and index is M. */
141
-}
142
-
143
/* Each entry in this array has bit n set if the insn allows
144
* size value n (otherwise it will UNDEF). Since unallocated
145
* op values will have no bits set they always UNDEF.
146
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
147
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
148
return 1;
149
}
150
- if (neon_2rm_is_v8_op(op) &&
151
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
152
- return 1;
153
- }
154
if (q && ((rm | rd) & 1)) {
155
return 1;
156
}
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
case NEON_2RM_VRINTM:
159
case NEON_2RM_VRINTP:
160
case NEON_2RM_VRINTZ:
161
+ case NEON_2RM_VCVTAU:
162
+ case NEON_2RM_VCVTAS:
163
+ case NEON_2RM_VCVTNU:
164
+ case NEON_2RM_VCVTNS:
165
+ case NEON_2RM_VCVTPU:
166
+ case NEON_2RM_VCVTPS:
167
+ case NEON_2RM_VCVTMU:
168
+ case NEON_2RM_VCVTMS:
169
/* handled by decodetree */
170
return 1;
171
case NEON_2RM_VTRN:
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
173
}
174
neon_store_reg(rm, pass, tmp2);
175
break;
176
- case NEON_2RM_VCVTAU:
177
- case NEON_2RM_VCVTAS:
178
- case NEON_2RM_VCVTNU:
179
- case NEON_2RM_VCVTNS:
180
- case NEON_2RM_VCVTPU:
181
- case NEON_2RM_VCVTPS:
182
- case NEON_2RM_VCVTMU:
183
- case NEON_2RM_VCVTMS:
184
- {
185
- bool is_signed = !extract32(insn, 7, 1);
186
- TCGv_ptr fpst = get_fpstatus_ptr(1);
187
- TCGv_i32 tcg_rmode, tcg_shift;
188
- int rmode = fp_decode_rm[extract32(insn, 8, 2)];
189
-
190
- tcg_shift = tcg_const_i32(0);
191
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
192
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
193
- cpu_env);
194
-
195
- if (is_signed) {
196
- gen_helper_vfp_tosls(tmp, tmp,
197
- tcg_shift, fpst);
198
- } else {
199
- gen_helper_vfp_touls(tmp, tmp,
200
- tcg_shift, fpst);
201
- }
202
-
203
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
204
- cpu_env);
205
- tcg_temp_free_i32(tcg_rmode);
206
- tcg_temp_free_i32(tcg_shift);
207
- tcg_temp_free_ptr(fpst);
208
- break;
209
- }
210
default:
211
/* Reserved op values were caught by the
212
* neon_2rm_sizes[] check earlier.
352
--
213
--
353
2.19.1
214
2.20.1
354
215
355
216
diff view generated by jsdifflib
1
The HCR.FB virtualization configuration register bit requests that
1
Convert the Neon VSWP insn to decodetree. Since the new implementation
2
TLB maintenance, branch predictor invalidate-all and icache
2
doesn't have to share a pass-loop with the other 2-reg-misc operations
3
invalidate-all operations performed in NS EL1 should be upgraded
3
we can implement the swap with 64-bit accesses rather than 32-bits
4
from "local CPU only to "broadcast within Inner Shareable domain".
4
(which brings us into line with the pseudocode and is more efficient).
5
For QEMU we NOP the branch predictor and icache operations, so
6
we only need to upgrade the TLB invalidates:
7
AArch32 TLBIALL, TLBIMVA, TLBIASID, DTLBIALL, DTLBIMVA, DTLBIASID,
8
ITLBIALL, ITLBIMVA, ITLBIASID, TLBIMVAA, TLBIMVAL, TLBIMVAAL
9
AArch64 TLBI VMALLE1, TLBI VAE1, TLBI ASIDE1, TLBI VAAE1,
10
TLBI VALE1, TLBI VAALE1
11
5
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20181012144235.19646-4-peter.maydell@linaro.org
8
Message-id: 20200616170844.13318-20-peter.maydell@linaro.org
15
---
9
---
16
target/arm/helper.c | 191 +++++++++++++++++++++++++++-----------------
10
target/arm/neon-dp.decode | 2 ++
17
1 file changed, 116 insertions(+), 75 deletions(-)
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 5 +---
13
3 files changed, 44 insertions(+), 4 deletions(-)
18
14
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/target/arm/neon-dp.decode
22
+++ b/target/arm/helper.c
18
+++ b/target/arm/neon-dp.decode
23
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
24
raw_write(env, ri, value);
20
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
25
}
21
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
26
22
27
-static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
+ VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
28
- uint64_t value)
24
+
29
-{
25
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
30
- /* Invalidate all (TLBIALL) */
26
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
31
- ARMCPU *cpu = arm_env_get_cpu(env);
27
32
-
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
- tlb_flush(CPU(cpu));
29
index XXXXXXX..XXXXXXX 100644
34
-}
30
--- a/target/arm/translate-neon.inc.c
35
-
31
+++ b/target/arm/translate-neon.inc.c
36
-static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
@@ -XXX,XX +XXX,XX @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
37
- uint64_t value)
33
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
38
-{
34
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
39
- /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
35
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
40
- ARMCPU *cpu = arm_env_get_cpu(env);
36
+
41
-
37
+static bool trans_VSWP(DisasContext *s, arg_2misc *a)
42
- tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
43
-}
44
-
45
-static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
46
- uint64_t value)
47
-{
48
- /* Invalidate by ASID (TLBIASID) */
49
- ARMCPU *cpu = arm_env_get_cpu(env);
50
-
51
- tlb_flush(CPU(cpu));
52
-}
53
-
54
-static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
55
- uint64_t value)
56
-{
57
- /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
58
- ARMCPU *cpu = arm_env_get_cpu(env);
59
-
60
- tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
61
-}
62
-
63
/* IS variants of TLB operations must affect all cores */
64
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
uint64_t value)
66
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
68
}
69
70
+/*
71
+ * Non-IS variants of TLB operations are upgraded to
72
+ * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
73
+ * force broadcast of these operations.
74
+ */
75
+static bool tlb_force_broadcast(CPUARMState *env)
76
+{
38
+{
77
+ return (env->cp15.hcr_el2 & HCR_FB) &&
39
+ TCGv_i64 rm, rd;
78
+ arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
40
+ int pass;
79
+}
80
+
41
+
81
+static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
42
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
82
+ uint64_t value)
43
+ return false;
83
+{
84
+ /* Invalidate all (TLBIALL) */
85
+ ARMCPU *cpu = arm_env_get_cpu(env);
86
+
87
+ if (tlb_force_broadcast(env)) {
88
+ tlbiall_is_write(env, NULL, value);
89
+ return;
90
+ }
44
+ }
91
+
45
+
92
+ tlb_flush(CPU(cpu));
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
93
+}
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
94
+
48
+ ((a->vd | a->vm) & 0x10)) {
95
+static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
49
+ return false;
96
+ uint64_t value)
97
+{
98
+ /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
99
+ ARMCPU *cpu = arm_env_get_cpu(env);
100
+
101
+ if (tlb_force_broadcast(env)) {
102
+ tlbimva_is_write(env, NULL, value);
103
+ return;
104
+ }
50
+ }
105
+
51
+
106
+ tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
52
+ if (a->size != 0) {
107
+}
53
+ return false;
108
+
109
+static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
110
+ uint64_t value)
111
+{
112
+ /* Invalidate by ASID (TLBIASID) */
113
+ ARMCPU *cpu = arm_env_get_cpu(env);
114
+
115
+ if (tlb_force_broadcast(env)) {
116
+ tlbiasid_is_write(env, NULL, value);
117
+ return;
118
+ }
54
+ }
119
+
55
+
120
+ tlb_flush(CPU(cpu));
56
+ if ((a->vd | a->vm) & a->q) {
121
+}
57
+ return false;
122
+
123
+static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
124
+ uint64_t value)
125
+{
126
+ /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
127
+ ARMCPU *cpu = arm_env_get_cpu(env);
128
+
129
+ if (tlb_force_broadcast(env)) {
130
+ tlbimvaa_is_write(env, NULL, value);
131
+ return;
132
+ }
58
+ }
133
+
59
+
134
+ tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
60
+ if (!vfp_access_check(s)) {
135
+}
61
+ return true;
136
+
137
static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
138
uint64_t value)
139
{
140
@@ -XXX,XX +XXX,XX @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
141
* Page D4-1736 (DDI0487A.b)
142
*/
143
144
-static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
145
- uint64_t value)
146
-{
147
- CPUState *cs = ENV_GET_CPU(env);
148
-
149
- if (arm_is_secure_below_el3(env)) {
150
- tlb_flush_by_mmuidx(cs,
151
- ARMMMUIdxBit_S1SE1 |
152
- ARMMMUIdxBit_S1SE0);
153
- } else {
154
- tlb_flush_by_mmuidx(cs,
155
- ARMMMUIdxBit_S12NSE1 |
156
- ARMMMUIdxBit_S12NSE0);
157
- }
158
-}
159
-
160
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
161
uint64_t value)
162
{
163
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
164
}
165
}
166
167
+static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
168
+ uint64_t value)
169
+{
170
+ CPUState *cs = ENV_GET_CPU(env);
171
+
172
+ if (tlb_force_broadcast(env)) {
173
+ tlbi_aa64_vmalle1_write(env, NULL, value);
174
+ return;
175
+ }
62
+ }
176
+
63
+
177
+ if (arm_is_secure_below_el3(env)) {
64
+ rm = tcg_temp_new_i64();
178
+ tlb_flush_by_mmuidx(cs,
65
+ rd = tcg_temp_new_i64();
179
+ ARMMMUIdxBit_S1SE1 |
66
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
180
+ ARMMMUIdxBit_S1SE0);
67
+ neon_load_reg64(rm, a->vm + pass);
181
+ } else {
68
+ neon_load_reg64(rd, a->vd + pass);
182
+ tlb_flush_by_mmuidx(cs,
69
+ neon_store_reg64(rm, a->vd + pass);
183
+ ARMMMUIdxBit_S12NSE1 |
70
+ neon_store_reg64(rd, a->vm + pass);
184
+ ARMMMUIdxBit_S12NSE0);
185
+ }
71
+ }
72
+ tcg_temp_free_i64(rm);
73
+ tcg_temp_free_i64(rd);
74
+
75
+ return true;
186
+}
76
+}
187
+
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
188
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
78
index XXXXXXX..XXXXXXX 100644
189
uint64_t value)
79
--- a/target/arm/translate.c
190
{
80
+++ b/target/arm/translate.c
191
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
192
tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
82
case NEON_2RM_VCVTPS:
193
}
83
case NEON_2RM_VCVTMU:
194
84
case NEON_2RM_VCVTMS:
195
-static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
85
+ case NEON_2RM_VSWP:
196
- uint64_t value)
86
/* handled by decodetree */
197
-{
87
return 1;
198
- /* Invalidate by VA, EL1&0 (AArch64 version).
88
case NEON_2RM_VTRN:
199
- * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
200
- * since we don't support flush-for-specific-ASID-only or
90
for (pass = 0; pass < (q ? 4 : 2); pass++) {
201
- * flush-last-level-only.
91
tmp = neon_load_reg(rm, pass);
202
- */
92
switch (op) {
203
- ARMCPU *cpu = arm_env_get_cpu(env);
93
- case NEON_2RM_VSWP:
204
- CPUState *cs = CPU(cpu);
94
- tmp2 = neon_load_reg(rd, pass);
205
- uint64_t pageaddr = sextract64(value << 12, 0, 56);
95
- neon_store_reg(rm, pass, tmp2);
206
-
96
- break;
207
- if (arm_is_secure_below_el3(env)) {
97
case NEON_2RM_VTRN:
208
- tlb_flush_page_by_mmuidx(cs, pageaddr,
98
tmp2 = neon_load_reg(rd, pass);
209
- ARMMMUIdxBit_S1SE1 |
99
switch (size) {
210
- ARMMMUIdxBit_S1SE0);
211
- } else {
212
- tlb_flush_page_by_mmuidx(cs, pageaddr,
213
- ARMMMUIdxBit_S12NSE1 |
214
- ARMMMUIdxBit_S12NSE0);
215
- }
216
-}
217
-
218
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
219
uint64_t value)
220
{
221
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
222
}
223
}
224
225
+static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
226
+ uint64_t value)
227
+{
228
+ /* Invalidate by VA, EL1&0 (AArch64 version).
229
+ * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
230
+ * since we don't support flush-for-specific-ASID-only or
231
+ * flush-last-level-only.
232
+ */
233
+ ARMCPU *cpu = arm_env_get_cpu(env);
234
+ CPUState *cs = CPU(cpu);
235
+ uint64_t pageaddr = sextract64(value << 12, 0, 56);
236
+
237
+ if (tlb_force_broadcast(env)) {
238
+ tlbi_aa64_vae1is_write(env, NULL, value);
239
+ return;
240
+ }
241
+
242
+ if (arm_is_secure_below_el3(env)) {
243
+ tlb_flush_page_by_mmuidx(cs, pageaddr,
244
+ ARMMMUIdxBit_S1SE1 |
245
+ ARMMMUIdxBit_S1SE0);
246
+ } else {
247
+ tlb_flush_page_by_mmuidx(cs, pageaddr,
248
+ ARMMMUIdxBit_S12NSE1 |
249
+ ARMMMUIdxBit_S12NSE0);
250
+ }
251
+}
252
+
253
static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
254
uint64_t value)
255
{
256
--
100
--
257
2.19.1
101
2.20.1
258
102
259
103
diff view generated by jsdifflib
1
For AArch32, exception return happens through certain kinds
1
Convert the Neon VTRN insn to decodetree. This is the last insn in the
2
of CPSR write. We don't currently have any CPU_LOG_INT logging
2
Neon data-processing group, so we can remove all the now-unused old
3
of these events (unlike AArch64, where we log in the ERET
3
decoder framework.
4
instruction). Add some suitable logging.
5
4
6
This will log exception returns like this:
5
It's possible that there's a more efficient implementation of
7
Exception return from AArch32 hyp to usr PC 0x80100374
6
VTRN, but for this conversion we just copy the existing approach.
8
9
paralleling the existing logging in the exception_return
10
helper for AArch64 exception returns:
11
Exception return from AArch64 EL2 to AArch64 EL0 PC 0x8003045c
12
Exception return from AArch64 EL2 to AArch32 EL0 PC 0x8003045c
13
14
(Note that an AArch32 exception return can only be
15
AArch32->AArch32, never to AArch64.)
16
7
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20181012144235.19646-2-peter.maydell@linaro.org
10
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org
20
---
11
---
21
target/arm/internals.h | 18 ++++++++++++++++++
12
target/arm/neon-dp.decode | 2 +-
22
target/arm/helper.c | 10 ++++++++++
13
target/arm/translate-neon.inc.c | 90 ++++++++
23
target/arm/translate.c | 7 +------
14
target/arm/translate.c | 363 +-------------------------------
24
3 files changed, 29 insertions(+), 6 deletions(-)
15
3 files changed, 93 insertions(+), 362 deletions(-)
25
16
26
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
27
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/internals.h
19
--- a/target/arm/neon-dp.decode
29
+++ b/target/arm/internals.h
20
+++ b/target/arm/neon-dp.decode
30
@@ -XXX,XX +XXX,XX @@ static inline uint32_t v7m_sp_limit(CPUARMState *env)
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
31
}
22
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
23
24
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
25
-
26
+ VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
27
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
28
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
35
36
return true;
32
}
37
}
33
38
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
34
+/**
35
+ * aarch32_mode_name(): Return name of the AArch32 CPU mode
36
+ * @psr: Program Status Register indicating CPU mode
37
+ *
38
+ * Returns, for debug logging purposes, a printable representation
39
+ * of the AArch32 CPU mode ("svc", "usr", etc) as indicated by
40
+ * the low bits of the specified PSR.
41
+ */
42
+static inline const char *aarch32_mode_name(uint32_t psr)
43
+{
39
+{
44
+ static const char cpu_mode_names[16][4] = {
40
+ TCGv_i32 rd, tmp;
45
+ "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
41
+
46
+ "???", "???", "hyp", "und", "???", "???", "???", "sys"
42
+ rd = tcg_temp_new_i32();
47
+ };
43
+ tmp = tcg_temp_new_i32();
48
+
44
+
49
+ return cpu_mode_names[psr & 0xf];
45
+ tcg_gen_shli_i32(rd, t0, 8);
46
+ tcg_gen_andi_i32(rd, rd, 0xff00ff00);
47
+ tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
48
+ tcg_gen_or_i32(rd, rd, tmp);
49
+
50
+ tcg_gen_shri_i32(t1, t1, 8);
51
+ tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
52
+ tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
53
+ tcg_gen_or_i32(t1, t1, tmp);
54
+ tcg_gen_mov_i32(t0, rd);
55
+
56
+ tcg_temp_free_i32(tmp);
57
+ tcg_temp_free_i32(rd);
50
+}
58
+}
51
+
59
+
52
#endif
60
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
53
diff --git a/target/arm/helper.c b/target/arm/helper.c
61
+{
54
index XXXXXXX..XXXXXXX 100644
62
+ TCGv_i32 rd, tmp;
55
--- a/target/arm/helper.c
63
+
56
+++ b/target/arm/helper.c
64
+ rd = tcg_temp_new_i32();
57
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
65
+ tmp = tcg_temp_new_i32();
58
mask |= CPSR_IL;
66
+
59
val |= CPSR_IL;
67
+ tcg_gen_shli_i32(rd, t0, 16);
60
}
68
+ tcg_gen_andi_i32(tmp, t1, 0xffff);
61
+ qemu_log_mask(LOG_GUEST_ERROR,
69
+ tcg_gen_or_i32(rd, rd, tmp);
62
+ "Illegal AArch32 mode switch attempt from %s to %s\n",
70
+ tcg_gen_shri_i32(t1, t1, 16);
63
+ aarch32_mode_name(env->uncached_cpsr),
71
+ tcg_gen_andi_i32(tmp, t0, 0xffff0000);
64
+ aarch32_mode_name(val));
72
+ tcg_gen_or_i32(t1, t1, tmp);
65
} else {
73
+ tcg_gen_mov_i32(t0, rd);
66
+ qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
74
+
67
+ write_type == CPSRWriteExceptionReturn ?
75
+ tcg_temp_free_i32(tmp);
68
+ "Exception return from AArch32" :
76
+ tcg_temp_free_i32(rd);
69
+ "AArch32 mode switch from",
77
+}
70
+ aarch32_mode_name(env->uncached_cpsr),
78
+
71
+ aarch32_mode_name(val), env->regs[15]);
79
+static bool trans_VTRN(DisasContext *s, arg_2misc *a)
72
switch_mode(env, val & CPSR_M);
80
+{
73
}
81
+ TCGv_i32 tmp, tmp2;
74
}
82
+ int pass;
83
+
84
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
85
+ return false;
86
+ }
87
+
88
+ /* UNDEF accesses to D16-D31 if they don't exist. */
89
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
90
+ ((a->vd | a->vm) & 0x10)) {
91
+ return false;
92
+ }
93
+
94
+ if ((a->vd | a->vm) & a->q) {
95
+ return false;
96
+ }
97
+
98
+ if (a->size == 3) {
99
+ return false;
100
+ }
101
+
102
+ if (!vfp_access_check(s)) {
103
+ return true;
104
+ }
105
+
106
+ if (a->size == 2) {
107
+ for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
108
+ tmp = neon_load_reg(a->vm, pass);
109
+ tmp2 = neon_load_reg(a->vd, pass + 1);
110
+ neon_store_reg(a->vm, pass, tmp2);
111
+ neon_store_reg(a->vd, pass + 1, tmp);
112
+ }
113
+ } else {
114
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
115
+ tmp = neon_load_reg(a->vm, pass);
116
+ tmp2 = neon_load_reg(a->vd, pass);
117
+ if (a->size == 0) {
118
+ gen_neon_trn_u8(tmp, tmp2);
119
+ } else {
120
+ gen_neon_trn_u16(tmp, tmp2);
121
+ }
122
+ neon_store_reg(a->vm, pass, tmp2);
123
+ neon_store_reg(a->vd, pass, tmp);
124
+ }
125
+ }
126
+ return true;
127
+}
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
132
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
80
translator_loop(ops, &dc.base, cpu, tb);
133
gen_rfe(s, pc, load_cpu_field(spsr));
81
}
134
}
82
135
83
-static const char *cpu_mode_names[16] = {
136
-static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
84
- "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
137
-{
85
- "???", "???", "hyp", "und", "???", "???", "???", "sys"
138
- TCGv_i32 rd, tmp;
139
-
140
- rd = tcg_temp_new_i32();
141
- tmp = tcg_temp_new_i32();
142
-
143
- tcg_gen_shli_i32(rd, t0, 8);
144
- tcg_gen_andi_i32(rd, rd, 0xff00ff00);
145
- tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
146
- tcg_gen_or_i32(rd, rd, tmp);
147
-
148
- tcg_gen_shri_i32(t1, t1, 8);
149
- tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
150
- tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
151
- tcg_gen_or_i32(t1, t1, tmp);
152
- tcg_gen_mov_i32(t0, rd);
153
-
154
- tcg_temp_free_i32(tmp);
155
- tcg_temp_free_i32(rd);
156
-}
157
-
158
-static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
159
-{
160
- TCGv_i32 rd, tmp;
161
-
162
- rd = tcg_temp_new_i32();
163
- tmp = tcg_temp_new_i32();
164
-
165
- tcg_gen_shli_i32(rd, t0, 16);
166
- tcg_gen_andi_i32(tmp, t1, 0xffff);
167
- tcg_gen_or_i32(rd, rd, tmp);
168
- tcg_gen_shri_i32(t1, t1, 16);
169
- tcg_gen_andi_i32(tmp, t0, 0xffff0000);
170
- tcg_gen_or_i32(t1, t1, tmp);
171
- tcg_gen_mov_i32(t0, rd);
172
-
173
- tcg_temp_free_i32(tmp);
174
- tcg_temp_free_i32(rd);
175
-}
176
-
177
-/* Symbolic constants for op fields for Neon 2-register miscellaneous.
178
- * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
179
- * table A7-13.
180
- */
181
-#define NEON_2RM_VREV64 0
182
-#define NEON_2RM_VREV32 1
183
-#define NEON_2RM_VREV16 2
184
-#define NEON_2RM_VPADDL 4
185
-#define NEON_2RM_VPADDL_U 5
186
-#define NEON_2RM_AESE 6 /* Includes AESD */
187
-#define NEON_2RM_AESMC 7 /* Includes AESIMC */
188
-#define NEON_2RM_VCLS 8
189
-#define NEON_2RM_VCLZ 9
190
-#define NEON_2RM_VCNT 10
191
-#define NEON_2RM_VMVN 11
192
-#define NEON_2RM_VPADAL 12
193
-#define NEON_2RM_VPADAL_U 13
194
-#define NEON_2RM_VQABS 14
195
-#define NEON_2RM_VQNEG 15
196
-#define NEON_2RM_VCGT0 16
197
-#define NEON_2RM_VCGE0 17
198
-#define NEON_2RM_VCEQ0 18
199
-#define NEON_2RM_VCLE0 19
200
-#define NEON_2RM_VCLT0 20
201
-#define NEON_2RM_SHA1H 21
202
-#define NEON_2RM_VABS 22
203
-#define NEON_2RM_VNEG 23
204
-#define NEON_2RM_VCGT0_F 24
205
-#define NEON_2RM_VCGE0_F 25
206
-#define NEON_2RM_VCEQ0_F 26
207
-#define NEON_2RM_VCLE0_F 27
208
-#define NEON_2RM_VCLT0_F 28
209
-#define NEON_2RM_VABS_F 30
210
-#define NEON_2RM_VNEG_F 31
211
-#define NEON_2RM_VSWP 32
212
-#define NEON_2RM_VTRN 33
213
-#define NEON_2RM_VUZP 34
214
-#define NEON_2RM_VZIP 35
215
-#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
216
-#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
217
-#define NEON_2RM_VSHLL 38
218
-#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
219
-#define NEON_2RM_VRINTN 40
220
-#define NEON_2RM_VRINTX 41
221
-#define NEON_2RM_VRINTA 42
222
-#define NEON_2RM_VRINTZ 43
223
-#define NEON_2RM_VCVT_F16_F32 44
224
-#define NEON_2RM_VRINTM 45
225
-#define NEON_2RM_VCVT_F32_F16 46
226
-#define NEON_2RM_VRINTP 47
227
-#define NEON_2RM_VCVTAU 48
228
-#define NEON_2RM_VCVTAS 49
229
-#define NEON_2RM_VCVTNU 50
230
-#define NEON_2RM_VCVTNS 51
231
-#define NEON_2RM_VCVTPU 52
232
-#define NEON_2RM_VCVTPS 53
233
-#define NEON_2RM_VCVTMU 54
234
-#define NEON_2RM_VCVTMS 55
235
-#define NEON_2RM_VRECPE 56
236
-#define NEON_2RM_VRSQRTE 57
237
-#define NEON_2RM_VRECPE_F 58
238
-#define NEON_2RM_VRSQRTE_F 59
239
-#define NEON_2RM_VCVT_FS 60
240
-#define NEON_2RM_VCVT_FU 61
241
-#define NEON_2RM_VCVT_SF 62
242
-#define NEON_2RM_VCVT_UF 63
243
-
244
-/* Each entry in this array has bit n set if the insn allows
245
- * size value n (otherwise it will UNDEF). Since unallocated
246
- * op values will have no bits set they always UNDEF.
247
- */
248
-static const uint8_t neon_2rm_sizes[] = {
249
- [NEON_2RM_VREV64] = 0x7,
250
- [NEON_2RM_VREV32] = 0x3,
251
- [NEON_2RM_VREV16] = 0x1,
252
- [NEON_2RM_VPADDL] = 0x7,
253
- [NEON_2RM_VPADDL_U] = 0x7,
254
- [NEON_2RM_AESE] = 0x1,
255
- [NEON_2RM_AESMC] = 0x1,
256
- [NEON_2RM_VCLS] = 0x7,
257
- [NEON_2RM_VCLZ] = 0x7,
258
- [NEON_2RM_VCNT] = 0x1,
259
- [NEON_2RM_VMVN] = 0x1,
260
- [NEON_2RM_VPADAL] = 0x7,
261
- [NEON_2RM_VPADAL_U] = 0x7,
262
- [NEON_2RM_VQABS] = 0x7,
263
- [NEON_2RM_VQNEG] = 0x7,
264
- [NEON_2RM_VCGT0] = 0x7,
265
- [NEON_2RM_VCGE0] = 0x7,
266
- [NEON_2RM_VCEQ0] = 0x7,
267
- [NEON_2RM_VCLE0] = 0x7,
268
- [NEON_2RM_VCLT0] = 0x7,
269
- [NEON_2RM_SHA1H] = 0x4,
270
- [NEON_2RM_VABS] = 0x7,
271
- [NEON_2RM_VNEG] = 0x7,
272
- [NEON_2RM_VCGT0_F] = 0x4,
273
- [NEON_2RM_VCGE0_F] = 0x4,
274
- [NEON_2RM_VCEQ0_F] = 0x4,
275
- [NEON_2RM_VCLE0_F] = 0x4,
276
- [NEON_2RM_VCLT0_F] = 0x4,
277
- [NEON_2RM_VABS_F] = 0x4,
278
- [NEON_2RM_VNEG_F] = 0x4,
279
- [NEON_2RM_VSWP] = 0x1,
280
- [NEON_2RM_VTRN] = 0x7,
281
- [NEON_2RM_VUZP] = 0x7,
282
- [NEON_2RM_VZIP] = 0x7,
283
- [NEON_2RM_VMOVN] = 0x7,
284
- [NEON_2RM_VQMOVN] = 0x7,
285
- [NEON_2RM_VSHLL] = 0x7,
286
- [NEON_2RM_SHA1SU1] = 0x4,
287
- [NEON_2RM_VRINTN] = 0x4,
288
- [NEON_2RM_VRINTX] = 0x4,
289
- [NEON_2RM_VRINTA] = 0x4,
290
- [NEON_2RM_VRINTZ] = 0x4,
291
- [NEON_2RM_VCVT_F16_F32] = 0x2,
292
- [NEON_2RM_VRINTM] = 0x4,
293
- [NEON_2RM_VCVT_F32_F16] = 0x2,
294
- [NEON_2RM_VRINTP] = 0x4,
295
- [NEON_2RM_VCVTAU] = 0x4,
296
- [NEON_2RM_VCVTAS] = 0x4,
297
- [NEON_2RM_VCVTNU] = 0x4,
298
- [NEON_2RM_VCVTNS] = 0x4,
299
- [NEON_2RM_VCVTPU] = 0x4,
300
- [NEON_2RM_VCVTPS] = 0x4,
301
- [NEON_2RM_VCVTMU] = 0x4,
302
- [NEON_2RM_VCVTMS] = 0x4,
303
- [NEON_2RM_VRECPE] = 0x4,
304
- [NEON_2RM_VRSQRTE] = 0x4,
305
- [NEON_2RM_VRECPE_F] = 0x4,
306
- [NEON_2RM_VRSQRTE_F] = 0x4,
307
- [NEON_2RM_VCVT_FS] = 0x4,
308
- [NEON_2RM_VCVT_FU] = 0x4,
309
- [NEON_2RM_VCVT_SF] = 0x4,
310
- [NEON_2RM_VCVT_UF] = 0x4,
86
-};
311
-};
87
-
312
-
88
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
313
static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
89
int flags)
314
uint32_t opr_sz, uint32_t max_sz,
315
gen_helper_gvec_3_ptr *fn)
316
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
317
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
318
}
319
320
-/* Translate a NEON data processing instruction. Return nonzero if the
321
- instruction is invalid.
322
- We process data in a mixture of 32-bit and 64-bit chunks.
323
- Mostly we use 32-bit chunks so we can use normal scalar instructions. */
324
-
325
-static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
326
-{
327
- int op;
328
- int q;
329
- int rd, rm;
330
- int size;
331
- int pass;
332
- int u;
333
- TCGv_i32 tmp, tmp2;
334
-
335
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
336
- return 1;
337
- }
338
-
339
- /* FIXME: this access check should not take precedence over UNDEF
340
- * for invalid encodings; we will generate incorrect syndrome information
341
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
342
- */
343
- if (s->fp_excp_el) {
344
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
345
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
346
- return 0;
347
- }
348
-
349
- if (!s->vfp_enabled)
350
- return 1;
351
- q = (insn & (1 << 6)) != 0;
352
- u = (insn >> 24) & 1;
353
- VFP_DREG_D(rd, insn);
354
- VFP_DREG_M(rm, insn);
355
- size = (insn >> 20) & 3;
356
-
357
- if ((insn & (1 << 23)) == 0) {
358
- /* Three register same length: handled by decodetree */
359
- return 1;
360
- } else if (insn & (1 << 4)) {
361
- /* Two registers and shift or reg and imm: handled by decodetree */
362
- return 1;
363
- } else { /* (insn & 0x00800010 == 0x00800000) */
364
- if (size != 3) {
365
- /*
366
- * Three registers of different lengths, or two registers and
367
- * a scalar: handled by decodetree
368
- */
369
- return 1;
370
- } else { /* size == 3 */
371
- if (!u) {
372
- /* Extract: handled by decodetree */
373
- return 1;
374
- } else if ((insn & (1 << 11)) == 0) {
375
- /* Two register misc. */
376
- op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
377
- size = (insn >> 18) & 3;
378
- /* UNDEF for unknown op values and bad op-size combinations */
379
- if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
380
- return 1;
381
- }
382
- if (q && ((rm | rd) & 1)) {
383
- return 1;
384
- }
385
- switch (op) {
386
- case NEON_2RM_VREV64:
387
- case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
388
- case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
389
- case NEON_2RM_VUZP:
390
- case NEON_2RM_VZIP:
391
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
392
- case NEON_2RM_VSHLL:
393
- case NEON_2RM_VCVT_F16_F32:
394
- case NEON_2RM_VCVT_F32_F16:
395
- case NEON_2RM_VMVN:
396
- case NEON_2RM_VNEG:
397
- case NEON_2RM_VABS:
398
- case NEON_2RM_VCEQ0:
399
- case NEON_2RM_VCGT0:
400
- case NEON_2RM_VCLE0:
401
- case NEON_2RM_VCGE0:
402
- case NEON_2RM_VCLT0:
403
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
404
- case NEON_2RM_SHA1H:
405
- case NEON_2RM_SHA1SU1:
406
- case NEON_2RM_VREV32:
407
- case NEON_2RM_VREV16:
408
- case NEON_2RM_VCLS:
409
- case NEON_2RM_VCLZ:
410
- case NEON_2RM_VCNT:
411
- case NEON_2RM_VABS_F:
412
- case NEON_2RM_VNEG_F:
413
- case NEON_2RM_VRECPE:
414
- case NEON_2RM_VRSQRTE:
415
- case NEON_2RM_VQABS:
416
- case NEON_2RM_VQNEG:
417
- case NEON_2RM_VRECPE_F:
418
- case NEON_2RM_VRSQRTE_F:
419
- case NEON_2RM_VCVT_FS:
420
- case NEON_2RM_VCVT_FU:
421
- case NEON_2RM_VCVT_SF:
422
- case NEON_2RM_VCVT_UF:
423
- case NEON_2RM_VRINTX:
424
- case NEON_2RM_VCGT0_F:
425
- case NEON_2RM_VCGE0_F:
426
- case NEON_2RM_VCEQ0_F:
427
- case NEON_2RM_VCLE0_F:
428
- case NEON_2RM_VCLT0_F:
429
- case NEON_2RM_VRINTN:
430
- case NEON_2RM_VRINTA:
431
- case NEON_2RM_VRINTM:
432
- case NEON_2RM_VRINTP:
433
- case NEON_2RM_VRINTZ:
434
- case NEON_2RM_VCVTAU:
435
- case NEON_2RM_VCVTAS:
436
- case NEON_2RM_VCVTNU:
437
- case NEON_2RM_VCVTNS:
438
- case NEON_2RM_VCVTPU:
439
- case NEON_2RM_VCVTPS:
440
- case NEON_2RM_VCVTMU:
441
- case NEON_2RM_VCVTMS:
442
- case NEON_2RM_VSWP:
443
- /* handled by decodetree */
444
- return 1;
445
- case NEON_2RM_VTRN:
446
- if (size == 2) {
447
- int n;
448
- for (n = 0; n < (q ? 4 : 2); n += 2) {
449
- tmp = neon_load_reg(rm, n);
450
- tmp2 = neon_load_reg(rd, n + 1);
451
- neon_store_reg(rm, n, tmp2);
452
- neon_store_reg(rd, n + 1, tmp);
453
- }
454
- } else {
455
- goto elementwise;
456
- }
457
- break;
458
-
459
- default:
460
- elementwise:
461
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
462
- tmp = neon_load_reg(rm, pass);
463
- switch (op) {
464
- case NEON_2RM_VTRN:
465
- tmp2 = neon_load_reg(rd, pass);
466
- switch (size) {
467
- case 0: gen_neon_trn_u8(tmp, tmp2); break;
468
- case 1: gen_neon_trn_u16(tmp, tmp2); break;
469
- default: abort();
470
- }
471
- neon_store_reg(rm, pass, tmp2);
472
- break;
473
- default:
474
- /* Reserved op values were caught by the
475
- * neon_2rm_sizes[] check earlier.
476
- */
477
- abort();
478
- }
479
- neon_store_reg(rd, pass, tmp);
480
- }
481
- break;
482
- }
483
- } else {
484
- /* VTBL, VTBX, VDUP: handled by decodetree */
485
- return 1;
486
- }
487
- }
488
- }
489
- return 0;
490
-}
491
-
492
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
90
{
493
{
91
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
494
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
92
psr & CPSR_V ? 'V' : '-',
495
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
93
psr & CPSR_T ? 'T' : 'A',
496
}
94
ns_status,
497
/* fall back to legacy decoder */
95
- cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
498
96
+ aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
499
- if (((insn >> 25) & 7) == 1) {
97
}
500
- /* NEON Data processing. */
98
501
- if (disas_neon_data_insn(s, insn)) {
99
if (flags & CPU_DUMP_FPU) {
502
- goto illegal_op;
503
- }
504
- return;
505
- }
506
if ((insn & 0x0e000f00) == 0x0c000100) {
507
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
508
/* iWMMXt register transfer. */
509
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
510
break;
511
}
512
if (((insn >> 24) & 3) == 3) {
513
- /* Translate into the equivalent ARM encoding. */
514
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
515
- if (disas_neon_data_insn(s, insn)) {
516
- goto illegal_op;
517
- }
518
+ /* Neon DP, but failed disas_neon_dp() */
519
+ goto illegal_op;
520
} else if (((insn >> 8) & 0xe) == 10) {
521
/* VFP, but failed disas_vfp. */
522
goto illegal_op;
100
--
523
--
101
2.19.1
524
2.20.1
102
525
103
526
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The functions neon_element_offset(), neon_load_element(),
2
2
neon_load_element64(), neon_store_element() and
3
Also introduces neon_element_offset to find the env offset
3
neon_store_element64() are used only in the translate-neon.inc.c
4
of a specific element within a neon register.
4
file, so move their definitions there.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Since the .inc.c file is #included in translate.c this doesn't make
7
Message-id: 20181011205206.3552-7-richard.henderson@linaro.org
7
much difference currently, but it's a more logical place to put the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
functions and it might be helpful if we ever decide to try to make
9
the .inc.c files genuinely separate compilation units.
10
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200616170844.13318-22-peter.maydell@linaro.org
10
---
14
---
11
target/arm/translate.c | 63 ++++++++++++++++++++++++------------------
15
target/arm/translate-neon.inc.c | 101 ++++++++++++++++++++++++++++++++
12
1 file changed, 36 insertions(+), 27 deletions(-)
16
target/arm/translate.c | 101 --------------------------------
13
17
2 files changed, 101 insertions(+), 101 deletions(-)
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
19
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
21
--- a/target/arm/translate-neon.inc.c
17
+++ b/target/arm/translate.c
22
+++ b/target/arm/translate-neon.inc.c
18
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
23
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
19
return vfp_reg_offset(0, sreg);
24
#include "decode-neon-ls.inc.c"
20
}
25
#include "decode-neon-shared.inc.c"
21
26
22
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
27
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
23
+ * where 0 is the least significant end of the register.
28
+ * where 0 is the least significant end of the register.
24
+ */
29
+ */
25
+static inline long
30
+static inline long
26
+neon_element_offset(int reg, int element, TCGMemOp size)
31
+neon_element_offset(int reg, int element, MemOp size)
27
+{
32
+{
28
+ int element_size = 1 << size;
33
+ int element_size = 1 << size;
29
+ int ofs = element * element_size;
34
+ int ofs = element * element_size;
30
+#ifdef HOST_WORDS_BIGENDIAN
35
+#ifdef HOST_WORDS_BIGENDIAN
31
+ /* Calculate the offset assuming fully little-endian,
36
+ /* Calculate the offset assuming fully little-endian,
...
...
36
+ }
41
+ }
37
+#endif
42
+#endif
38
+ return neon_reg_offset(reg, 0) + ofs;
43
+ return neon_reg_offset(reg, 0) + ofs;
39
+}
44
+}
40
+
45
+
46
+static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
47
+{
48
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
49
+
50
+ switch (mop) {
51
+ case MO_UB:
52
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
53
+ break;
54
+ case MO_UW:
55
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
56
+ break;
57
+ case MO_UL:
58
+ tcg_gen_ld_i32(var, cpu_env, offset);
59
+ break;
60
+ default:
61
+ g_assert_not_reached();
62
+ }
63
+}
64
+
65
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
66
+{
67
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
68
+
69
+ switch (mop) {
70
+ case MO_UB:
71
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
72
+ break;
73
+ case MO_UW:
74
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
75
+ break;
76
+ case MO_UL:
77
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
78
+ break;
79
+ case MO_Q:
80
+ tcg_gen_ld_i64(var, cpu_env, offset);
81
+ break;
82
+ default:
83
+ g_assert_not_reached();
84
+ }
85
+}
86
+
87
+static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
88
+{
89
+ long offset = neon_element_offset(reg, ele, size);
90
+
91
+ switch (size) {
92
+ case MO_8:
93
+ tcg_gen_st8_i32(var, cpu_env, offset);
94
+ break;
95
+ case MO_16:
96
+ tcg_gen_st16_i32(var, cpu_env, offset);
97
+ break;
98
+ case MO_32:
99
+ tcg_gen_st_i32(var, cpu_env, offset);
100
+ break;
101
+ default:
102
+ g_assert_not_reached();
103
+ }
104
+}
105
+
106
+static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
107
+{
108
+ long offset = neon_element_offset(reg, ele, size);
109
+
110
+ switch (size) {
111
+ case MO_8:
112
+ tcg_gen_st8_i64(var, cpu_env, offset);
113
+ break;
114
+ case MO_16:
115
+ tcg_gen_st16_i64(var, cpu_env, offset);
116
+ break;
117
+ case MO_32:
118
+ tcg_gen_st32_i64(var, cpu_env, offset);
119
+ break;
120
+ case MO_64:
121
+ tcg_gen_st_i64(var, cpu_env, offset);
122
+ break;
123
+ default:
124
+ g_assert_not_reached();
125
+ }
126
+}
127
+
128
static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
129
{
130
int opr_sz;
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
136
return vfp_reg_offset(0, sreg);
137
}
138
139
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
140
- * where 0 is the least significant end of the register.
141
- */
142
-static inline long
143
-neon_element_offset(int reg, int element, MemOp size)
144
-{
145
- int element_size = 1 << size;
146
- int ofs = element * element_size;
147
-#ifdef HOST_WORDS_BIGENDIAN
148
- /* Calculate the offset assuming fully little-endian,
149
- * then XOR to account for the order of the 8-byte units.
150
- */
151
- if (element_size < 8) {
152
- ofs ^= 8 - element_size;
153
- }
154
-#endif
155
- return neon_reg_offset(reg, 0) + ofs;
156
-}
157
-
41
static TCGv_i32 neon_load_reg(int reg, int pass)
158
static TCGv_i32 neon_load_reg(int reg, int pass)
42
{
159
{
43
TCGv_i32 tmp = tcg_temp_new_i32();
160
TCGv_i32 tmp = tcg_temp_new_i32();
44
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
161
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
45
tmp = load_reg(s, rd);
162
return tmp;
46
if (insn & (1 << 23)) {
163
}
47
/* VDUP */
164
48
- if (size == 0) {
165
-static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
49
- gen_neon_dup_u8(tmp, 0);
166
-{
50
- } else if (size == 1) {
167
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
51
- gen_neon_dup_low16(tmp);
168
-
52
- }
169
- switch (mop) {
53
- for (n = 0; n <= pass * 2; n++) {
170
- case MO_UB:
54
- tmp2 = tcg_temp_new_i32();
171
- tcg_gen_ld8u_i32(var, cpu_env, offset);
55
- tcg_gen_mov_i32(tmp2, tmp);
172
- break;
56
- neon_store_reg(rn, n, tmp2);
173
- case MO_UW:
57
- }
174
- tcg_gen_ld16u_i32(var, cpu_env, offset);
58
- neon_store_reg(rn, n, tmp);
175
- break;
59
+ int vec_size = pass ? 16 : 8;
176
- case MO_UL:
60
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
177
- tcg_gen_ld_i32(var, cpu_env, offset);
61
+ vec_size, vec_size, tmp);
178
- break;
62
+ tcg_temp_free_i32(tmp);
179
- default:
63
} else {
180
- g_assert_not_reached();
64
/* VMOV */
181
- }
65
switch (size) {
182
-}
66
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
183
-
67
tcg_temp_free_i32(tmp);
184
-static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
68
} else if ((insn & 0x380) == 0) {
185
-{
69
/* VDUP */
186
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
70
+ int element;
187
-
71
+ TCGMemOp size;
188
- switch (mop) {
72
+
189
- case MO_UB:
73
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
190
- tcg_gen_ld8u_i64(var, cpu_env, offset);
74
return 1;
191
- break;
75
}
192
- case MO_UW:
76
- if (insn & (1 << 19)) {
193
- tcg_gen_ld16u_i64(var, cpu_env, offset);
77
- tmp = neon_load_reg(rm, 1);
194
- break;
78
- } else {
195
- case MO_UL:
79
- tmp = neon_load_reg(rm, 0);
196
- tcg_gen_ld32u_i64(var, cpu_env, offset);
80
- }
197
- break;
81
if (insn & (1 << 16)) {
198
- case MO_Q:
82
- gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
199
- tcg_gen_ld_i64(var, cpu_env, offset);
83
+ size = MO_8;
200
- break;
84
+ element = (insn >> 17) & 7;
201
- default:
85
} else if (insn & (1 << 17)) {
202
- g_assert_not_reached();
86
- if ((insn >> 18) & 1)
203
- }
87
- gen_neon_dup_high16(tmp);
204
-}
88
- else
205
-
89
- gen_neon_dup_low16(tmp);
206
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
90
+ size = MO_16;
207
{
91
+ element = (insn >> 18) & 3;
208
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
92
+ } else {
209
tcg_temp_free_i32(var);
93
+ size = MO_32;
210
}
94
+ element = (insn >> 19) & 1;
211
95
}
212
-static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
96
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
213
-{
97
- tmp2 = tcg_temp_new_i32();
214
- long offset = neon_element_offset(reg, ele, size);
98
- tcg_gen_mov_i32(tmp2, tmp);
215
-
99
- neon_store_reg(rd, pass, tmp2);
216
- switch (size) {
100
- }
217
- case MO_8:
101
- tcg_temp_free_i32(tmp);
218
- tcg_gen_st8_i32(var, cpu_env, offset);
102
+ tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
219
- break;
103
+ neon_element_offset(rm, element, size),
220
- case MO_16:
104
+ q ? 16 : 8, q ? 16 : 8);
221
- tcg_gen_st16_i32(var, cpu_env, offset);
105
} else {
222
- break;
106
return 1;
223
- case MO_32:
107
}
224
- tcg_gen_st_i32(var, cpu_env, offset);
225
- break;
226
- default:
227
- g_assert_not_reached();
228
- }
229
-}
230
-
231
-static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
232
-{
233
- long offset = neon_element_offset(reg, ele, size);
234
-
235
- switch (size) {
236
- case MO_8:
237
- tcg_gen_st8_i64(var, cpu_env, offset);
238
- break;
239
- case MO_16:
240
- tcg_gen_st16_i64(var, cpu_env, offset);
241
- break;
242
- case MO_32:
243
- tcg_gen_st32_i64(var, cpu_env, offset);
244
- break;
245
- case MO_64:
246
- tcg_gen_st_i64(var, cpu_env, offset);
247
- break;
248
- default:
249
- g_assert_not_reached();
250
- }
251
-}
252
-
253
static inline void neon_load_reg64(TCGv_i64 var, int reg)
254
{
255
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
108
--
256
--
109
2.19.1
257
2.20.1
110
258
111
259
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Since commit ba3e7926691ed3 it has been unnecessary for target code
2
to call gen_io_end() after an IO instruction in icount mode; it is
3
sufficient to call gen_io_start() before it and to force the end of
4
the TB.
2
5
3
Both arm and thumb2 division are controlled by the same ISAR field,
6
Many now-unnecessary calls to gen_io_end() were removed in commit
4
which takes care of the arm implies thumb case. Having M imply
7
9e9b10c6491153b, but some were missed or accidentally added later.
5
thumb2 division was wrong for cortex-m0, which is v6m and does not
8
Remove unneeded calls from the arm target:
6
have thumb2 at all, much less thumb2 division.
7
9
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
* the call in the handling of exception-return-via-LDM is
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
unnecessary, and the code is already forcing end-of-TB
10
Message-id: 20181016223115.24100-5-richard.henderson@linaro.org
12
* the call in the VFP access check code is more complicated:
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
we weren't ending the TB, so we need to add the code to
14
force that by setting DISAS_UPDATE
15
* the doc comment for ARM_CP_IO doesn't need to mention
16
gen_io_end() any more
17
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
22
Message-id: 20200619170324.12093-1-peter.maydell@linaro.org
13
---
23
---
14
target/arm/cpu.h | 12 ++++++++++--
24
target/arm/cpu.h | 2 +-
15
linux-user/elfload.c | 4 ++--
25
target/arm/translate-vfp.inc.c | 7 +++----
16
target/arm/cpu.c | 10 +---------
26
target/arm/translate.c | 3 ---
17
target/arm/translate.c | 4 ++--
27
3 files changed, 4 insertions(+), 8 deletions(-)
18
4 files changed, 15 insertions(+), 15 deletions(-)
19
28
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
31
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
33
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
25
ARM_FEATURE_VFP3,
34
* migration or KVM state synchronization. (Typically this is for "registers"
26
ARM_FEATURE_VFP_FP16,
35
* which are actually used as instructions for cache maintenance and so on.)
27
ARM_FEATURE_NEON,
36
* IO indicates that this register does I/O and therefore its accesses
28
- ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
37
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
29
ARM_FEATURE_M, /* Microcontroller profile. */
38
+ * need to be marked with gen_io_start() and also end the TB. In particular,
30
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
39
* registers which implement clocks or timers require this.
31
ARM_FEATURE_THUMB2EE,
40
* RAISES_EXC is for when the read or write hook might raise an exception;
32
@@ -XXX,XX +XXX,XX @@ enum arm_features {
41
* the generated code will synchronize the CPU state before calling the hook
33
ARM_FEATURE_V5,
42
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
34
ARM_FEATURE_STRONGARM,
35
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
36
- ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
37
ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
38
ARM_FEATURE_GENERIC_TIMER,
39
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
40
@@ -XXX,XX +XXX,XX @@ extern const uint64_t pred_esz_masks[4];
41
/*
42
* 32-bit feature tests via id registers.
43
*/
44
+static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
45
+{
46
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
47
+}
48
+
49
+static inline bool isar_feature_arm_div(const ARMISARegisters *id)
50
+{
51
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
52
+}
53
+
54
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
55
{
56
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
57
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
58
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
59
--- a/linux-user/elfload.c
44
--- a/target/arm/translate-vfp.inc.c
60
+++ b/linux-user/elfload.c
45
+++ b/target/arm/translate-vfp.inc.c
61
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
46
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
62
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
47
if (s->v7m_lspact) {
63
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
48
/*
64
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
49
* Lazy state saving affects external memory and also the NVIC,
65
- GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
50
- * so we must mark it as an IO operation for icount.
66
- GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
51
+ * so we must mark it as an IO operation for icount (and cause
67
+ GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
52
+ * this to be the last insn in the TB).
68
+ GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
53
*/
69
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
54
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
70
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
55
+ s->base.is_jmp = DISAS_UPDATE;
71
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
56
gen_io_start();
72
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
57
}
73
index XXXXXXX..XXXXXXX 100644
58
gen_helper_v7m_preserve_fp_state(cpu_env);
74
--- a/target/arm/cpu.c
59
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
75
+++ b/target/arm/cpu.c
60
- gen_io_end();
76
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
61
- }
77
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
62
/*
78
* Security Extensions is ARM_FEATURE_EL3.
63
* If the preserve_fp_state helper doesn't throw an exception
79
*/
64
* then it will clear LSPACT; we don't need to repeat this for
80
- set_feature(env, ARM_FEATURE_ARM_DIV);
81
+ assert(cpu_isar_feature(arm_div, cpu));
82
set_feature(env, ARM_FEATURE_LPAE);
83
set_feature(env, ARM_FEATURE_V7);
84
}
85
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
86
if (arm_feature(env, ARM_FEATURE_V5)) {
87
set_feature(env, ARM_FEATURE_V4T);
88
}
89
- if (arm_feature(env, ARM_FEATURE_M)) {
90
- set_feature(env, ARM_FEATURE_THUMB_DIV);
91
- }
92
- if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
93
- set_feature(env, ARM_FEATURE_THUMB_DIV);
94
- }
95
if (arm_feature(env, ARM_FEATURE_VFP4)) {
96
set_feature(env, ARM_FEATURE_VFP3);
97
set_feature(env, ARM_FEATURE_VFP_FP16);
98
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
99
ARMCPU *cpu = ARM_CPU(obj);
100
101
set_feature(&cpu->env, ARM_FEATURE_V7);
102
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
103
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
104
set_feature(&cpu->env, ARM_FEATURE_V7MP);
105
set_feature(&cpu->env, ARM_FEATURE_PMSA);
106
cpu->midr = 0x411fc153; /* r1p3 */
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
67
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
68
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
69
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
112
case 1:
70
gen_io_start();
113
case 3:
71
}
114
/* SDIV, UDIV */
72
gen_helper_cpsr_write_eret(cpu_env, tmp);
115
- if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
73
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
116
+ if (!dc_isar_feature(arm_div, s)) {
74
- gen_io_end();
117
goto illegal_op;
75
- }
118
}
76
tcg_temp_free_i32(tmp);
119
if (((insn >> 5) & 7) || (rd != 15)) {
77
/* Must exit loop to check un-masked IRQs */
120
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
78
s->base.is_jmp = DISAS_EXIT;
121
tmp2 = load_reg(s, rm);
122
if ((op & 0x50) == 0x10) {
123
/* sdiv, udiv */
124
- if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
125
+ if (!dc_isar_feature(thumb_div, s)) {
126
goto illegal_op;
127
}
128
if (op & 0x20)
129
--
79
--
130
2.19.1
80
2.20.1
131
81
132
82
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In commit cfdb2c0c95ae9205b0 ("target/arm: Vectorize SABA/UABA") we
2
replaced the old handling of SABA/UABA with a vectorized implementation
3
which returns early rather than falling into the loop-ever-elements
4
code. We forgot to delete the part of the old looping code that
5
did the accumulate step, and Coverity correctly warns (CID 1428955)
6
that this code is now dead. Delete it.
2
7
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Fixes: cfdb2c0c95ae9205b0
4
Message-id: 20181011205206.3552-4-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200619171547.29780-1-peter.maydell@linaro.org
7
---
13
---
8
target/arm/translate-a64.c | 28 +++-------------------------
14
target/arm/translate-a64.c | 12 ------------
9
1 file changed, 3 insertions(+), 25 deletions(-)
15
1 file changed, 12 deletions(-)
10
16
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
19
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
20
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
16
for (xs = 0; xs < selem; xs++) {
22
genfn(tcg_res, tcg_op1, tcg_op2);
17
if (replicate) {
23
}
18
/* Load and replicate to all elements */
24
19
- uint64_t mulconst;
25
- if (opcode == 0xf) {
20
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
26
- /* SABA, UABA: accumulating ops */
21
27
- static NeonGenTwoOpFn * const fns[3] = {
22
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
28
- gen_helper_neon_add_u8,
23
get_mem_index(s), s->be_data + scale);
29
- gen_helper_neon_add_u16,
24
- switch (scale) {
30
- tcg_gen_add_i32,
25
- case 0:
31
- };
26
- mulconst = 0x0101010101010101ULL;
32
-
27
- break;
33
- read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
28
- case 1:
34
- fns[size](tcg_res, tcg_op1, tcg_res);
29
- mulconst = 0x0001000100010001ULL;
30
- break;
31
- case 2:
32
- mulconst = 0x0000000100000001ULL;
33
- break;
34
- case 3:
35
- mulconst = 0;
36
- break;
37
- default:
38
- g_assert_not_reached();
39
- }
35
- }
40
- if (mulconst) {
36
-
41
- tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
37
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
42
- }
38
43
- write_vec_element(s, tcg_tmp, rt, 0, MO_64);
39
tcg_temp_free_i32(tcg_res);
44
- if (is_q) {
45
- write_vec_element(s, tcg_tmp, rt, 1, MO_64);
46
- }
47
+ tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
48
+ (is_q + 1) * 8, vec_full_reg_size(s),
49
+ tcg_tmp);
50
tcg_temp_free_i64(tcg_tmp);
51
- clear_vec_high(s, is_q, rt);
52
} else {
53
/* Load/store one element per register */
54
if (is_load) {
55
--
40
--
56
2.19.1
41
2.20.1
57
42
58
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The EL3 version of this register does not include an ASID,
3
Add a trace event to see when a guest disable/enable the watchdog.
4
and so the tlb_flush performed by vmsa_ttbr_write is not needed.
5
4
6
Reviewed-by: Aaron Lindsay <aaron@os.amperecomputing.com>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200617072539.32686-2-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20181019015617.22583-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/helper.c | 2 +-
10
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
hw/watchdog/trace-events | 1 +
12
2 files changed, 2 insertions(+)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
18
+++ b/target/arm/helper.c
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
20
.fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
19
break;
21
{ .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
20
case A_WDOGLOCK:
22
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
21
s->lock = (value != WDOG_UNLOCK_VALUE);
23
- .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
22
+ trace_cmsdk_apb_watchdog_lock(s->lock);
24
+ .access = PL3_RW, .resetvalue = 0,
23
break;
25
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
24
case A_WDOGITCR:
26
{ .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
25
if (s->is_luminary) {
27
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
26
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/watchdog/trace-events
29
+++ b/hw/watchdog/trace-events
30
@@ -XXX,XX +XXX,XX @@
31
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
32
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
33
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
34
+cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
28
--
35
--
29
2.19.1
36
2.20.1
30
37
31
38
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
For a sequence of loads or stores from a single register,
3
Use self-explicit definitions instead of magic values.
4
little-endian operations can be promoted to an 8-byte op.
5
This can reduce the number of operations by a factor of 8.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20181011205206.3552-20-richard.henderson@linaro.org
6
Message-id: 20200617072539.32686-3-f4bug@amsat.org
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
target/arm/translate.c | 10 ++++++++++
10
hw/i2c/versatile_i2c.c | 14 ++++++++++----
14
1 file changed, 10 insertions(+)
11
1 file changed, 10 insertions(+), 4 deletions(-)
15
12
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
15
--- a/hw/i2c/versatile_i2c.c
19
+++ b/target/arm/translate.c
16
+++ b/hw/i2c/versatile_i2c.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@
21
if (size == 3 && (interleave | spacing) != 1) {
18
#include "qemu/osdep.h"
22
return 1;
19
#include "hw/sysbus.h"
23
}
20
#include "hw/i2c/bitbang_i2c.h"
24
+ /* For our purposes, bytes are always little-endian. */
21
+#include "hw/registerfields.h"
25
+ if (size == 0) {
22
#include "qemu/log.h"
26
+ endian = MO_LE;
23
#include "qemu/module.h"
27
+ }
24
28
+ /* Consecutive little-endian elements from a single register
25
@@ -XXX,XX +XXX,XX @@ typedef struct VersatileI2CState {
29
+ * can be promoted to a larger little-endian operation.
26
int in;
30
+ */
27
} VersatileI2CState;
31
+ if (interleave == 1 && endian == MO_LE) {
28
32
+ size = 3;
29
+REG32(CONTROL_GET, 0)
33
+ }
30
+REG32(CONTROL_SET, 0)
34
tmp64 = tcg_temp_new_i64();
31
+REG32(CONTROL_CLR, 4)
35
addr = tcg_temp_new_i32();
32
+
36
tmp2 = tcg_const_i32(1 << size);
33
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
34
unsigned size)
35
{
36
VersatileI2CState *s = (VersatileI2CState *)opaque;
37
38
- if (offset == 0) {
39
+ switch (offset) {
40
+ case A_CONTROL_SET:
41
return (s->out & 1) | (s->in << 1);
42
- } else {
43
+ default:
44
qemu_log_mask(LOG_GUEST_ERROR,
45
"%s: Bad offset 0x%x\n", __func__, (int)offset);
46
return -1;
47
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
48
VersatileI2CState *s = (VersatileI2CState *)opaque;
49
50
switch (offset) {
51
- case 0:
52
+ case A_CONTROL_SET:
53
s->out |= value & 3;
54
break;
55
- case 4:
56
+ case A_CONTROL_CLR:
57
s->out &= ~value;
58
break;
59
default:
37
--
60
--
38
2.19.1
61
2.20.1
39
62
40
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This is done generically in translator_loop.
3
Use self-explicit definitions instead of magic values.
4
4
5
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200617072539.32686-4-f4bug@amsat.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20181011205206.3552-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/translate-a64.c | 1 -
10
hw/i2c/versatile_i2c.c | 7 +++++--
13
target/arm/translate.c | 1 -
11
1 file changed, 5 insertions(+), 2 deletions(-)
14
2 files changed, 2 deletions(-)
15
12
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
15
--- a/hw/i2c/versatile_i2c.c
19
+++ b/target/arm/translate-a64.c
16
+++ b/hw/i2c/versatile_i2c.c
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
17
@@ -XXX,XX +XXX,XX @@ REG32(CONTROL_GET, 0)
21
18
REG32(CONTROL_SET, 0)
22
static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
19
REG32(CONTROL_CLR, 4)
20
21
+#define SCL BIT(0)
22
+#define SDA BIT(1)
23
+
24
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
25
unsigned size)
23
{
26
{
24
- tcg_clear_temp_count();
27
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
28
qemu_log_mask(LOG_GUEST_ERROR,
29
"%s: Bad offset 0x%x\n", __func__, (int)offset);
30
}
31
- bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
32
- s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
33
+ bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
34
+ s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
25
}
35
}
26
36
27
static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
37
static const MemoryRegionOps versatile_i2c_ops = {
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.c
31
+++ b/target/arm/translate.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
33
tcg_gen_movi_i32(tmp, 0);
34
store_cpu_field(tmp, condexec_bits);
35
}
36
- tcg_clear_temp_count();
37
}
38
39
static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
40
--
38
--
41
2.19.1
39
2.20.1
42
40
43
41
diff view generated by jsdifflib
1
From: Richard Henderson <rth@twiddle.net>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This can reduce the number of opcodes required for certain
3
'ARM SBCon two-wire serial bus interface' is the official
4
complex forms of load-multiple (e.g. ld4.16b).
4
name describing the pair of registers used to bitbanging
5
I2C in the Versatile boards.
5
6
6
Signed-off-by: Richard Henderson <rth@twiddle.net>
7
Make the private VersatileI2CState structure as public
7
Message-id: 20181011205206.3552-2-richard.henderson@linaro.org
8
ArmSbconI2CState.
9
Add the TYPE_ARM_SBCON_I2C, alias to our current
10
TYPE_VERSATILE_I2C model.
11
Rename the memory region description as 'arm_sbcon_i2c'.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-5-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/translate-a64.c | 12 ++++++++----
18
include/hw/i2c/arm_sbcon_i2c.h | 35 ++++++++++++++++++++++++++++++++++
12
1 file changed, 8 insertions(+), 4 deletions(-)
19
hw/i2c/versatile_i2c.c | 17 +++++------------
20
MAINTAINERS | 1 +
21
3 files changed, 41 insertions(+), 12 deletions(-)
22
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
13
23
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
diff --git a/include/hw/i2c/arm_sbcon_i2c.h b/include/hw/i2c/arm_sbcon_i2c.h
25
new file mode 100644
26
index XXXXXXX..XXXXXXX
27
--- /dev/null
28
+++ b/include/hw/i2c/arm_sbcon_i2c.h
29
@@ -XXX,XX +XXX,XX @@
30
+/*
31
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
32
+ * a.k.a.
33
+ * ARM Versatile I2C controller
34
+ *
35
+ * Copyright (c) 2006-2007 CodeSourcery.
36
+ * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
37
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
38
+ *
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
+ */
41
+#ifndef HW_I2C_ARM_SBCON_H
42
+#define HW_I2C_ARM_SBCON_H
43
+
44
+#include "hw/sysbus.h"
45
+#include "hw/i2c/bitbang_i2c.h"
46
+
47
+#define TYPE_VERSATILE_I2C "versatile_i2c"
48
+#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
49
+
50
+#define ARM_SBCON_I2C(obj) \
51
+ OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
52
+
53
+typedef struct ArmSbconI2CState {
54
+ /*< private >*/
55
+ SysBusDevice parent_obj;
56
+ /*< public >*/
57
+
58
+ MemoryRegion iomem;
59
+ bitbang_i2c_interface bitbang;
60
+ int out;
61
+ int in;
62
+} ArmSbconI2CState;
63
+
64
+#endif /* HW_I2C_ARM_SBCON_H */
65
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
15
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
67
--- a/hw/i2c/versatile_i2c.c
17
+++ b/target/arm/translate-a64.c
68
+++ b/hw/i2c/versatile_i2c.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
69
@@ -XXX,XX +XXX,XX @@
19
bool is_store = !extract32(insn, 22, 1);
70
/*
20
bool is_postidx = extract32(insn, 23, 1);
71
- * ARM Versatile I2C controller
21
bool is_q = extract32(insn, 30, 1);
72
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
22
- TCGv_i64 tcg_addr, tcg_rn;
73
+ * a.k.a. ARM Versatile I2C controller
23
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
74
*
24
75
* Copyright (c) 2006-2007 CodeSourcery.
25
int ebytes = 1 << size;
76
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
26
int elements = (is_q ? 128 : 64) / (8 << size);
77
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
78
*/
28
tcg_rn = cpu_reg_sp(s, rn);
79
29
tcg_addr = tcg_temp_new_i64();
80
#include "qemu/osdep.h"
30
tcg_gen_mov_i64(tcg_addr, tcg_rn);
81
-#include "hw/sysbus.h"
31
+ tcg_ebytes = tcg_const_i64(ebytes);
82
-#include "hw/i2c/bitbang_i2c.h"
32
83
+#include "hw/i2c/arm_sbcon_i2c.h"
33
for (r = 0; r < rpt; r++) {
84
#include "hw/registerfields.h"
34
int e;
85
#include "qemu/log.h"
35
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
86
#include "qemu/module.h"
36
clear_vec_high(s, is_q, tt);
87
37
}
88
-#define TYPE_VERSATILE_I2C "versatile_i2c"
38
}
89
#define VERSATILE_I2C(obj) \
39
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
90
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
40
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
91
41
tt = (tt + 1) % 32;
92
-typedef struct VersatileI2CState {
42
}
93
- SysBusDevice parent_obj;
43
}
94
+typedef ArmSbconI2CState VersatileI2CState;
44
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
95
45
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
96
- MemoryRegion iomem;
46
}
97
- bitbang_i2c_interface bitbang;
47
}
98
- int out;
48
+ tcg_temp_free_i64(tcg_ebytes);
99
- int in;
49
tcg_temp_free_i64(tcg_addr);
100
-} VersatileI2CState;
101
102
REG32(CONTROL_GET, 0)
103
REG32(CONTROL_SET, 0)
104
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_init(Object *obj)
105
bus = i2c_init_bus(dev, "i2c");
106
bitbang_i2c_init(&s->bitbang, bus);
107
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
108
- "versatile_i2c", 0x1000);
109
+ "arm_sbcon_i2c", 0x1000);
110
sysbus_init_mmio(sbd, &s->iomem);
50
}
111
}
51
112
52
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
113
diff --git a/MAINTAINERS b/MAINTAINERS
53
bool replicate = false;
114
index XXXXXXX..XXXXXXX 100644
54
int index = is_q << 3 | S << 2 | size;
115
--- a/MAINTAINERS
55
int ebytes, xs;
116
+++ b/MAINTAINERS
56
- TCGv_i64 tcg_addr, tcg_rn;
117
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
57
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
118
L: qemu-arm@nongnu.org
58
119
S: Maintained
59
switch (scale) {
120
F: hw/*/versatile*
60
case 3:
121
+F: include/hw/i2c/arm_sbcon_i2c.h
61
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
122
F: hw/misc/arm_sysctl.c
62
tcg_rn = cpu_reg_sp(s, rn);
123
F: docs/system/arm/versatile.rst
63
tcg_addr = tcg_temp_new_i64();
64
tcg_gen_mov_i64(tcg_addr, tcg_rn);
65
+ tcg_ebytes = tcg_const_i64(ebytes);
66
67
for (xs = 0; xs < selem; xs++) {
68
if (replicate) {
69
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
70
do_vec_st(s, rt, index, tcg_addr, scale);
71
}
72
}
73
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
74
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
75
rt = (rt + 1) % 32;
76
}
77
78
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
79
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
80
}
81
}
82
+ tcg_temp_free_i64(tcg_ebytes);
83
tcg_temp_free_i64(tcg_addr);
84
}
85
124
86
--
125
--
87
2.19.1
126
2.20.1
88
127
89
128
diff view generated by jsdifflib
1
From: Stewart Hildebrand <Stewart.Hildebrand@dornerworks.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
"The Image must be placed text_offset bytes from a 2MB aligned base
3
By using the TYPE_* definitions for devices, we can:
4
address anywhere in usable system RAM and called there."
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
5
6
6
For the virt board, we write our startup bootloader at the very
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
bottom of RAM, so that bit can't be used for the image. To avoid
8
Message-id: 20200617072539.32686-6-f4bug@amsat.org
8
overlap in case the image requests to be loaded at an offset
9
smaller than our bootloader, we increment the load offset to the
10
next 2MB.
11
12
This fixes a boot failure for Xen AArch64.
13
14
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@dornerworks.com>
15
Tested-by: Andre Przywara <andre.przywara@arm.com>
16
Message-id: b8a89518794b4436af0c151ed10de4fa@dornerworks.com
17
[PMM: Rephrased a comment a bit]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
11
---
21
hw/arm/boot.c | 18 ++++++++++++++++++
12
hw/arm/realview.c | 3 ++-
22
1 file changed, 18 insertions(+)
13
hw/arm/versatilepb.c | 3 ++-
14
hw/arm/vexpress.c | 3 ++-
15
3 files changed, 6 insertions(+), 3 deletions(-)
23
16
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
17
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/boot.c
19
--- a/hw/arm/realview.c
27
+++ b/hw/arm/boot.c
20
+++ b/hw/arm/realview.c
28
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
29
#include "qemu/config-file.h"
22
#include "hw/cpu/a9mpcore.h"
30
#include "qemu/option.h"
23
#include "hw/intc/realview_gic.h"
31
#include "exec/address-spaces.h"
24
#include "hw/irq.h"
32
+#include "qemu/units.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
33
26
34
/* Kernel boot protocol is specified in the kernel docs
27
#define SMP_BOOT_ADDR 0xe0000000
35
* Documentation/arm/Booting and Documentation/arm64/booting.txt
28
#define SMP_BOOTREG_ADDR 0x10000030
36
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
37
#define ARM64_TEXT_OFFSET_OFFSET 8
38
#define ARM64_MAGIC_OFFSET 56
39
40
+#define BOOTLOADER_MAX_SIZE (4 * KiB)
41
+
42
AddressSpace *arm_boot_address_space(ARMCPU *cpu,
43
const struct arm_boot_info *info)
44
{
45
@@ -XXX,XX +XXX,XX @@ static void write_bootloader(const char *name, hwaddr addr,
46
code[i] = tswap32(insn);
47
}
48
49
+ assert((len * sizeof(uint32_t)) < BOOTLOADER_MAX_SIZE);
50
+
51
rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as);
52
53
g_free(code);
54
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
55
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
56
if (hdrvals[1] != 0) {
57
kernel_load_offset = le64_to_cpu(hdrvals[0]);
58
+
59
+ /*
60
+ * We write our startup "bootloader" at the very bottom of RAM,
61
+ * so that bit can't be used for the image. Luckily the Image
62
+ * format specification is that the image requests only an offset
63
+ * from a 2MB boundary, not an absolute load address. So if the
64
+ * image requests an offset that might mean it overlaps with the
65
+ * bootloader, we can just load it starting at 2MB+offset rather
66
+ * than 0MB + offset.
67
+ */
68
+ if (kernel_load_offset < BOOTLOADER_MAX_SIZE) {
69
+ kernel_load_offset += 2 * MiB;
70
+ }
71
}
30
}
72
}
31
}
73
32
33
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
34
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
35
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
36
i2c_create_slave(i2c, "ds1338", 0x68);
37
38
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/versatilepb.c
41
+++ b/hw/arm/versatilepb.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "sysemu/sysemu.h"
44
#include "hw/pci/pci.h"
45
#include "hw/i2c/i2c.h"
46
+#include "hw/i2c/arm_sbcon_i2c.h"
47
#include "hw/irq.h"
48
#include "hw/boards.h"
49
#include "exec/address-spaces.h"
50
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
51
/* Add PL031 Real Time Clock. */
52
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
53
54
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
55
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
56
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
57
i2c_create_slave(i2c, "ds1338", 0x68);
58
59
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/vexpress.c
62
+++ b/hw/arm/vexpress.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/char/pl011.h"
65
#include "hw/cpu/a9mpcore.h"
66
#include "hw/cpu/a15mpcore.h"
67
+#include "hw/i2c/arm_sbcon_i2c.h"
68
69
#define VEXPRESS_BOARD_ID 0x8e0
70
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
71
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
72
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
73
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
74
75
- dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
76
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, map[VE_SERIALDVI], NULL);
77
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
78
i2c_create_slave(i2c, "sii9022", 0x39);
79
74
--
80
--
75
2.19.1
81
2.20.1
76
82
77
83
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Create struct ARMISARegisters, to be accessed during translation.
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
4
Message-id: 20200617072539.32686-7-f4bug@amsat.org
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181016223115.24100-2-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
target/arm/cpu.h | 32 ++++----
8
hw/arm/mps2.c | 5 ++++-
11
hw/intc/armv7m_nvic.c | 12 +--
9
1 file changed, 4 insertions(+), 1 deletion(-)
12
target/arm/cpu.c | 178 +++++++++++++++++++++---------------------
13
target/arm/cpu64.c | 70 ++++++++---------
14
target/arm/helper.c | 28 +++----
15
5 files changed, 162 insertions(+), 158 deletions(-)
16
10
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
13
--- a/hw/arm/mps2.c
20
+++ b/target/arm/cpu.h
14
+++ b/hw/arm/mps2.c
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
* ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
16
MemoryRegion blockram_m2;
23
* is used for reset values of non-constant registers; no reset_
17
MemoryRegion blockram_m3;
24
* prefix means a constant register.
18
MemoryRegion sram;
25
+ * Some of these registers are split out into a substructure that
19
+ /* FPGA APB subsystem */
26
+ * is shared with the translators to control the ISA.
20
MPS2SCC scc;
27
*/
21
+ /* CMSDK APB subsystem */
28
+ struct ARMISARegisters {
22
CMSDKAPBDualTimer dualtimer;
29
+ uint32_t id_isar0;
23
} MPS2MachineState;
30
+ uint32_t id_isar1;
24
31
+ uint32_t id_isar2;
25
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
32
+ uint32_t id_isar3;
26
g_assert_not_reached();
33
+ uint32_t id_isar4;
34
+ uint32_t id_isar5;
35
+ uint32_t id_isar6;
36
+ uint32_t mvfr0;
37
+ uint32_t mvfr1;
38
+ uint32_t mvfr2;
39
+ uint64_t id_aa64isar0;
40
+ uint64_t id_aa64isar1;
41
+ uint64_t id_aa64pfr0;
42
+ uint64_t id_aa64pfr1;
43
+ } isar;
44
uint32_t midr;
45
uint32_t revidr;
46
uint32_t reset_fpsid;
47
- uint32_t mvfr0;
48
- uint32_t mvfr1;
49
- uint32_t mvfr2;
50
uint32_t ctr;
51
uint32_t reset_sctlr;
52
uint32_t id_pfr0;
53
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
54
uint32_t id_mmfr2;
55
uint32_t id_mmfr3;
56
uint32_t id_mmfr4;
57
- uint32_t id_isar0;
58
- uint32_t id_isar1;
59
- uint32_t id_isar2;
60
- uint32_t id_isar3;
61
- uint32_t id_isar4;
62
- uint32_t id_isar5;
63
- uint32_t id_isar6;
64
- uint64_t id_aa64pfr0;
65
- uint64_t id_aa64pfr1;
66
uint64_t id_aa64dfr0;
67
uint64_t id_aa64dfr1;
68
uint64_t id_aa64afr0;
69
uint64_t id_aa64afr1;
70
- uint64_t id_aa64isar0;
71
- uint64_t id_aa64isar1;
72
uint64_t id_aa64mmfr0;
73
uint64_t id_aa64mmfr1;
74
uint32_t dbgdidr;
75
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/intc/armv7m_nvic.c
78
+++ b/hw/intc/armv7m_nvic.c
79
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
80
case 0xd5c: /* MMFR3. */
81
return cpu->id_mmfr3;
82
case 0xd60: /* ISAR0. */
83
- return cpu->id_isar0;
84
+ return cpu->isar.id_isar0;
85
case 0xd64: /* ISAR1. */
86
- return cpu->id_isar1;
87
+ return cpu->isar.id_isar1;
88
case 0xd68: /* ISAR2. */
89
- return cpu->id_isar2;
90
+ return cpu->isar.id_isar2;
91
case 0xd6c: /* ISAR3. */
92
- return cpu->id_isar3;
93
+ return cpu->isar.id_isar3;
94
case 0xd70: /* ISAR4. */
95
- return cpu->id_isar4;
96
+ return cpu->isar.id_isar4;
97
case 0xd74: /* ISAR5. */
98
- return cpu->id_isar5;
99
+ return cpu->isar.id_isar5;
100
case 0xd78: /* CLIDR */
101
return cpu->clidr;
102
case 0xd7c: /* CTR */
103
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/cpu.c
106
+++ b/target/arm/cpu.c
107
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
108
g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu);
109
110
env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
111
- env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
112
- env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
113
- env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;
114
+ env->vfp.xregs[ARM_VFP_MVFR0] = cpu->isar.mvfr0;
115
+ env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1;
116
+ env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2;
117
118
cpu->power_state = cpu->start_powered_off ? PSCI_OFF : PSCI_ON;
119
s->halted = cpu->start_powered_off;
120
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
121
* registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].
122
*/
123
cpu->id_pfr1 &= ~0xf0;
124
- cpu->id_aa64pfr0 &= ~0xf000;
125
+ cpu->isar.id_aa64pfr0 &= ~0xf000;
126
}
27
}
127
28
128
if (!cpu->has_el2) {
29
+ /* CMSDK APB subsystem */
129
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
30
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
130
* registers if we don't have EL2. These are id_pfr1[15:12] and
31
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
131
* id_aa64pfr0_el1[11:8].
32
-
132
*/
33
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
133
- cpu->id_aa64pfr0 &= ~0xf00;
34
TYPE_CMSDK_APB_DUALTIMER);
134
+ cpu->isar.id_aa64pfr0 &= ~0xf00;
35
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
135
cpu->id_pfr1 &= ~0xf000;
36
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
136
}
37
qdev_get_gpio_in(armv7m, 10));
137
38
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
138
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
39
139
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
40
+ /* FPGA APB subsystem */
140
cpu->midr = 0x4107b362;
41
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
141
cpu->reset_fpsid = 0x410120b4;
42
sccdev = DEVICE(&mms->scc);
142
- cpu->mvfr0 = 0x11111111;
43
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
143
- cpu->mvfr1 = 0x00000000;
144
+ cpu->isar.mvfr0 = 0x11111111;
145
+ cpu->isar.mvfr1 = 0x00000000;
146
cpu->ctr = 0x1dd20d2;
147
cpu->reset_sctlr = 0x00050078;
148
cpu->id_pfr0 = 0x111;
149
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
150
cpu->id_mmfr0 = 0x01130003;
151
cpu->id_mmfr1 = 0x10030302;
152
cpu->id_mmfr2 = 0x01222110;
153
- cpu->id_isar0 = 0x00140011;
154
- cpu->id_isar1 = 0x12002111;
155
- cpu->id_isar2 = 0x11231111;
156
- cpu->id_isar3 = 0x01102131;
157
- cpu->id_isar4 = 0x141;
158
+ cpu->isar.id_isar0 = 0x00140011;
159
+ cpu->isar.id_isar1 = 0x12002111;
160
+ cpu->isar.id_isar2 = 0x11231111;
161
+ cpu->isar.id_isar3 = 0x01102131;
162
+ cpu->isar.id_isar4 = 0x141;
163
cpu->reset_auxcr = 7;
164
}
165
166
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
167
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
168
cpu->midr = 0x4117b363;
169
cpu->reset_fpsid = 0x410120b4;
170
- cpu->mvfr0 = 0x11111111;
171
- cpu->mvfr1 = 0x00000000;
172
+ cpu->isar.mvfr0 = 0x11111111;
173
+ cpu->isar.mvfr1 = 0x00000000;
174
cpu->ctr = 0x1dd20d2;
175
cpu->reset_sctlr = 0x00050078;
176
cpu->id_pfr0 = 0x111;
177
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
178
cpu->id_mmfr0 = 0x01130003;
179
cpu->id_mmfr1 = 0x10030302;
180
cpu->id_mmfr2 = 0x01222110;
181
- cpu->id_isar0 = 0x00140011;
182
- cpu->id_isar1 = 0x12002111;
183
- cpu->id_isar2 = 0x11231111;
184
- cpu->id_isar3 = 0x01102131;
185
- cpu->id_isar4 = 0x141;
186
+ cpu->isar.id_isar0 = 0x00140011;
187
+ cpu->isar.id_isar1 = 0x12002111;
188
+ cpu->isar.id_isar2 = 0x11231111;
189
+ cpu->isar.id_isar3 = 0x01102131;
190
+ cpu->isar.id_isar4 = 0x141;
191
cpu->reset_auxcr = 7;
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
195
set_feature(&cpu->env, ARM_FEATURE_EL3);
196
cpu->midr = 0x410fb767;
197
cpu->reset_fpsid = 0x410120b5;
198
- cpu->mvfr0 = 0x11111111;
199
- cpu->mvfr1 = 0x00000000;
200
+ cpu->isar.mvfr0 = 0x11111111;
201
+ cpu->isar.mvfr1 = 0x00000000;
202
cpu->ctr = 0x1dd20d2;
203
cpu->reset_sctlr = 0x00050078;
204
cpu->id_pfr0 = 0x111;
205
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
206
cpu->id_mmfr0 = 0x01130003;
207
cpu->id_mmfr1 = 0x10030302;
208
cpu->id_mmfr2 = 0x01222100;
209
- cpu->id_isar0 = 0x0140011;
210
- cpu->id_isar1 = 0x12002111;
211
- cpu->id_isar2 = 0x11231121;
212
- cpu->id_isar3 = 0x01102131;
213
- cpu->id_isar4 = 0x01141;
214
+ cpu->isar.id_isar0 = 0x0140011;
215
+ cpu->isar.id_isar1 = 0x12002111;
216
+ cpu->isar.id_isar2 = 0x11231121;
217
+ cpu->isar.id_isar3 = 0x01102131;
218
+ cpu->isar.id_isar4 = 0x01141;
219
cpu->reset_auxcr = 7;
220
}
221
222
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
223
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
224
cpu->midr = 0x410fb022;
225
cpu->reset_fpsid = 0x410120b4;
226
- cpu->mvfr0 = 0x11111111;
227
- cpu->mvfr1 = 0x00000000;
228
+ cpu->isar.mvfr0 = 0x11111111;
229
+ cpu->isar.mvfr1 = 0x00000000;
230
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
231
cpu->id_pfr0 = 0x111;
232
cpu->id_pfr1 = 0x1;
233
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
234
cpu->id_mmfr0 = 0x01100103;
235
cpu->id_mmfr1 = 0x10020302;
236
cpu->id_mmfr2 = 0x01222000;
237
- cpu->id_isar0 = 0x00100011;
238
- cpu->id_isar1 = 0x12002111;
239
- cpu->id_isar2 = 0x11221011;
240
- cpu->id_isar3 = 0x01102131;
241
- cpu->id_isar4 = 0x141;
242
+ cpu->isar.id_isar0 = 0x00100011;
243
+ cpu->isar.id_isar1 = 0x12002111;
244
+ cpu->isar.id_isar2 = 0x11221011;
245
+ cpu->isar.id_isar3 = 0x01102131;
246
+ cpu->isar.id_isar4 = 0x141;
247
cpu->reset_auxcr = 1;
248
}
249
250
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
251
cpu->id_mmfr1 = 0x00000000;
252
cpu->id_mmfr2 = 0x00000000;
253
cpu->id_mmfr3 = 0x00000000;
254
- cpu->id_isar0 = 0x01141110;
255
- cpu->id_isar1 = 0x02111000;
256
- cpu->id_isar2 = 0x21112231;
257
- cpu->id_isar3 = 0x01111110;
258
- cpu->id_isar4 = 0x01310102;
259
- cpu->id_isar5 = 0x00000000;
260
- cpu->id_isar6 = 0x00000000;
261
+ cpu->isar.id_isar0 = 0x01141110;
262
+ cpu->isar.id_isar1 = 0x02111000;
263
+ cpu->isar.id_isar2 = 0x21112231;
264
+ cpu->isar.id_isar3 = 0x01111110;
265
+ cpu->isar.id_isar4 = 0x01310102;
266
+ cpu->isar.id_isar5 = 0x00000000;
267
+ cpu->isar.id_isar6 = 0x00000000;
268
}
269
270
static void cortex_m4_initfn(Object *obj)
271
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
272
cpu->id_mmfr1 = 0x00000000;
273
cpu->id_mmfr2 = 0x00000000;
274
cpu->id_mmfr3 = 0x00000000;
275
- cpu->id_isar0 = 0x01141110;
276
- cpu->id_isar1 = 0x02111000;
277
- cpu->id_isar2 = 0x21112231;
278
- cpu->id_isar3 = 0x01111110;
279
- cpu->id_isar4 = 0x01310102;
280
- cpu->id_isar5 = 0x00000000;
281
- cpu->id_isar6 = 0x00000000;
282
+ cpu->isar.id_isar0 = 0x01141110;
283
+ cpu->isar.id_isar1 = 0x02111000;
284
+ cpu->isar.id_isar2 = 0x21112231;
285
+ cpu->isar.id_isar3 = 0x01111110;
286
+ cpu->isar.id_isar4 = 0x01310102;
287
+ cpu->isar.id_isar5 = 0x00000000;
288
+ cpu->isar.id_isar6 = 0x00000000;
289
}
290
291
static void cortex_m33_initfn(Object *obj)
292
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
293
cpu->id_mmfr1 = 0x00000000;
294
cpu->id_mmfr2 = 0x01000000;
295
cpu->id_mmfr3 = 0x00000000;
296
- cpu->id_isar0 = 0x01101110;
297
- cpu->id_isar1 = 0x02212000;
298
- cpu->id_isar2 = 0x20232232;
299
- cpu->id_isar3 = 0x01111131;
300
- cpu->id_isar4 = 0x01310132;
301
- cpu->id_isar5 = 0x00000000;
302
- cpu->id_isar6 = 0x00000000;
303
+ cpu->isar.id_isar0 = 0x01101110;
304
+ cpu->isar.id_isar1 = 0x02212000;
305
+ cpu->isar.id_isar2 = 0x20232232;
306
+ cpu->isar.id_isar3 = 0x01111131;
307
+ cpu->isar.id_isar4 = 0x01310132;
308
+ cpu->isar.id_isar5 = 0x00000000;
309
+ cpu->isar.id_isar6 = 0x00000000;
310
cpu->clidr = 0x00000000;
311
cpu->ctr = 0x8000c000;
312
}
313
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
314
cpu->id_mmfr1 = 0x00000000;
315
cpu->id_mmfr2 = 0x01200000;
316
cpu->id_mmfr3 = 0x0211;
317
- cpu->id_isar0 = 0x02101111;
318
- cpu->id_isar1 = 0x13112111;
319
- cpu->id_isar2 = 0x21232141;
320
- cpu->id_isar3 = 0x01112131;
321
- cpu->id_isar4 = 0x0010142;
322
- cpu->id_isar5 = 0x0;
323
- cpu->id_isar6 = 0x0;
324
+ cpu->isar.id_isar0 = 0x02101111;
325
+ cpu->isar.id_isar1 = 0x13112111;
326
+ cpu->isar.id_isar2 = 0x21232141;
327
+ cpu->isar.id_isar3 = 0x01112131;
328
+ cpu->isar.id_isar4 = 0x0010142;
329
+ cpu->isar.id_isar5 = 0x0;
330
+ cpu->isar.id_isar6 = 0x0;
331
cpu->mp_is_up = true;
332
cpu->pmsav7_dregion = 16;
333
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
334
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
335
set_feature(&cpu->env, ARM_FEATURE_EL3);
336
cpu->midr = 0x410fc080;
337
cpu->reset_fpsid = 0x410330c0;
338
- cpu->mvfr0 = 0x11110222;
339
- cpu->mvfr1 = 0x00011111;
340
+ cpu->isar.mvfr0 = 0x11110222;
341
+ cpu->isar.mvfr1 = 0x00011111;
342
cpu->ctr = 0x82048004;
343
cpu->reset_sctlr = 0x00c50078;
344
cpu->id_pfr0 = 0x1031;
345
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
346
cpu->id_mmfr1 = 0x20000000;
347
cpu->id_mmfr2 = 0x01202000;
348
cpu->id_mmfr3 = 0x11;
349
- cpu->id_isar0 = 0x00101111;
350
- cpu->id_isar1 = 0x12112111;
351
- cpu->id_isar2 = 0x21232031;
352
- cpu->id_isar3 = 0x11112131;
353
- cpu->id_isar4 = 0x00111142;
354
+ cpu->isar.id_isar0 = 0x00101111;
355
+ cpu->isar.id_isar1 = 0x12112111;
356
+ cpu->isar.id_isar2 = 0x21232031;
357
+ cpu->isar.id_isar3 = 0x11112131;
358
+ cpu->isar.id_isar4 = 0x00111142;
359
cpu->dbgdidr = 0x15141000;
360
cpu->clidr = (1 << 27) | (2 << 24) | 3;
361
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
362
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
363
set_feature(&cpu->env, ARM_FEATURE_CBAR);
364
cpu->midr = 0x410fc090;
365
cpu->reset_fpsid = 0x41033090;
366
- cpu->mvfr0 = 0x11110222;
367
- cpu->mvfr1 = 0x01111111;
368
+ cpu->isar.mvfr0 = 0x11110222;
369
+ cpu->isar.mvfr1 = 0x01111111;
370
cpu->ctr = 0x80038003;
371
cpu->reset_sctlr = 0x00c50078;
372
cpu->id_pfr0 = 0x1031;
373
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
374
cpu->id_mmfr1 = 0x20000000;
375
cpu->id_mmfr2 = 0x01230000;
376
cpu->id_mmfr3 = 0x00002111;
377
- cpu->id_isar0 = 0x00101111;
378
- cpu->id_isar1 = 0x13112111;
379
- cpu->id_isar2 = 0x21232041;
380
- cpu->id_isar3 = 0x11112131;
381
- cpu->id_isar4 = 0x00111142;
382
+ cpu->isar.id_isar0 = 0x00101111;
383
+ cpu->isar.id_isar1 = 0x13112111;
384
+ cpu->isar.id_isar2 = 0x21232041;
385
+ cpu->isar.id_isar3 = 0x11112131;
386
+ cpu->isar.id_isar4 = 0x00111142;
387
cpu->dbgdidr = 0x35141000;
388
cpu->clidr = (1 << 27) | (1 << 24) | 3;
389
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
390
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
391
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
392
cpu->midr = 0x410fc075;
393
cpu->reset_fpsid = 0x41023075;
394
- cpu->mvfr0 = 0x10110222;
395
- cpu->mvfr1 = 0x11111111;
396
+ cpu->isar.mvfr0 = 0x10110222;
397
+ cpu->isar.mvfr1 = 0x11111111;
398
cpu->ctr = 0x84448003;
399
cpu->reset_sctlr = 0x00c50078;
400
cpu->id_pfr0 = 0x00001131;
401
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
402
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
403
* table 4-41 gives 0x02101110, which includes the arm div insns.
404
*/
405
- cpu->id_isar0 = 0x02101110;
406
- cpu->id_isar1 = 0x13112111;
407
- cpu->id_isar2 = 0x21232041;
408
- cpu->id_isar3 = 0x11112131;
409
- cpu->id_isar4 = 0x10011142;
410
+ cpu->isar.id_isar0 = 0x02101110;
411
+ cpu->isar.id_isar1 = 0x13112111;
412
+ cpu->isar.id_isar2 = 0x21232041;
413
+ cpu->isar.id_isar3 = 0x11112131;
414
+ cpu->isar.id_isar4 = 0x10011142;
415
cpu->dbgdidr = 0x3515f005;
416
cpu->clidr = 0x0a200023;
417
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
418
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
419
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
420
cpu->midr = 0x412fc0f1;
421
cpu->reset_fpsid = 0x410430f0;
422
- cpu->mvfr0 = 0x10110222;
423
- cpu->mvfr1 = 0x11111111;
424
+ cpu->isar.mvfr0 = 0x10110222;
425
+ cpu->isar.mvfr1 = 0x11111111;
426
cpu->ctr = 0x8444c004;
427
cpu->reset_sctlr = 0x00c50078;
428
cpu->id_pfr0 = 0x00001131;
429
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
430
cpu->id_mmfr1 = 0x20000000;
431
cpu->id_mmfr2 = 0x01240000;
432
cpu->id_mmfr3 = 0x02102211;
433
- cpu->id_isar0 = 0x02101110;
434
- cpu->id_isar1 = 0x13112111;
435
- cpu->id_isar2 = 0x21232041;
436
- cpu->id_isar3 = 0x11112131;
437
- cpu->id_isar4 = 0x10011142;
438
+ cpu->isar.id_isar0 = 0x02101110;
439
+ cpu->isar.id_isar1 = 0x13112111;
440
+ cpu->isar.id_isar2 = 0x21232041;
441
+ cpu->isar.id_isar3 = 0x11112131;
442
+ cpu->isar.id_isar4 = 0x10011142;
443
cpu->dbgdidr = 0x3515f021;
444
cpu->clidr = 0x0a200023;
445
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
446
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/target/arm/cpu64.c
449
+++ b/target/arm/cpu64.c
450
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
451
cpu->midr = 0x411fd070;
452
cpu->revidr = 0x00000000;
453
cpu->reset_fpsid = 0x41034070;
454
- cpu->mvfr0 = 0x10110222;
455
- cpu->mvfr1 = 0x12111111;
456
- cpu->mvfr2 = 0x00000043;
457
+ cpu->isar.mvfr0 = 0x10110222;
458
+ cpu->isar.mvfr1 = 0x12111111;
459
+ cpu->isar.mvfr2 = 0x00000043;
460
cpu->ctr = 0x8444c004;
461
cpu->reset_sctlr = 0x00c50838;
462
cpu->id_pfr0 = 0x00000131;
463
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
464
cpu->id_mmfr1 = 0x40000000;
465
cpu->id_mmfr2 = 0x01260000;
466
cpu->id_mmfr3 = 0x02102211;
467
- cpu->id_isar0 = 0x02101110;
468
- cpu->id_isar1 = 0x13112111;
469
- cpu->id_isar2 = 0x21232042;
470
- cpu->id_isar3 = 0x01112131;
471
- cpu->id_isar4 = 0x00011142;
472
- cpu->id_isar5 = 0x00011121;
473
- cpu->id_isar6 = 0;
474
- cpu->id_aa64pfr0 = 0x00002222;
475
+ cpu->isar.id_isar0 = 0x02101110;
476
+ cpu->isar.id_isar1 = 0x13112111;
477
+ cpu->isar.id_isar2 = 0x21232042;
478
+ cpu->isar.id_isar3 = 0x01112131;
479
+ cpu->isar.id_isar4 = 0x00011142;
480
+ cpu->isar.id_isar5 = 0x00011121;
481
+ cpu->isar.id_isar6 = 0;
482
+ cpu->isar.id_aa64pfr0 = 0x00002222;
483
cpu->id_aa64dfr0 = 0x10305106;
484
cpu->pmceid0 = 0x00000000;
485
cpu->pmceid1 = 0x00000000;
486
- cpu->id_aa64isar0 = 0x00011120;
487
+ cpu->isar.id_aa64isar0 = 0x00011120;
488
cpu->id_aa64mmfr0 = 0x00001124;
489
cpu->dbgdidr = 0x3516d000;
490
cpu->clidr = 0x0a200023;
491
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
492
cpu->midr = 0x410fd034;
493
cpu->revidr = 0x00000000;
494
cpu->reset_fpsid = 0x41034070;
495
- cpu->mvfr0 = 0x10110222;
496
- cpu->mvfr1 = 0x12111111;
497
- cpu->mvfr2 = 0x00000043;
498
+ cpu->isar.mvfr0 = 0x10110222;
499
+ cpu->isar.mvfr1 = 0x12111111;
500
+ cpu->isar.mvfr2 = 0x00000043;
501
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
502
cpu->reset_sctlr = 0x00c50838;
503
cpu->id_pfr0 = 0x00000131;
504
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
505
cpu->id_mmfr1 = 0x40000000;
506
cpu->id_mmfr2 = 0x01260000;
507
cpu->id_mmfr3 = 0x02102211;
508
- cpu->id_isar0 = 0x02101110;
509
- cpu->id_isar1 = 0x13112111;
510
- cpu->id_isar2 = 0x21232042;
511
- cpu->id_isar3 = 0x01112131;
512
- cpu->id_isar4 = 0x00011142;
513
- cpu->id_isar5 = 0x00011121;
514
- cpu->id_isar6 = 0;
515
- cpu->id_aa64pfr0 = 0x00002222;
516
+ cpu->isar.id_isar0 = 0x02101110;
517
+ cpu->isar.id_isar1 = 0x13112111;
518
+ cpu->isar.id_isar2 = 0x21232042;
519
+ cpu->isar.id_isar3 = 0x01112131;
520
+ cpu->isar.id_isar4 = 0x00011142;
521
+ cpu->isar.id_isar5 = 0x00011121;
522
+ cpu->isar.id_isar6 = 0;
523
+ cpu->isar.id_aa64pfr0 = 0x00002222;
524
cpu->id_aa64dfr0 = 0x10305106;
525
- cpu->id_aa64isar0 = 0x00011120;
526
+ cpu->isar.id_aa64isar0 = 0x00011120;
527
cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
528
cpu->dbgdidr = 0x3516d000;
529
cpu->clidr = 0x0a200023;
530
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
531
cpu->midr = 0x410fd083;
532
cpu->revidr = 0x00000000;
533
cpu->reset_fpsid = 0x41034080;
534
- cpu->mvfr0 = 0x10110222;
535
- cpu->mvfr1 = 0x12111111;
536
- cpu->mvfr2 = 0x00000043;
537
+ cpu->isar.mvfr0 = 0x10110222;
538
+ cpu->isar.mvfr1 = 0x12111111;
539
+ cpu->isar.mvfr2 = 0x00000043;
540
cpu->ctr = 0x8444c004;
541
cpu->reset_sctlr = 0x00c50838;
542
cpu->id_pfr0 = 0x00000131;
543
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
544
cpu->id_mmfr1 = 0x40000000;
545
cpu->id_mmfr2 = 0x01260000;
546
cpu->id_mmfr3 = 0x02102211;
547
- cpu->id_isar0 = 0x02101110;
548
- cpu->id_isar1 = 0x13112111;
549
- cpu->id_isar2 = 0x21232042;
550
- cpu->id_isar3 = 0x01112131;
551
- cpu->id_isar4 = 0x00011142;
552
- cpu->id_isar5 = 0x00011121;
553
- cpu->id_aa64pfr0 = 0x00002222;
554
+ cpu->isar.id_isar0 = 0x02101110;
555
+ cpu->isar.id_isar1 = 0x13112111;
556
+ cpu->isar.id_isar2 = 0x21232042;
557
+ cpu->isar.id_isar3 = 0x01112131;
558
+ cpu->isar.id_isar4 = 0x00011142;
559
+ cpu->isar.id_isar5 = 0x00011121;
560
+ cpu->isar.id_aa64pfr0 = 0x00002222;
561
cpu->id_aa64dfr0 = 0x10305106;
562
cpu->pmceid0 = 0x00000000;
563
cpu->pmceid1 = 0x00000000;
564
- cpu->id_aa64isar0 = 0x00011120;
565
+ cpu->isar.id_aa64isar0 = 0x00011120;
566
cpu->id_aa64mmfr0 = 0x00001124;
567
cpu->dbgdidr = 0x3516d000;
568
cpu->clidr = 0x0a200023;
569
diff --git a/target/arm/helper.c b/target/arm/helper.c
570
index XXXXXXX..XXXXXXX 100644
571
--- a/target/arm/helper.c
572
+++ b/target/arm/helper.c
573
@@ -XXX,XX +XXX,XX @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
574
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
575
{
576
ARMCPU *cpu = arm_env_get_cpu(env);
577
- uint64_t pfr0 = cpu->id_aa64pfr0;
578
+ uint64_t pfr0 = cpu->isar.id_aa64pfr0;
579
580
if (env->gicv3state) {
581
pfr0 |= 1 << 24;
582
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
583
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
584
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
585
.access = PL1_R, .type = ARM_CP_CONST,
586
- .resetvalue = cpu->id_isar0 },
587
+ .resetvalue = cpu->isar.id_isar0 },
588
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
589
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
590
.access = PL1_R, .type = ARM_CP_CONST,
591
- .resetvalue = cpu->id_isar1 },
592
+ .resetvalue = cpu->isar.id_isar1 },
593
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
594
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
595
.access = PL1_R, .type = ARM_CP_CONST,
596
- .resetvalue = cpu->id_isar2 },
597
+ .resetvalue = cpu->isar.id_isar2 },
598
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
599
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
600
.access = PL1_R, .type = ARM_CP_CONST,
601
- .resetvalue = cpu->id_isar3 },
602
+ .resetvalue = cpu->isar.id_isar3 },
603
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
604
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
605
.access = PL1_R, .type = ARM_CP_CONST,
606
- .resetvalue = cpu->id_isar4 },
607
+ .resetvalue = cpu->isar.id_isar4 },
608
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
609
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
610
.access = PL1_R, .type = ARM_CP_CONST,
611
- .resetvalue = cpu->id_isar5 },
612
+ .resetvalue = cpu->isar.id_isar5 },
613
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
614
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
615
.access = PL1_R, .type = ARM_CP_CONST,
616
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
617
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
618
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
619
.access = PL1_R, .type = ARM_CP_CONST,
620
- .resetvalue = cpu->id_isar6 },
621
+ .resetvalue = cpu->isar.id_isar6 },
622
REGINFO_SENTINEL
623
};
624
define_arm_cp_regs(cpu, v6_idregs);
625
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
626
{ .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
627
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
628
.access = PL1_R, .type = ARM_CP_CONST,
629
- .resetvalue = cpu->id_aa64pfr1},
630
+ .resetvalue = cpu->isar.id_aa64pfr1},
631
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
632
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
633
.access = PL1_R, .type = ARM_CP_CONST,
634
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
635
{ .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
636
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
637
.access = PL1_R, .type = ARM_CP_CONST,
638
- .resetvalue = cpu->id_aa64isar0 },
639
+ .resetvalue = cpu->isar.id_aa64isar0 },
640
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
641
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
642
.access = PL1_R, .type = ARM_CP_CONST,
643
- .resetvalue = cpu->id_aa64isar1 },
644
+ .resetvalue = cpu->isar.id_aa64isar1 },
645
{ .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
646
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
647
.access = PL1_R, .type = ARM_CP_CONST,
648
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
649
{ .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
650
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
651
.access = PL1_R, .type = ARM_CP_CONST,
652
- .resetvalue = cpu->mvfr0 },
653
+ .resetvalue = cpu->isar.mvfr0 },
654
{ .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
655
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
656
.access = PL1_R, .type = ARM_CP_CONST,
657
- .resetvalue = cpu->mvfr1 },
658
+ .resetvalue = cpu->isar.mvfr1 },
659
{ .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
660
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
661
.access = PL1_R, .type = ARM_CP_CONST,
662
- .resetvalue = cpu->mvfr2 },
663
+ .resetvalue = cpu->isar.mvfr2 },
664
{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
665
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
666
.access = PL1_R, .type = ARM_CP_CONST,
667
--
44
--
668
2.19.1
45
2.20.1
669
46
670
47
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Announce 64bit addressing support.
3
To differenciate with the CMSDK APB peripheral region,
4
rename this region 'CMSDK AHB peripheral region'.
4
5
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20181017213932.19973-3-edgar.iglesias@gmail.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200617072539.32686-8-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/net/cadence_gem.c | 3 ++-
11
hw/arm/mps2.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
13
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/cadence_gem.c
16
--- a/hw/arm/mps2.c
17
+++ b/hw/net/cadence_gem.c
17
+++ b/hw/arm/mps2.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
#define GEM_DESCONF4 (0x0000028C/4)
19
*/
20
#define GEM_DESCONF5 (0x00000290/4)
20
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
21
#define GEM_DESCONF6 (0x00000294/4)
21
0x40000000, 0x00010000);
22
+#define GEM_DESCONF6_64B_MASK (1U << 23)
22
- create_unimplemented_device("CMSDK peripheral region @0x40010000",
23
#define GEM_DESCONF7 (0x00000298/4)
23
+ create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
24
24
0x40010000, 0x00010000);
25
#define GEM_INT_Q1_STATUS (0x00000400 / 4)
25
create_unimplemented_device("Extra peripheral region @0x40020000",
26
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
26
0x40020000, 0x00010000);
27
s->regs[GEM_DESCONF] = 0x02500111;
27
+
28
s->regs[GEM_DESCONF2] = 0x2ab13fff;
28
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
29
s->regs[GEM_DESCONF5] = 0x002f2045;
29
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
30
- s->regs[GEM_DESCONF6] = 0x0;
30
31
+ s->regs[GEM_DESCONF6] = GEM_DESCONF6_64B_MASK;
32
33
if (s->num_priority_queues > 1) {
34
queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
35
--
31
--
36
2.19.1
32
2.20.1
37
33
38
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
We already model the CMSDK APB watchdog device, let's use it!
4
Message-id: 20181011205206.3552-8-richard.henderson@linaro.org
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20200617072539.32686-9-f4bug@amsat.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/translate.c | 67 ++++++++++++++++++++++++------------------
11
hw/arm/mps2.c | 7 +++++++
9
1 file changed, 39 insertions(+), 28 deletions(-)
12
hw/arm/Kconfig | 1 +
13
2 files changed, 8 insertions(+)
10
14
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
17
--- a/hw/arm/mps2.c
14
+++ b/target/arm/translate.c
18
+++ b/hw/arm/mps2.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
16
return 1;
20
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
17
}
21
qdev_get_gpio_in(armv7m, 10));
18
} else { /* (insn & 0x00380080) == 0 */
22
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
19
- int invert;
23
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
20
+ int invert, reg_ofs, vec_size;
24
+ TYPE_CMSDK_APB_WATCHDOG);
21
+
25
+ qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
22
if (q && (rd & 1)) {
26
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
23
return 1;
27
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
24
}
28
+ qdev_get_gpio_in_named(armv7m, "NMI", 0));
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
29
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
26
break;
30
27
case 14:
31
/* FPGA APB subsystem */
28
imm |= (imm << 8) | (imm << 16) | (imm << 24);
32
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
29
- if (invert)
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
30
+ if (invert) {
34
index XXXXXXX..XXXXXXX 100644
31
imm = ~imm;
35
--- a/hw/arm/Kconfig
32
+ }
36
+++ b/hw/arm/Kconfig
33
break;
37
@@ -XXX,XX +XXX,XX @@ config MPS2
34
case 15:
38
select PL080 # DMA controller
35
if (invert) {
39
select SPLIT_IRQ
36
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
40
select UNIMP
37
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
41
+ select CMSDK_APB_WATCHDOG
38
break;
42
39
}
43
config FSL_IMX7
40
- if (invert)
44
bool
41
+ if (invert) {
42
imm = ~imm;
43
+ }
44
45
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
46
- if (op & 1 && op < 12) {
47
- tmp = neon_load_reg(rd, pass);
48
- if (invert) {
49
- /* The immediate value has already been inverted, so
50
- BIC becomes AND. */
51
- tcg_gen_andi_i32(tmp, tmp, imm);
52
- } else {
53
- tcg_gen_ori_i32(tmp, tmp, imm);
54
- }
55
+ reg_ofs = neon_reg_offset(rd, 0);
56
+ vec_size = q ? 16 : 8;
57
+
58
+ if (op & 1 && op < 12) {
59
+ if (invert) {
60
+ /* The immediate value has already been inverted,
61
+ * so BIC becomes AND.
62
+ */
63
+ tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
64
+ vec_size, vec_size);
65
} else {
66
- /* VMOV, VMVN. */
67
- tmp = tcg_temp_new_i32();
68
- if (op == 14 && invert) {
69
- int n;
70
- uint32_t val;
71
- val = 0;
72
- for (n = 0; n < 4; n++) {
73
- if (imm & (1 << (n + (pass & 1) * 4)))
74
- val |= 0xff << (n * 8);
75
- }
76
- tcg_gen_movi_i32(tmp, val);
77
- } else {
78
- tcg_gen_movi_i32(tmp, imm);
79
- }
80
+ tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
81
+ vec_size, vec_size);
82
+ }
83
+ } else {
84
+ /* VMOV, VMVN. */
85
+ if (op == 14 && invert) {
86
+ TCGv_i64 t64 = tcg_temp_new_i64();
87
+
88
+ for (pass = 0; pass <= q; ++pass) {
89
+ uint64_t val = 0;
90
+ int n;
91
+
92
+ for (n = 0; n < 8; n++) {
93
+ if (imm & (1 << (n + pass * 8))) {
94
+ val |= 0xffull << (n * 8);
95
+ }
96
+ }
97
+ tcg_gen_movi_i64(t64, val);
98
+ neon_store_reg64(t64, rd + pass);
99
+ }
100
+ tcg_temp_free_i64(t64);
101
+ } else {
102
+ tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
103
}
104
- neon_store_reg(rd, pass, tmp);
105
}
106
}
107
} else { /* (insn & 0x00800010 == 0x00800000) */
108
--
45
--
109
2.19.1
46
2.20.1
110
47
111
48
diff view generated by jsdifflib
1
From: Markus Armbruster <armbru@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Device models aren't supposed to go on fishing expeditions for
3
Register the GPIO peripherals as unimplemented to better
4
backends. They should expose suitable properties for the user to set.
4
follow their accesses, for example booting Zephyr:
5
For onboard devices, board code sets them.
6
5
7
Device ssi-sd picks up its block backend in its init() method with
6
----------------
8
drive_get_next() instead. This mistake is already marked FIXME since
7
IN: arm_mps2_pinmux_init
9
commit af9e40a.
8
0x00001160: f64f 0231 movw r2, #0xf831
9
0x00001164: 4b06 ldr r3, [pc, #0x18]
10
0x00001166: 2000 movs r0, #0
11
0x00001168: 619a str r2, [r3, #0x18]
12
0x0000116a: f24c 426f movw r2, #0xc46f
13
0x0000116e: f503 5380 add.w r3, r3, #0x1000
14
0x00001172: 619a str r2, [r3, #0x18]
15
0x00001174: f44f 529e mov.w r2, #0x13c0
16
0x00001178: f503 5380 add.w r3, r3, #0x1000
17
0x0000117c: 619a str r2, [r3, #0x18]
18
0x0000117e: 4770 bx lr
19
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xf831, offset 0x18)
20
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xc46f, offset 0x18)
21
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0x13c0, offset 0x18)
10
22
11
Unset user_creatable to remove the mistake from our external
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
interface. Since the SSI bus doesn't support hotplug, only -device
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
can be affected. Only certain ARM machines have ssi-sd and provide an
25
Message-id: 20200617072539.32686-10-f4bug@amsat.org
14
SSI bus for it; this patch breaks -device ssi-sd for these machines.
15
No actual use of -device ssi-sd is known.
16
17
Signed-off-by: Markus Armbruster <armbru@redhat.com>
18
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Acked-by: Thomas Huth <thuth@redhat.com>
20
Message-id: 20181009060835.4608-1-armbru@redhat.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
27
---
23
hw/sd/ssi-sd.c | 2 ++
28
hw/arm/mps2.c | 8 ++++++--
24
1 file changed, 2 insertions(+)
29
1 file changed, 6 insertions(+), 2 deletions(-)
25
30
26
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
31
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
27
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/sd/ssi-sd.c
33
--- a/hw/arm/mps2.c
29
+++ b/hw/sd/ssi-sd.c
34
+++ b/hw/arm/mps2.c
30
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
35
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
31
k->cs_polarity = SSI_CS_LOW;
36
MemoryRegion *system_memory = get_system_memory();
32
dc->vmsd = &vmstate_ssi_sd;
37
MachineClass *mc = MACHINE_GET_CLASS(machine);
33
dc->reset = ssi_sd_reset;
38
DeviceState *armv7m, *sccdev;
34
+ /* Reason: init() method uses drive_get_next() */
39
+ int i;
35
+ dc->user_creatable = false;
40
36
}
41
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
37
42
error_report("This board can only be used with CPU %s",
38
static const TypeInfo ssi_sd_info = {
43
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
44
*/
45
Object *orgate;
46
DeviceState *orgate_dev;
47
- int i;
48
49
orgate = object_new(TYPE_OR_IRQ);
50
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
51
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
52
*/
53
Object *orgate;
54
DeviceState *orgate_dev;
55
- int i;
56
57
orgate = object_new(TYPE_OR_IRQ);
58
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
60
default:
61
g_assert_not_reached();
62
}
63
+ for (i = 0; i < 4; i++) {
64
+ static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
65
+ 0x40012000, 0x40013000};
66
+ create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
67
+ }
68
69
/* CMSDK APB subsystem */
70
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
39
--
71
--
40
2.19.1
72
2.20.1
41
73
42
74
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Message-id: 20200617072539.32686-11-f4bug@amsat.org
5
Message-id: 20181011205206.3552-6-richard.henderson@linaro.org
6
[PMM: drop change to now-deleted cpu_mode_names array]
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
target/arm/translate.c | 4 ++--
8
hw/arm/mps2.c | 9 +++++++++
11
1 file changed, 2 insertions(+), 2 deletions(-)
9
1 file changed, 9 insertions(+)
12
10
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
13
--- a/hw/arm/mps2.c
16
+++ b/target/arm/translate.c
14
+++ b/hw/arm/mps2.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 cpu_F0d, cpu_F1d;
15
@@ -XXX,XX +XXX,XX @@
18
16
#include "hw/timer/cmsdk-apb-timer.h"
19
#include "exec/gen-icount.h"
17
#include "hw/timer/cmsdk-apb-dualtimer.h"
20
18
#include "hw/misc/mps2-scc.h"
21
-static const char *regnames[] =
19
+#include "hw/misc/mps2-fpgaio.h"
22
+static const char * const regnames[] =
20
#include "hw/net/lan9118.h"
23
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
21
#include "net/net.h"
24
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
22
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
25
23
26
@@ -XXX,XX +XXX,XX @@ static struct {
24
typedef enum MPS2FPGAType {
27
int nregs;
25
FPGA_AN385,
28
int interleave;
26
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
int spacing;
27
MemoryRegion sram;
30
-} neon_ls_element_type[11] = {
28
/* FPGA APB subsystem */
31
+} const neon_ls_element_type[11] = {
29
MPS2SCC scc;
32
{4, 4, 1},
30
+ MPS2FPGAIO fpgaio;
33
{4, 4, 2},
31
/* CMSDK APB subsystem */
34
{4, 1, 1},
32
CMSDKAPBDualTimer dualtimer;
33
+ CMSDKAPBWatchdog watchdog;
34
} MPS2MachineState;
35
36
#define TYPE_MPS2_MACHINE "mps2"
37
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
38
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
39
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
40
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
41
+ object_initialize_child(OBJECT(mms), "fpgaio",
42
+ &mms->fpgaio, TYPE_MPS2_FPGAIO);
43
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
44
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
45
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
46
47
/* In hardware this is a LAN9220; the LAN9118 is software compatible
48
* except that it doesn't support the checksum-offload feature.
35
--
49
--
36
2.19.1
50
2.20.1
37
51
38
52
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Announce the availability of the various priority queues.
3
From 'Application Note AN385', chapter 3.9, SPI:
4
This fixes an issue where guest kernels would miss to
5
configure secondary queues due to inproper feature bits.
6
4
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
The SMM implements five PL022 SPI modules.
8
Message-id: 20181017213932.19973-2-edgar.iglesias@gmail.com
6
7
Two pairs of modules share the same OR-gated IRQ.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-12-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/net/cadence_gem.c | 8 +++++++-
14
hw/arm/mps2.c | 24 ++++++++++++++++++++++++
13
1 file changed, 7 insertions(+), 1 deletion(-)
15
hw/arm/Kconfig | 6 +++---
16
2 files changed, 27 insertions(+), 3 deletions(-)
14
17
15
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/cadence_gem.c
20
--- a/hw/arm/mps2.c
18
+++ b/hw/net/cadence_gem.c
21
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
22
@@ -XXX,XX +XXX,XX @@
20
int i;
23
#include "hw/timer/cmsdk-apb-dualtimer.h"
21
CadenceGEMState *s = CADENCE_GEM(d);
24
#include "hw/misc/mps2-scc.h"
22
const uint8_t *a;
25
#include "hw/misc/mps2-fpgaio.h"
23
+ uint32_t queues_mask = 0;
26
+#include "hw/ssi/pl022.h"
24
27
#include "hw/net/lan9118.h"
25
DB_PRINT("\n");
28
#include "net/net.h"
26
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
27
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
28
s->regs[GEM_DESCONF] = 0x02500111;
31
qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
29
s->regs[GEM_DESCONF2] = 0x2ab13fff;
32
sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
30
s->regs[GEM_DESCONF5] = 0x002f2045;
33
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
31
- s->regs[GEM_DESCONF6] = 0x00000200;
34
+ sysbus_create_simple(TYPE_PL022, 0x40025000, /* External ADC */
32
+ s->regs[GEM_DESCONF6] = 0x0;
35
+ qdev_get_gpio_in(armv7m, 22));
36
+ for (i = 0; i < 2; i++) {
37
+ static const int spi_irqno[] = {11, 24};
38
+ static const hwaddr spibase[] = {0x40020000, /* APB */
39
+ 0x40021000, /* LCD */
40
+ 0x40026000, /* Shield0 */
41
+ 0x40027000}; /* Shield1 */
42
+ DeviceState *orgate_dev;
43
+ Object *orgate;
44
+ int j;
33
+
45
+
34
+ if (s->num_priority_queues > 1) {
46
+ orgate = object_new(TYPE_OR_IRQ);
35
+ queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
47
+ object_property_set_int(orgate, 2, "num-lines", &error_fatal);
36
+ s->regs[GEM_DESCONF6] |= queues_mask;
48
+ orgate_dev = DEVICE(orgate);
49
+ qdev_realize(orgate_dev, NULL, &error_fatal);
50
+ qdev_connect_gpio_out(orgate_dev, 0,
51
+ qdev_get_gpio_in(armv7m, spi_irqno[i]));
52
+ for (j = 0; j < 2; j++) {
53
+ sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
54
+ qdev_get_gpio_in(orgate_dev, j));
55
+ }
37
+ }
56
+ }
38
57
39
/* Set MAC address */
58
/* In hardware this is a LAN9220; the LAN9118 is software compatible
40
a = &s->conf.macaddr.a[0];
59
* except that it doesn't support the checksum-offload feature.
60
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/Kconfig
63
+++ b/hw/arm/Kconfig
64
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
65
select ARM_TIMER # sp804
66
select ARM_V7M
67
select PL011 # UART
68
- select PL022 # Serial port
69
+ select PL022 # SPI
70
select PL031 # RTC
71
select PL061 # GPIO
72
select PL310 # cache controller
73
@@ -XXX,XX +XXX,XX @@ config STELLARIS
74
select CMSDK_APB_WATCHDOG
75
select I2C
76
select PL011 # UART
77
- select PL022 # Serial port
78
+ select PL022 # SPI
79
select PL061 # GPIO
80
select SSD0303 # OLED display
81
select SSD0323 # OLED display
82
@@ -XXX,XX +XXX,XX @@ config MPS2
83
select MPS2_FPGAIO
84
select MPS2_SCC
85
select OR_IRQ
86
- select PL022 # Serial port
87
+ select PL022 # SPI
88
select PL080 # DMA controller
89
select SPLIT_IRQ
90
select UNIMP
41
--
91
--
42
2.19.1
92
2.20.1
43
93
44
94
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Having V6 alone imply jazelle was wrong for cortex-m0.
3
From 'Application Note AN385', chapter 3.14:
4
Change to an assertion for V6 & !M.
5
4
6
This was harmless, because the only place we tested ARM_FEATURE_JAZELLE
5
The SMM implements a simple SBCon interface based on I2C.
7
was for 'bxj' in disas_arm(), which is unreachable for M-profile cores.
8
6
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
There are 4 SBCon interfaces on the FPGA APB subsystem.
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
11
Message-id: 20181016223115.24100-6-richard.henderson@linaro.org
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-13-f4bug@amsat.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
target/arm/cpu.h | 6 +++++-
14
hw/arm/mps2.c | 8 ++++++++
16
target/arm/cpu.c | 17 ++++++++++++++---
15
hw/arm/Kconfig | 1 +
17
target/arm/translate.c | 2 +-
16
2 files changed, 9 insertions(+)
18
3 files changed, 20 insertions(+), 5 deletions(-)
19
17
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
20
--- a/hw/arm/mps2.c
23
+++ b/target/arm/cpu.h
21
+++ b/hw/arm/mps2.c
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
22
@@ -XXX,XX +XXX,XX @@
25
ARM_FEATURE_PMU, /* has PMU support */
23
#include "hw/misc/mps2-scc.h"
26
ARM_FEATURE_VBAR, /* has cp15 VBAR */
24
#include "hw/misc/mps2-fpgaio.h"
27
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
25
#include "hw/ssi/pl022.h"
28
- ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
26
+#include "hw/i2c/arm_sbcon_i2c.h"
29
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
27
#include "hw/net/lan9118.h"
30
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
28
#include "net/net.h"
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_arm_div(const ARMISARegisters *id)
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
33
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
31
qdev_get_gpio_in(orgate_dev, j));
34
}
35
36
+static inline bool isar_feature_jazelle(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
39
+}
40
+
41
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
42
{
43
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
49
}
50
if (arm_feature(env, ARM_FEATURE_V6)) {
51
set_feature(env, ARM_FEATURE_V5);
52
- set_feature(env, ARM_FEATURE_JAZELLE);
53
if (!arm_feature(env, ARM_FEATURE_M)) {
54
+ assert(cpu_isar_feature(jazelle, cpu));
55
set_feature(env, ARM_FEATURE_AUXCR);
56
}
32
}
57
}
33
}
58
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
34
+ for (i = 0; i < 4; i++) {
59
set_feature(&cpu->env, ARM_FEATURE_VFP);
35
+ static const hwaddr i2cbase[] = {0x40022000, /* Touch */
60
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
36
+ 0x40023000, /* Audio */
61
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
37
+ 0x40029000, /* Shield0 */
62
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
38
+ 0x4002a000}; /* Shield1 */
63
cpu->midr = 0x41069265;
39
+ sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
64
cpu->reset_fpsid = 0x41011090;
40
+ }
65
cpu->ctr = 0x1dd20d2;
41
66
cpu->reset_sctlr = 0x00090078;
42
/* In hardware this is a LAN9220; the LAN9118 is software compatible
67
+
43
* except that it doesn't support the checksum-offload feature.
68
+ /*
44
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
69
+ * ARMv5 does not have the ID_ISAR registers, but we can still
70
+ * set the field to indicate Jazelle support within QEMU.
71
+ */
72
+ cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
73
}
74
75
static void arm946_initfn(Object *obj)
76
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
77
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
78
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
79
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
80
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
81
cpu->midr = 0x4106a262;
82
cpu->reset_fpsid = 0x410110a0;
83
cpu->ctr = 0x1dd20d2;
84
cpu->reset_sctlr = 0x00090078;
85
cpu->reset_auxcr = 1;
86
+
87
+ /*
88
+ * ARMv5 does not have the ID_ISAR registers, but we can still
89
+ * set the field to indicate Jazelle support within QEMU.
90
+ */
91
+ cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
92
+
93
{
94
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
95
ARMCPRegInfo ifar = {
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
46
--- a/hw/arm/Kconfig
99
+++ b/target/arm/translate.c
47
+++ b/hw/arm/Kconfig
100
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ config MPS2
101
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
49
select SPLIT_IRQ
102
/* currently all emulated v5 cores are also v5TE, so don't bother */
50
select UNIMP
103
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
51
select CMSDK_APB_WATCHDOG
104
-#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
52
+ select VERSATILE_I2C
105
+#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
53
106
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
54
config FSL_IMX7
107
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
55
bool
108
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
109
--
56
--
110
2.19.1
57
2.20.1
111
58
112
59
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Instantiating mps2-an505 (cortex-m33) will fail make check when
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
V7VE asserts that ID_ISAR0.Divide includes ARM division. It is
4
Message-id: 20200617072539.32686-14-f4bug@amsat.org
5
also wrong to include ARM_FEATURE_LPAE.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20181016223115.24100-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
target/arm/cpu.c | 6 +++++-
8
hw/arm/mps2.c | 1 +
13
1 file changed, 5 insertions(+), 1 deletion(-)
9
1 file changed, 1 insertion(+)
14
10
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
13
--- a/hw/arm/mps2.c
18
+++ b/target/arm/cpu.c
14
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
15
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
20
16
0x4002a000}; /* Shield1 */
21
/* Some features automatically imply others: */
17
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
22
if (arm_feature(env, ARM_FEATURE_V8)) {
23
- set_feature(env, ARM_FEATURE_V7VE);
24
+ if (arm_feature(env, ARM_FEATURE_M)) {
25
+ set_feature(env, ARM_FEATURE_V7);
26
+ } else {
27
+ set_feature(env, ARM_FEATURE_V7VE);
28
+ }
29
}
18
}
30
if (arm_feature(env, ARM_FEATURE_V7VE)) {
19
+ create_unimplemented_device("i2s", 0x40024000, 0x400);
31
/* v7 Virtualization Extensions. In real hardware this implies
20
21
/* In hardware this is a LAN9220; the LAN9118 is software compatible
22
* except that it doesn't support the checksum-offload feature.
32
--
23
--
33
2.19.1
24
2.20.1
34
25
35
26
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
From 'Application Note AN521', chapter 4.7:
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20181016223115.24100-7-richard.henderson@linaro.org
5
The SMM implements four SBCon serial modules:
6
7
One SBCon module for use by the Color LCD touch interface.
8
One SBCon module to configure the audio controller.
9
Two general purpose SBCon modules, that connect to the
10
Expansion headers J7 and J8, are intended for use with the
11
V2C-Shield1 which provide an I2C interface on the headers.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-15-f4bug@amsat.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
17
---
9
target/arm/cpu.h | 6 +++++-
18
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
10
linux-user/elfload.c | 2 +-
19
1 file changed, 18 insertions(+), 5 deletions(-)
11
target/arm/cpu.c | 4 ----
12
target/arm/helper.c | 2 +-
13
target/arm/machine.c | 3 +--
14
5 files changed, 8 insertions(+), 9 deletions(-)
15
20
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
23
--- a/hw/arm/mps2-tz.c
19
+++ b/target/arm/cpu.h
24
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
25
@@ -XXX,XX +XXX,XX @@
21
ARM_FEATURE_NEON,
26
#include "hw/arm/armsse.h"
22
ARM_FEATURE_M, /* Microcontroller profile. */
27
#include "hw/dma/pl080.h"
23
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
28
#include "hw/ssi/pl022.h"
24
- ARM_FEATURE_THUMB2EE,
29
+#include "hw/i2c/arm_sbcon_i2c.h"
25
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
30
#include "hw/net/lan9118.h"
26
ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
31
#include "net/net.h"
27
ARM_FEATURE_V4T,
32
#include "hw/core/split-irq.h"
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_jazelle(const ARMISARegisters *id)
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
34
TZPPC ppc[5];
35
TZMPC ssram_mpc[3];
36
PL022State spi[5];
37
- UnimplementedDeviceState i2c[4];
38
+ ArmSbconI2CState i2c[4];
39
UnimplementedDeviceState i2s_audio;
40
UnimplementedDeviceState gpio[4];
41
UnimplementedDeviceState gfx;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
43
return sysbus_mmio_get_region(s, 0);
30
}
44
}
31
45
32
+static inline bool isar_feature_t32ee(const ARMISARegisters *id)
46
+static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
47
+ const char *name, hwaddr size)
33
+{
48
+{
34
+ return FIELD_EX32(id->id_isar3, ID_ISAR3, T32EE) != 0;
49
+ ArmSbconI2CState *i2c = opaque;
50
+ SysBusDevice *s;
51
+
52
+ object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
53
+ s = SYS_BUS_DEVICE(i2c);
54
+ sysbus_realize(s, &error_fatal);
55
+ return sysbus_mmio_get_region(s, 0);
35
+}
56
+}
36
+
57
+
37
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
58
static void mps2tz_common_init(MachineState *machine)
38
{
59
{
39
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
60
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
40
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
61
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
41
index XXXXXXX..XXXXXXX 100644
62
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
42
--- a/linux-user/elfload.c
63
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
43
+++ b/linux-user/elfload.c
64
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
44
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
65
- { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
45
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
66
- { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
46
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
67
- { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
47
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
68
- { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
48
- GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
69
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
49
+ GET_FEATURE_ID(t32ee, ARM_HWCAP_ARM_THUMBEE);
70
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
50
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
71
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
51
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
72
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
52
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
73
},
53
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
74
}, {
54
index XXXXXXX..XXXXXXX 100644
75
.name = "apb_ppcexp2",
55
--- a/target/arm/cpu.c
56
+++ b/target/arm/cpu.c
57
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
58
set_feature(&cpu->env, ARM_FEATURE_V7);
59
set_feature(&cpu->env, ARM_FEATURE_VFP3);
60
set_feature(&cpu->env, ARM_FEATURE_NEON);
61
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
62
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
63
set_feature(&cpu->env, ARM_FEATURE_EL3);
64
cpu->midr = 0x410fc080;
65
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
66
set_feature(&cpu->env, ARM_FEATURE_VFP3);
67
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
68
set_feature(&cpu->env, ARM_FEATURE_NEON);
69
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
70
set_feature(&cpu->env, ARM_FEATURE_EL3);
71
/* Note that A9 supports the MP extensions even for
72
* A9UP and single-core A9MP (which are both different
73
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
74
set_feature(&cpu->env, ARM_FEATURE_V7VE);
75
set_feature(&cpu->env, ARM_FEATURE_VFP4);
76
set_feature(&cpu->env, ARM_FEATURE_NEON);
77
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
78
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
79
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
80
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
81
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
82
set_feature(&cpu->env, ARM_FEATURE_V7VE);
83
set_feature(&cpu->env, ARM_FEATURE_VFP4);
84
set_feature(&cpu->env, ARM_FEATURE_NEON);
85
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
86
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
87
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
88
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
89
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/helper.c
92
+++ b/target/arm/helper.c
93
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
94
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
95
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
96
}
97
- if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
98
+ if (cpu_isar_feature(t32ee, cpu)) {
99
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
100
}
101
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
102
diff --git a/target/arm/machine.c b/target/arm/machine.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/machine.c
105
+++ b/target/arm/machine.c
106
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
107
static bool thumb2ee_needed(void *opaque)
108
{
109
ARMCPU *cpu = opaque;
110
- CPUARMState *env = &cpu->env;
111
112
- return arm_feature(env, ARM_FEATURE_THUMB2EE);
113
+ return cpu_isar_feature(t32ee, cpu);
114
}
115
116
static const VMStateDescription vmstate_thumb2ee = {
117
--
76
--
118
2.19.1
77
2.20.1
119
78
120
79
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch extends the qemu-kvm state sync logic with support for
3
Since commit d70c996df23f, when enabling the PMU we get:
4
KVM_GET/SET_VCPU_EVENTS, giving access to yet missing SError exception.
4
5
And also it can support the exception state migration.
5
$ qemu-system-aarch64 -cpu host,pmu=on -M virt,accel=kvm,gic-version=3
6
6
Segmentation fault (core dumped)
7
The SError exception states include SError pending state and ESR value,
7
8
the kvm_put/get_vcpu_events() will be called when set or get system
8
Thread 1 "qemu-system-aar" received signal SIGSEGV, Segmentation fault.
9
registers. When do migration, if source machine has SError pending,
9
0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
10
QEMU will do this migration regardless whether the target machine supports
10
2588 ret = ioctl(s->fd, type, arg);
11
to specify guest ESR value, because if target machine does not support that,
11
(gdb) bt
12
it can also inject the SError with zero ESR value.
12
#0 0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
13
13
#1 0x0000aaaaaae31568 in kvm_check_extension (s=0x0, extension=126) at accel/kvm/kvm-all.c:916
14
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
#2 0x0000aaaaaafce254 in kvm_arm_pmu_supported (cpu=0xaaaaac214ab0) at target/arm/kvm.c:213
15
#3 0x0000aaaaaafc0f94 in arm_set_pmu (obj=0xaaaaac214ab0, value=true, errp=0xffffffffe438) at target/arm/cpu.c:1111
16
#4 0x0000aaaaab5533ac in property_set_bool (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", opaque=0xaaaaac222730, errp=0xffffffffe438) at qom/object.c:2170
17
#5 0x0000aaaaab5512f0 in object_property_set (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1328
18
#6 0x0000aaaaab551e10 in object_property_parse (obj=0xaaaaac214ab0, string=0xaaaaac11b4c0 "on", name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1561
19
#7 0x0000aaaaab54ee8c in object_apply_global_props (obj=0xaaaaac214ab0, props=0xaaaaac018e20, errp=0xaaaaabd6fd88 <error_fatal>) at qom/object.c:407
20
#8 0x0000aaaaab1dd5a4 in qdev_prop_set_globals (dev=0xaaaaac214ab0) at hw/core/qdev-properties.c:1218
21
#9 0x0000aaaaab1d9fac in device_post_init (obj=0xaaaaac214ab0) at hw/core/qdev.c:1050
22
...
23
#15 0x0000aaaaab54f310 in object_initialize_with_type (obj=0xaaaaac214ab0, size=52208, type=0xaaaaabe237f0) at qom/object.c:512
24
#16 0x0000aaaaab54fa24 in object_new_with_type (type=0xaaaaabe237f0) at qom/object.c:687
25
#17 0x0000aaaaab54fa80 in object_new (typename=0xaaaaabe23970 "host-arm-cpu") at qom/object.c:702
26
#18 0x0000aaaaaaf04a74 in machvirt_init (machine=0xaaaaac0a8550) at hw/arm/virt.c:1770
27
#19 0x0000aaaaab1e8720 in machine_run_board_init (machine=0xaaaaac0a8550) at hw/core/machine.c:1138
28
#20 0x0000aaaaaaf95394 in qemu_init (argc=5, argv=0xffffffffea58, envp=0xffffffffea88) at softmmu/vl.c:4348
29
#21 0x0000aaaaaada3f74 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at softmmu/main.c:48
30
31
This is because in frame #2, cpu->kvm_state is still NULL
32
(the vCPU is not yet realized).
33
34
KVM has a hard requirement of all cores supporting the same
35
feature set. We only need to check if the accelerator supports
36
a feature, not each vCPU individually.
37
38
Fix by removing the 'CPUState *cpu' argument from the
39
kvm_arm_<FEATURE>_supported() functions.
40
41
Fixes: d70c996df23f ('Use CPUState::kvm_state in kvm_arm_pmu_supported')
42
Reported-by: Haibo Xu <haibo.xu@linaro.org>
15
Reviewed-by: Andrew Jones <drjones@redhat.com>
43
Reviewed-by: Andrew Jones <drjones@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
44
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
17
Message-id: 1538067351-23931-3-git-send-email-gengdongjiu@huawei.com
45
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
46
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
47
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
49
---
20
target/arm/cpu.h | 7 ++++++
50
target/arm/kvm_arm.h | 21 +++++++++------------
21
target/arm/kvm_arm.h | 24 ++++++++++++++++++
51
target/arm/cpu.c | 2 +-
22
target/arm/kvm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++
52
target/arm/cpu64.c | 10 +++++-----
23
target/arm/kvm32.c | 13 ++++++++++
53
target/arm/kvm.c | 4 ++--
24
target/arm/kvm64.c | 13 ++++++++++
54
target/arm/kvm64.c | 14 +++++---------
25
target/arm/machine.c | 22 ++++++++++++++++
55
5 files changed, 22 insertions(+), 29 deletions(-)
26
6 files changed, 139 insertions(+)
56
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
33
*/
34
} exception;
35
36
+ /* Information associated with an SError */
37
+ struct {
38
+ uint8_t pending;
39
+ uint8_t has_esr;
40
+ uint64_t esr;
41
+ } serror;
42
+
43
/* Thumb-2 EE state. */
44
uint32_t teecr;
45
uint32_t teehbr;
46
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
57
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
47
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/kvm_arm.h
59
--- a/target/arm/kvm_arm.h
49
+++ b/target/arm/kvm_arm.h
60
+++ b/target/arm/kvm_arm.h
50
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu);
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj);
62
63
/**
64
* kvm_arm_aarch32_supported:
65
- * @cs: CPUState
66
*
67
- * Returns: true if the KVM VCPU can enable AArch32 mode
68
+ * Returns: true if KVM can enable AArch32 mode
69
* and false otherwise.
51
*/
70
*/
52
void kvm_arm_reset_vcpu(ARMCPU *cpu);
71
-bool kvm_arm_aarch32_supported(CPUState *cs);
53
72
+bool kvm_arm_aarch32_supported(void);
54
+/**
73
55
+ * kvm_arm_init_serror_injection:
74
/**
56
+ * @cs: CPUState
75
* kvm_arm_pmu_supported:
57
+ *
76
- * @cs: CPUState
58
+ * Check whether KVM can set guest SError syndrome.
77
*
59
+ */
78
- * Returns: true if the KVM VCPU can enable its PMU
60
+void kvm_arm_init_serror_injection(CPUState *cs);
79
+ * Returns: true if KVM can enable the PMU
61
+
80
* and false otherwise.
62
+/**
81
*/
63
+ * kvm_get_vcpu_events:
82
-bool kvm_arm_pmu_supported(CPUState *cs);
64
+ * @cpu: ARMCPU
83
+bool kvm_arm_pmu_supported(void);
65
+ *
84
66
+ * Get VCPU related state from kvm.
85
/**
67
+ */
86
* kvm_arm_sve_supported:
68
+int kvm_get_vcpu_events(ARMCPU *cpu);
87
- * @cs: CPUState
69
+
88
*
70
+/**
89
- * Returns true if the KVM VCPU can enable SVE and false otherwise.
71
+ * kvm_put_vcpu_events:
90
+ * Returns true if KVM can enable SVE and false otherwise.
72
+ * @cpu: ARMCPU
91
*/
73
+ *
92
-bool kvm_arm_sve_supported(CPUState *cs);
74
+ * Put VCPU related state to kvm.
93
+bool kvm_arm_sve_supported(void);
75
+ */
94
76
+int kvm_put_vcpu_events(ARMCPU *cpu);
95
/**
77
+
96
* kvm_arm_get_max_vm_ipa_size:
78
#ifdef CONFIG_KVM
97
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
79
/**
98
80
* kvm_arm_create_scratch_host_vcpu:
99
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
100
101
-static inline bool kvm_arm_aarch32_supported(CPUState *cs)
102
+static inline bool kvm_arm_aarch32_supported(void)
103
{
104
return false;
105
}
106
107
-static inline bool kvm_arm_pmu_supported(CPUState *cs)
108
+static inline bool kvm_arm_pmu_supported(void)
109
{
110
return false;
111
}
112
113
-static inline bool kvm_arm_sve_supported(CPUState *cs)
114
+static inline bool kvm_arm_sve_supported(void)
115
{
116
return false;
117
}
118
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/cpu.c
121
+++ b/target/arm/cpu.c
122
@@ -XXX,XX +XXX,XX @@ static void arm_set_pmu(Object *obj, bool value, Error **errp)
123
ARMCPU *cpu = ARM_CPU(obj);
124
125
if (value) {
126
- if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
127
+ if (kvm_enabled() && !kvm_arm_pmu_supported()) {
128
error_setg(errp, "'pmu' feature not supported by KVM on this host");
129
return;
130
}
131
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/cpu64.c
134
+++ b/target/arm/cpu64.c
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
136
137
/* Collect the set of vector lengths supported by KVM. */
138
bitmap_zero(kvm_supported, ARM_MAX_VQ);
139
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
140
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
141
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
142
} else if (kvm_enabled()) {
143
assert(!cpu_isar_feature(aa64_sve, cpu));
144
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
145
return;
146
}
147
148
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
149
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
150
error_setg(errp, "cannot set sve-max-vq");
151
error_append_hint(errp, "SVE not supported by KVM on this host\n");
152
return;
153
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
154
return;
155
}
156
157
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
158
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
159
error_setg(errp, "cannot enable %s", name);
160
error_append_hint(errp, "SVE not supported by KVM on this host\n");
161
return;
162
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
163
return;
164
}
165
166
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
167
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
168
error_setg(errp, "'sve' feature not supported by KVM on this host");
169
return;
170
}
171
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
172
* uniform execution state like do_interrupt.
173
*/
174
if (value == false) {
175
- if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
176
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
177
error_setg(errp, "'aarch64' feature cannot be disabled "
178
"unless KVM is enabled and 32-bit EL1 "
179
"is supported");
81
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
180
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
82
index XXXXXXX..XXXXXXX 100644
181
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/kvm.c
182
--- a/target/arm/kvm.c
84
+++ b/target/arm/kvm.c
183
+++ b/target/arm/kvm.c
85
@@ -XXX,XX +XXX,XX @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
184
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj)
86
};
185
}
87
186
}
88
static bool cap_has_mp_state;
187
89
+static bool cap_has_inject_serror_esr;
188
-bool kvm_arm_pmu_supported(CPUState *cpu)
90
189
+bool kvm_arm_pmu_supported(void)
91
static ARMHostCPUFeatures arm_host_cpu_features;
190
{
92
191
- return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
93
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs)
192
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
94
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
193
}
95
}
194
96
195
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
97
+void kvm_arm_init_serror_injection(CPUState *cs)
98
+{
99
+ cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
100
+ KVM_CAP_ARM_INJECT_SERROR_ESR);
101
+}
102
+
103
bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
104
int *fdarray,
105
struct kvm_vcpu_init *init)
106
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu)
107
return 0;
108
}
109
110
+int kvm_put_vcpu_events(ARMCPU *cpu)
111
+{
112
+ CPUARMState *env = &cpu->env;
113
+ struct kvm_vcpu_events events;
114
+ int ret;
115
+
116
+ if (!kvm_has_vcpu_events()) {
117
+ return 0;
118
+ }
119
+
120
+ memset(&events, 0, sizeof(events));
121
+ events.exception.serror_pending = env->serror.pending;
122
+
123
+ /* Inject SError to guest with specified syndrome if host kernel
124
+ * supports it, otherwise inject SError without syndrome.
125
+ */
126
+ if (cap_has_inject_serror_esr) {
127
+ events.exception.serror_has_esr = env->serror.has_esr;
128
+ events.exception.serror_esr = env->serror.esr;
129
+ }
130
+
131
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events);
132
+ if (ret) {
133
+ error_report("failed to put vcpu events");
134
+ }
135
+
136
+ return ret;
137
+}
138
+
139
+int kvm_get_vcpu_events(ARMCPU *cpu)
140
+{
141
+ CPUARMState *env = &cpu->env;
142
+ struct kvm_vcpu_events events;
143
+ int ret;
144
+
145
+ if (!kvm_has_vcpu_events()) {
146
+ return 0;
147
+ }
148
+
149
+ memset(&events, 0, sizeof(events));
150
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_VCPU_EVENTS, &events);
151
+ if (ret) {
152
+ error_report("failed to get vcpu events");
153
+ return ret;
154
+ }
155
+
156
+ env->serror.pending = events.exception.serror_pending;
157
+ env->serror.has_esr = events.exception.serror_has_esr;
158
+ env->serror.esr = events.exception.serror_esr;
159
+
160
+ return 0;
161
+}
162
+
163
void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
164
{
165
}
166
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/arm/kvm32.c
169
+++ b/target/arm/kvm32.c
170
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
171
}
172
cpu->mp_affinity = mpidr & ARM32_AFFINITY_MASK;
173
174
+ /* Check whether userspace can specify guest syndrome value */
175
+ kvm_arm_init_serror_injection(cs);
176
+
177
return kvm_arm_init_cpreg_list(cpu);
178
}
179
180
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
181
return ret;
182
}
183
184
+ ret = kvm_put_vcpu_events(cpu);
185
+ if (ret) {
186
+ return ret;
187
+ }
188
+
189
/* Note that we do not call write_cpustate_to_list()
190
* here, so we are only writing the tuple list back to
191
* KVM. This is safe because nothing can change the
192
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
193
}
194
vfp_set_fpscr(env, fpscr);
195
196
+ ret = kvm_get_vcpu_events(cpu);
197
+ if (ret) {
198
+ return ret;
199
+ }
200
+
201
if (!write_kvmstate_to_list(cpu)) {
202
return EINVAL;
203
}
204
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
196
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
205
index XXXXXXX..XXXXXXX 100644
197
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/kvm64.c
198
--- a/target/arm/kvm64.c
207
+++ b/target/arm/kvm64.c
199
+++ b/target/arm/kvm64.c
200
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
201
return true;
202
}
203
204
-bool kvm_arm_aarch32_supported(CPUState *cpu)
205
+bool kvm_arm_aarch32_supported(void)
206
{
207
- KVMState *s = KVM_STATE(current_accel());
208
-
209
- return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
210
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
211
}
212
213
-bool kvm_arm_sve_supported(CPUState *cpu)
214
+bool kvm_arm_sve_supported(void)
215
{
216
- KVMState *s = KVM_STATE(current_accel());
217
-
218
- return kvm_check_extension(s, KVM_CAP_ARM_SVE);
219
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
220
}
221
222
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
208
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
223
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
209
224
env->features &= ~(1ULL << ARM_FEATURE_PMU);
210
kvm_arm_init_debug(cs);
225
}
211
226
if (cpu_isar_feature(aa64_sve, cpu)) {
212
+ /* Check whether user space can specify guest syndrome value */
227
- assert(kvm_arm_sve_supported(cs));
213
+ kvm_arm_init_serror_injection(cs);
228
+ assert(kvm_arm_sve_supported());
214
+
229
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
215
return kvm_arm_init_cpreg_list(cpu);
230
}
216
}
231
217
218
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
219
return ret;
220
}
221
222
+ ret = kvm_put_vcpu_events(cpu);
223
+ if (ret) {
224
+ return ret;
225
+ }
226
+
227
if (!write_list_to_kvmstate(cpu, level)) {
228
return EINVAL;
229
}
230
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
231
}
232
vfp_set_fpcr(env, fpr);
233
234
+ ret = kvm_get_vcpu_events(cpu);
235
+ if (ret) {
236
+ return ret;
237
+ }
238
+
239
if (!write_kvmstate_to_list(cpu)) {
240
return EINVAL;
241
}
242
diff --git a/target/arm/machine.c b/target/arm/machine.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/target/arm/machine.c
245
+++ b/target/arm/machine.c
246
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sve = {
247
};
248
#endif /* AARCH64 */
249
250
+static bool serror_needed(void *opaque)
251
+{
252
+ ARMCPU *cpu = opaque;
253
+ CPUARMState *env = &cpu->env;
254
+
255
+ return env->serror.pending != 0;
256
+}
257
+
258
+static const VMStateDescription vmstate_serror = {
259
+ .name = "cpu/serror",
260
+ .version_id = 1,
261
+ .minimum_version_id = 1,
262
+ .needed = serror_needed,
263
+ .fields = (VMStateField[]) {
264
+ VMSTATE_UINT8(env.serror.pending, ARMCPU),
265
+ VMSTATE_UINT8(env.serror.has_esr, ARMCPU),
266
+ VMSTATE_UINT64(env.serror.esr, ARMCPU),
267
+ VMSTATE_END_OF_LIST()
268
+ }
269
+};
270
+
271
static bool m_needed(void *opaque)
272
{
273
ARMCPU *cpu = opaque;
274
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
275
#ifdef TARGET_AARCH64
276
&vmstate_sve,
277
#endif
278
+ &vmstate_serror,
279
NULL
280
}
281
};
282
--
232
--
283
2.19.1
233
2.20.1
284
234
285
235
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
Some cpu features may be enabled and disabled for all configurations
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
that support the feature. Let's test that.
5
Message-id: 20181016223115.24100-8-richard.henderson@linaro.org
5
6
A recent regression[*] inspired adding these tests.
7
8
[*] '-cpu host,pmu=on' caused a segfault
9
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20200623090622.30365-2-philmd@redhat.com
13
Message-Id: <20200623082310.17577-1-drjones@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
16
---
9
target/arm/cpu.h | 16 +++++++++++++++-
17
tests/qtest/arm-cpu-features.c | 38 ++++++++++++++++++++++++++++++----
10
linux-user/aarch64/signal.c | 4 ++--
18
1 file changed, 34 insertions(+), 4 deletions(-)
11
linux-user/elfload.c | 2 +-
12
linux-user/syscall.c | 10 ++++++----
13
target/arm/cpu64.c | 5 ++++-
14
target/arm/helper.c | 9 ++++++---
15
target/arm/machine.c | 3 +--
16
target/arm/translate-a64.c | 4 ++--
17
8 files changed, 37 insertions(+), 16 deletions(-)
18
19
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
--- a/tests/qtest/arm-cpu-features.c
22
+++ b/target/arm/cpu.h
23
+++ b/tests/qtest/arm-cpu-features.c
23
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
24
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
24
FIELD(ID_AA64ISAR1, SB, 36, 4)
25
qobject_unref(_resp); \
25
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
26
})
26
27
27
+FIELD(ID_AA64PFR0, EL0, 0, 4)
28
-#define assert_feature(qts, cpu_type, feature, expected_value) \
28
+FIELD(ID_AA64PFR0, EL1, 4, 4)
29
+#define resp_assert_feature(resp, feature, expected_value) \
29
+FIELD(ID_AA64PFR0, EL2, 8, 4)
30
({ \
30
+FIELD(ID_AA64PFR0, EL3, 12, 4)
31
- QDict *_resp, *_props; \
31
+FIELD(ID_AA64PFR0, FP, 16, 4)
32
+ QDict *_props; \
32
+FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
33
\
33
+FIELD(ID_AA64PFR0, GIC, 24, 4)
34
- _resp = do_query_no_props(qts, cpu_type); \
34
+FIELD(ID_AA64PFR0, RAS, 28, 4)
35
g_assert(_resp); \
35
+FIELD(ID_AA64PFR0, SVE, 32, 4)
36
g_assert(resp_has_props(_resp)); \
37
_props = resp_get_props(_resp); \
38
g_assert(qdict_get(_props, feature)); \
39
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
40
+})
36
+
41
+
37
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
42
+#define assert_feature(qts, cpu_type, feature, expected_value) \
38
43
+({ \
39
/* If adding a feature bit which corresponds to a Linux ELF
44
+ QDict *_resp; \
40
@@ -XXX,XX +XXX,XX @@ enum arm_features {
45
+ \
41
ARM_FEATURE_PMU, /* has PMU support */
46
+ _resp = do_query_no_props(qts, cpu_type); \
42
ARM_FEATURE_VBAR, /* has cp15 VBAR */
47
+ g_assert(_resp); \
43
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
48
+ resp_assert_feature(_resp, feature, expected_value); \
44
- ARM_FEATURE_SVE, /* has Scalable Vector Extension */
49
+ qobject_unref(_resp); \
45
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
50
+})
46
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
47
};
48
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
49
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
50
}
51
52
+static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
53
+{
54
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
55
+}
56
+
51
+
57
/*
52
+#define assert_set_feature(qts, cpu_type, feature, value) \
58
* Forward to the above feature tests given an ARMCPU pointer.
53
+({ \
59
*/
54
+ const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
60
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
55
+ QDict *_resp; \
61
index XXXXXXX..XXXXXXX 100644
56
+ \
62
--- a/linux-user/aarch64/signal.c
57
+ _resp = do_query(qts, cpu_type, _fmt, feature); \
63
+++ b/linux-user/aarch64/signal.c
58
+ g_assert(_resp); \
64
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
59
+ resp_assert_feature(_resp, feature, value); \
65
break;
60
qobject_unref(_resp); \
66
61
})
67
case TARGET_SVE_MAGIC:
62
68
- if (arm_feature(env, ARM_FEATURE_SVE)) {
63
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
69
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
64
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
70
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
65
71
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
66
/* Test expected feature presence/absence for some cpu types */
72
if (!sve && size == sve_size) {
67
- assert_has_feature_enabled(qts, "max", "pmu");
73
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
68
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
74
&layout);
69
assert_has_not_feature(qts, "cortex-a15", "aarch64");
75
70
76
/* SVE state needs saving only if it exists. */
71
+ /* Enabling and disabling pmu should always work. */
77
- if (arm_feature(env, ARM_FEATURE_SVE)) {
72
+ assert_has_feature_enabled(qts, "max", "pmu");
78
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
73
+ assert_set_feature(qts, "max", "pmu", false);
79
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
74
+ assert_set_feature(qts, "max", "pmu", true);
80
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
81
sve_ofs = alloc_sigframe_space(sve_size, &layout);
82
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/linux-user/elfload.c
85
+++ b/linux-user/elfload.c
86
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
87
GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
88
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
89
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
90
- GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
91
+ GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
92
93
#undef GET_FEATURE
94
#undef GET_FEATURE_ID
95
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/linux-user/syscall.c
98
+++ b/linux-user/syscall.c
99
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
100
* even though the current architectural maximum is VQ=16.
101
*/
102
ret = -TARGET_EINVAL;
103
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)
104
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(cpu_env))
105
&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
106
CPUARMState *env = cpu_env;
107
ARMCPU *cpu = arm_env_get_cpu(env);
108
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
109
return ret;
110
case TARGET_PR_SVE_GET_VL:
111
ret = -TARGET_EINVAL;
112
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
113
- CPUARMState *env = cpu_env;
114
- ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
115
+ {
116
+ ARMCPU *cpu = arm_env_get_cpu(cpu_env);
117
+ if (cpu_isar_feature(aa64_sve, cpu)) {
118
+ ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
119
+ }
120
}
121
return ret;
122
#endif /* AARCH64 */
123
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/target/arm/cpu64.c
126
+++ b/target/arm/cpu64.c
127
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
128
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
129
cpu->isar.id_aa64isar1 = t;
130
131
+ t = cpu->isar.id_aa64pfr0;
132
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
133
+ cpu->isar.id_aa64pfr0 = t;
134
+
75
+
135
/* Replicate the same data to the 32-bit id registers. */
76
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
136
u = cpu->isar.id_isar5;
77
137
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
78
if (g_str_equal(qtest_get_arch(), "aarch64")) {
138
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
79
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
139
* present in either.
140
*/
141
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
142
- set_feature(&cpu->env, ARM_FEATURE_SVE);
143
/* For usermode -cpu max we can use a larger and more efficient DCZ
144
* blocksize since we don't have to follow what the hardware does.
145
*/
146
diff --git a/target/arm/helper.c b/target/arm/helper.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/helper.c
149
+++ b/target/arm/helper.c
150
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
151
define_one_arm_cp_reg(cpu, &sctlr);
152
}
153
154
- if (arm_feature(env, ARM_FEATURE_SVE)) {
155
+ if (cpu_isar_feature(aa64_sve, cpu)) {
156
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
157
if (arm_feature(env, ARM_FEATURE_EL2)) {
158
define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
159
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
160
uint32_t flags;
161
162
if (is_a64(env)) {
163
+ ARMCPU *cpu = arm_env_get_cpu(env);
164
+
165
*pc = env->pc;
166
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
167
/* Get control bits for tagged addresses */
168
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
169
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
170
171
- if (arm_feature(env, ARM_FEATURE_SVE)) {
172
+ if (cpu_isar_feature(aa64_sve, cpu)) {
173
int sve_el = sve_exception_el(env, current_el);
174
uint32_t zcr_len;
175
176
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
177
void aarch64_sve_change_el(CPUARMState *env, int old_el,
178
int new_el, bool el0_a64)
179
{
180
+ ARMCPU *cpu = arm_env_get_cpu(env);
181
int old_len, new_len;
182
bool old_a64, new_a64;
183
184
/* Nothing to do if no SVE. */
185
- if (!arm_feature(env, ARM_FEATURE_SVE)) {
186
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
187
return;
80
return;
188
}
81
}
189
82
190
diff --git a/target/arm/machine.c b/target/arm/machine.c
83
+ /* Enabling and disabling kvm-no-adjvtime should always work. */
191
index XXXXXXX..XXXXXXX 100644
84
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
192
--- a/target/arm/machine.c
85
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
193
+++ b/target/arm/machine.c
86
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
194
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
87
195
static bool sve_needed(void *opaque)
88
if (g_str_equal(qtest_get_arch(), "aarch64")) {
196
{
89
bool kvm_supports_sve;
197
ARMCPU *cpu = opaque;
90
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
198
- CPUARMState *env = &cpu->env;
91
char *error;
199
92
200
- return arm_feature(env, ARM_FEATURE_SVE);
93
assert_has_feature_enabled(qts, "host", "aarch64");
201
+ return cpu_isar_feature(aa64_sve, cpu);
94
+
202
}
95
+ /* Enabling and disabling pmu should always work. */
203
96
assert_has_feature_enabled(qts, "host", "pmu");
204
/* The first two words of each Zreg is stored in VFP state. */
97
+ assert_set_feature(qts, "host", "pmu", false);
205
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
98
+ assert_set_feature(qts, "host", "pmu", true);
206
index XXXXXXX..XXXXXXX 100644
99
207
--- a/target/arm/translate-a64.c
100
assert_error(qts, "cortex-a15",
208
+++ b/target/arm/translate-a64.c
101
"We cannot guarantee the CPU type 'cortex-a15' works "
209
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
210
cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
211
vfp_get_fpcr(env), vfp_get_fpsr(env));
212
213
- if (arm_feature(env, ARM_FEATURE_SVE) && sve_exception_el(env, el) == 0) {
214
+ if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
215
int j, zcr_len = sve_zcr_len_for_el(env, el);
216
217
for (i = 0; i <= FFR_PRED_NUM; i++) {
218
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
219
unallocated_encoding(s);
220
break;
221
case 0x2:
222
- if (!arm_dc_feature(s, ARM_FEATURE_SVE) || !disas_sve(s, insn)) {
223
+ if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
224
unallocated_encoding(s);
225
}
226
break;
227
--
102
--
228
2.19.1
103
2.20.1
229
104
230
105
diff view generated by jsdifflib
Deleted patch
1
The A/I/F bits in ISR_EL1 should track the virtual interrupt
2
status, not the physical interrupt status, if the associated
3
HCR_EL2.AMO/IMO/FMO bit is set. Implement this, rather than
4
always showing the physical interrupt status.
5
1
6
We don't currently implement anything to do with external
7
aborts, so this applies only to the I and F bits (though it
8
ought to be possible for the outer guest to present a virtual
9
external abort to the inner guest, even if QEMU doesn't
10
emulate physical external aborts, so there is missing
11
functionality in this area).
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20181012144235.19646-6-peter.maydell@linaro.org
16
---
17
target/arm/helper.c | 22 ++++++++++++++++++----
18
1 file changed, 18 insertions(+), 4 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
25
CPUState *cs = ENV_GET_CPU(env);
26
uint64_t ret = 0;
27
28
- if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
29
- ret |= CPSR_I;
30
+ if (arm_hcr_el2_imo(env)) {
31
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
32
+ ret |= CPSR_I;
33
+ }
34
+ } else {
35
+ if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
36
+ ret |= CPSR_I;
37
+ }
38
}
39
- if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
40
- ret |= CPSR_F;
41
+
42
+ if (arm_hcr_el2_fmo(env)) {
43
+ if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
44
+ ret |= CPSR_F;
45
+ }
46
+ } else {
47
+ if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
48
+ ret |= CPSR_F;
49
+ }
50
}
51
+
52
/* External aborts are not possible in QEMU so A bit is always clear */
53
return ret;
54
}
55
--
56
2.19.1
57
58
diff view generated by jsdifflib
Deleted patch
1
If the HCR_EL2 PTW virtualizaiton configuration register bit
2
is set, then this means that a stage 2 Permission fault must
3
be generated if a stage 1 translation table access is made
4
to an address that is mapped as Device memory in stage 2.
5
Implement this.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181012144235.19646-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 21 ++++++++++++++++++++-
12
1 file changed, 20 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
19
hwaddr s2pa;
20
int s2prot;
21
int ret;
22
+ ARMCacheAttrs cacheattrs = {};
23
+ ARMCacheAttrs *pcacheattrs = NULL;
24
+
25
+ if (env->cp15.hcr_el2 & HCR_PTW) {
26
+ /*
27
+ * PTW means we must fault if this S1 walk touches S2 Device
28
+ * memory; otherwise we don't care about the attributes and can
29
+ * save the S2 translation the effort of computing them.
30
+ */
31
+ pcacheattrs = &cacheattrs;
32
+ }
33
34
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
35
- &txattrs, &s2prot, &s2size, fi, NULL);
36
+ &txattrs, &s2prot, &s2size, fi, pcacheattrs);
37
if (ret) {
38
assert(fi->type != ARMFault_None);
39
fi->s2addr = addr;
40
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
41
fi->s1ptw = true;
42
return ~0;
43
}
44
+ if (pcacheattrs && (pcacheattrs->attrs & 0xf0) == 0) {
45
+ /* Access was to Device memory: generate Permission fault */
46
+ fi->type = ARMFault_Permission;
47
+ fi->s2addr = addr;
48
+ fi->stage2 = true;
49
+ fi->s1ptw = true;
50
+ return ~0;
51
+ }
52
addr = s2pa;
53
}
54
return addr;
55
--
56
2.19.1
57
58
diff view generated by jsdifflib
Deleted patch
1
For the v7 version of the Arm architecture, the IL bit in
2
syndrome register values where the field is not valid was
3
defined to be UNK/SBZP. In v8 this is RES1, which is what
4
QEMU currently implements. Handle the desired v7 behaviour
5
by squashing the IL bit for the affected cases:
6
* EC == EC_UNCATEGORIZED
7
* prefetch aborts
8
* data aborts where ISV is 0
9
1
10
(The fourth case listed in the v8 Arm ARM DDI 0487C.a in
11
section G7.2.70, "illegal state exception", can't happen
12
on a v7 CPU.)
13
14
This deals with a corner case noted in a comment.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20181012144235.19646-10-peter.maydell@linaro.org
19
---
20
target/arm/internals.h | 7 ++-----
21
target/arm/helper.c | 13 +++++++++++++
22
2 files changed, 15 insertions(+), 5 deletions(-)
23
24
diff --git a/target/arm/internals.h b/target/arm/internals.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/internals.h
27
+++ b/target/arm/internals.h
28
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_get_ec(uint32_t syn)
29
/* Utility functions for constructing various kinds of syndrome value.
30
* Note that in general we follow the AArch64 syndrome values; in a
31
* few cases the value in HSR for exceptions taken to AArch32 Hyp
32
- * mode differs slightly, so if we ever implemented Hyp mode then the
33
- * syndrome value would need some massaging on exception entry.
34
- * (One example of this is that AArch64 defaults to IL bit set for
35
- * exceptions which don't specifically indicate information about the
36
- * trapping instruction, whereas AArch32 defaults to IL bit clear.)
37
+ * mode differs slightly, and we fix this up when populating HSR in
38
+ * arm_cpu_do_interrupt_aarch32_hyp().
39
*/
40
static inline uint32_t syn_uncategorized(void)
41
{
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
47
}
48
49
if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
50
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
51
+ /*
52
+ * QEMU syndrome values are v8-style. v7 has the IL bit
53
+ * UNK/SBZP for "field not valid" cases, where v8 uses RES1.
54
+ * If this is a v7 CPU, squash the IL bit in those cases.
55
+ */
56
+ if (cs->exception_index == EXCP_PREFETCH_ABORT ||
57
+ (cs->exception_index == EXCP_DATA_ABORT &&
58
+ !(env->exception.syndrome & ARM_EL_ISV)) ||
59
+ syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
60
+ env->exception.syndrome &= ~ARM_EL_IL;
61
+ }
62
+ }
63
env->cp15.esr_el[2] = env->exception.syndrome;
64
}
65
66
--
67
2.19.1
68
69
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
2
2
3
Move expanders for VBSL, VBIT, and VBIF from translate-a64.c.
3
This adds support for memory(pc-dimm) hot remove on arm/virt that
4
uses acpi ged device.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
NVDIMM hot removal is not yet supported.
6
Message-id: 20181011205206.3552-9-richard.henderson@linaro.org
7
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
9
Message-id: 20200622124157.20360-1-shameerali.kolothum.thodi@huawei.com
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/translate.h | 6 ++
14
hw/acpi/generic_event_device.c | 29 ++++++++++++++++
11
target/arm/translate-a64.c | 61 --------------
15
hw/arm/virt.c | 62 ++++++++++++++++++++++++++++++++--
12
target/arm/translate.c | 162 +++++++++++++++++++++++++++----------
16
2 files changed, 89 insertions(+), 2 deletions(-)
13
3 files changed, 124 insertions(+), 105 deletions(-)
14
17
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
20
--- a/hw/acpi/generic_event_device.c
18
+++ b/target/arm/translate.h
21
+++ b/hw/acpi/generic_event_device.c
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
22
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
20
return ret;
21
}
22
23
+
24
+/* Vector operations shared between ARM and AArch64. */
25
+extern const GVecGen3 bsl_op;
26
+extern const GVecGen3 bit_op;
27
+extern const GVecGen3 bif_op;
28
+
29
/*
30
* Forward to the isar_feature_* tests given a DisasContext pointer.
31
*/
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
35
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
37
}
23
}
38
}
24
}
39
25
40
-static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
26
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
41
-{
27
+ DeviceState *dev, Error **errp)
42
- tcg_gen_xor_i64(rn, rn, rm);
43
- tcg_gen_and_i64(rn, rn, rd);
44
- tcg_gen_xor_i64(rd, rm, rn);
45
-}
46
-
47
-static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
48
-{
49
- tcg_gen_xor_i64(rn, rn, rd);
50
- tcg_gen_and_i64(rn, rn, rm);
51
- tcg_gen_xor_i64(rd, rd, rn);
52
-}
53
-
54
-static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
55
-{
56
- tcg_gen_xor_i64(rn, rn, rd);
57
- tcg_gen_andc_i64(rn, rn, rm);
58
- tcg_gen_xor_i64(rd, rd, rn);
59
-}
60
-
61
-static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
62
-{
63
- tcg_gen_xor_vec(vece, rn, rn, rm);
64
- tcg_gen_and_vec(vece, rn, rn, rd);
65
- tcg_gen_xor_vec(vece, rd, rm, rn);
66
-}
67
-
68
-static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
69
-{
70
- tcg_gen_xor_vec(vece, rn, rn, rd);
71
- tcg_gen_and_vec(vece, rn, rn, rm);
72
- tcg_gen_xor_vec(vece, rd, rd, rn);
73
-}
74
-
75
-static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
76
-{
77
- tcg_gen_xor_vec(vece, rn, rn, rd);
78
- tcg_gen_andc_vec(vece, rn, rn, rm);
79
- tcg_gen_xor_vec(vece, rd, rd, rn);
80
-}
81
-
82
/* Logic op (opcode == 3) subgroup of C3.6.16. */
83
static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
84
{
85
- static const GVecGen3 bsl_op = {
86
- .fni8 = gen_bsl_i64,
87
- .fniv = gen_bsl_vec,
88
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
89
- .load_dest = true
90
- };
91
- static const GVecGen3 bit_op = {
92
- .fni8 = gen_bit_i64,
93
- .fniv = gen_bit_vec,
94
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
95
- .load_dest = true
96
- };
97
- static const GVecGen3 bif_op = {
98
- .fni8 = gen_bif_i64,
99
- .fniv = gen_bif_vec,
100
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
101
- .load_dest = true
102
- };
103
-
104
int rd = extract32(insn, 0, 5);
105
int rn = extract32(insn, 5, 5);
106
int rm = extract32(insn, 16, 5);
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
}
114
115
-/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
116
-static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
117
-{
118
- tcg_gen_and_i32(t, t, c);
119
- tcg_gen_andc_i32(f, f, c);
120
- tcg_gen_or_i32(dest, t, f);
121
-}
122
-
123
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
124
{
125
switch (size) {
126
@@ -XXX,XX +XXX,XX @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
127
return 1;
128
}
129
130
+/*
131
+ * Expanders for VBitOps_VBIF, VBIT, VBSL.
132
+ */
133
+static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
134
+{
28
+{
135
+ tcg_gen_xor_i64(rn, rn, rm);
29
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
136
+ tcg_gen_and_i64(rn, rn, rd);
30
+
137
+ tcg_gen_xor_i64(rd, rm, rn);
31
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
32
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
33
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
34
+ } else {
35
+ error_setg(errp, "acpi: device unplug request for unsupported device"
36
+ " type: %s", object_get_typename(OBJECT(dev)));
37
+ }
138
+}
38
+}
139
+
39
+
140
+static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
40
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
41
+ DeviceState *dev, Error **errp)
141
+{
42
+{
142
+ tcg_gen_xor_i64(rn, rn, rd);
43
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
143
+ tcg_gen_and_i64(rn, rn, rm);
44
+
144
+ tcg_gen_xor_i64(rd, rd, rn);
45
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
46
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
47
+ } else {
48
+ error_setg(errp, "acpi: device unplug for unsupported device"
49
+ " type: %s", object_get_typename(OBJECT(dev)));
50
+ }
145
+}
51
+}
146
+
52
+
147
+static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
53
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
54
{
55
AcpiGedState *s = ACPI_GED(adev);
56
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
57
dc->vmsd = &vmstate_acpi_ged;
58
59
hc->plug = acpi_ged_device_plug_cb;
60
+ hc->unplug_request = acpi_ged_unplug_request_cb;
61
+ hc->unplug = acpi_ged_unplug_cb;
62
63
adevc->send_event = acpi_ged_send_event;
64
}
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/virt.c
68
+++ b/hw/arm/virt.c
69
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
70
}
71
}
72
73
+static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
74
+ DeviceState *dev, Error **errp)
148
+{
75
+{
149
+ tcg_gen_xor_i64(rn, rn, rd);
76
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
150
+ tcg_gen_andc_i64(rn, rn, rm);
77
+ Error *local_err = NULL;
151
+ tcg_gen_xor_i64(rd, rd, rn);
78
+
79
+ if (!vms->acpi_dev) {
80
+ error_setg(&local_err,
81
+ "memory hotplug is not enabled: missing acpi-ged device");
82
+ goto out;
83
+ }
84
+
85
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
86
+ error_setg(&local_err,
87
+ "nvdimm device hot unplug is not supported yet.");
88
+ goto out;
89
+ }
90
+
91
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
92
+ &local_err);
93
+out:
94
+ error_propagate(errp, local_err);
152
+}
95
+}
153
+
96
+
154
+static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
97
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
98
+ DeviceState *dev, Error **errp)
155
+{
99
+{
156
+ tcg_gen_xor_vec(vece, rn, rn, rm);
100
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
157
+ tcg_gen_and_vec(vece, rn, rn, rd);
101
+ Error *local_err = NULL;
158
+ tcg_gen_xor_vec(vece, rd, rm, rn);
102
+
103
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
104
+ if (local_err) {
105
+ goto out;
106
+ }
107
+
108
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
109
+ qdev_unrealize(dev);
110
+
111
+out:
112
+ error_propagate(errp, local_err);
159
+}
113
+}
160
+
114
+
161
+static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
115
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
162
+{
116
DeviceState *dev, Error **errp)
163
+ tcg_gen_xor_vec(vece, rn, rn, rd);
117
{
164
+ tcg_gen_and_vec(vece, rn, rn, rm);
118
- error_setg(errp, "device unplug request for unsupported device"
165
+ tcg_gen_xor_vec(vece, rd, rd, rn);
119
- " type: %s", object_get_typename(OBJECT(dev)));
120
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
121
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
122
+ } else {
123
+ error_setg(errp, "device unplug request for unsupported device"
124
+ " type: %s", object_get_typename(OBJECT(dev)));
125
+ }
166
+}
126
+}
167
+
127
+
168
+static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
128
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
129
+ DeviceState *dev, Error **errp)
169
+{
130
+{
170
+ tcg_gen_xor_vec(vece, rn, rn, rd);
131
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
171
+ tcg_gen_andc_vec(vece, rn, rn, rm);
132
+ virt_dimm_unplug(hotplug_dev, dev, errp);
172
+ tcg_gen_xor_vec(vece, rd, rd, rn);
133
+ } else {
173
+}
134
+ error_setg(errp, "virt: device unplug for unsupported device"
174
+
135
+ " type: %s", object_get_typename(OBJECT(dev)));
175
+const GVecGen3 bsl_op = {
136
+ }
176
+ .fni8 = gen_bsl_i64,
137
}
177
+ .fniv = gen_bsl_vec,
138
178
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
139
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
179
+ .load_dest = true
140
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
180
+};
141
hc->pre_plug = virt_machine_device_pre_plug_cb;
181
+
142
hc->plug = virt_machine_device_plug_cb;
182
+const GVecGen3 bit_op = {
143
hc->unplug_request = virt_machine_device_unplug_request_cb;
183
+ .fni8 = gen_bit_i64,
144
+ hc->unplug = virt_machine_device_unplug_cb;
184
+ .fniv = gen_bit_vec,
145
mc->numa_mem_supported = true;
185
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
146
mc->nvdimm_supported = true;
186
+ .load_dest = true
147
mc->auto_enable_numa_with_memhp = true;
187
+};
188
+
189
+const GVecGen3 bif_op = {
190
+ .fni8 = gen_bif_i64,
191
+ .fniv = gen_bif_vec,
192
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
193
+ .load_dest = true
194
+};
195
+
196
+
197
/* Translate a NEON data processing instruction. Return nonzero if the
198
instruction is invalid.
199
We process data in a mixture of 32-bit and 64-bit chunks.
200
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
{
202
int op;
203
int q;
204
- int rd, rn, rm;
205
+ int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
206
int size;
207
int shift;
208
int pass;
209
int count;
210
int pairwise;
211
int u;
212
+ int vec_size;
213
uint32_t imm, mask;
214
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
215
TCGv_ptr ptr1, ptr2, ptr3;
216
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
217
VFP_DREG_N(rn, insn);
218
VFP_DREG_M(rm, insn);
219
size = (insn >> 20) & 3;
220
+ vec_size = q ? 16 : 8;
221
+ rd_ofs = neon_reg_offset(rd, 0);
222
+ rn_ofs = neon_reg_offset(rn, 0);
223
+ rm_ofs = neon_reg_offset(rm, 0);
224
+
225
if ((insn & (1 << 23)) == 0) {
226
/* Three register same length. */
227
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
228
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
229
q, rd, rn, rm);
230
}
231
return 1;
232
+
233
+ case NEON_3R_LOGIC: /* Logic ops. */
234
+ switch ((u << 2) | size) {
235
+ case 0: /* VAND */
236
+ tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
237
+ vec_size, vec_size);
238
+ break;
239
+ case 1: /* VBIC */
240
+ tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
241
+ vec_size, vec_size);
242
+ break;
243
+ case 2:
244
+ if (rn == rm) {
245
+ /* VMOV */
246
+ tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
247
+ } else {
248
+ /* VORR */
249
+ tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
250
+ vec_size, vec_size);
251
+ }
252
+ break;
253
+ case 3: /* VORN */
254
+ tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
255
+ vec_size, vec_size);
256
+ break;
257
+ case 4: /* VEOR */
258
+ tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
259
+ vec_size, vec_size);
260
+ break;
261
+ case 5: /* VBSL */
262
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
263
+ vec_size, vec_size, &bsl_op);
264
+ break;
265
+ case 6: /* VBIT */
266
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
267
+ vec_size, vec_size, &bit_op);
268
+ break;
269
+ case 7: /* VBIF */
270
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
271
+ vec_size, vec_size, &bif_op);
272
+ break;
273
+ }
274
+ return 0;
275
}
276
- if (size == 3 && op != NEON_3R_LOGIC) {
277
+ if (size == 3) {
278
/* 64-bit element instructions. */
279
for (pass = 0; pass < (q ? 2 : 1); pass++) {
280
neon_load_reg64(cpu_V0, rn + pass);
281
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
282
case NEON_3R_VRHADD:
283
GEN_NEON_INTEGER_OP(rhadd);
284
break;
285
- case NEON_3R_LOGIC: /* Logic ops. */
286
- switch ((u << 2) | size) {
287
- case 0: /* VAND */
288
- tcg_gen_and_i32(tmp, tmp, tmp2);
289
- break;
290
- case 1: /* BIC */
291
- tcg_gen_andc_i32(tmp, tmp, tmp2);
292
- break;
293
- case 2: /* VORR */
294
- tcg_gen_or_i32(tmp, tmp, tmp2);
295
- break;
296
- case 3: /* VORN */
297
- tcg_gen_orc_i32(tmp, tmp, tmp2);
298
- break;
299
- case 4: /* VEOR */
300
- tcg_gen_xor_i32(tmp, tmp, tmp2);
301
- break;
302
- case 5: /* VBSL */
303
- tmp3 = neon_load_reg(rd, pass);
304
- gen_neon_bsl(tmp, tmp, tmp2, tmp3);
305
- tcg_temp_free_i32(tmp3);
306
- break;
307
- case 6: /* VBIT */
308
- tmp3 = neon_load_reg(rd, pass);
309
- gen_neon_bsl(tmp, tmp, tmp3, tmp2);
310
- tcg_temp_free_i32(tmp3);
311
- break;
312
- case 7: /* VBIF */
313
- tmp3 = neon_load_reg(rd, pass);
314
- gen_neon_bsl(tmp, tmp3, tmp, tmp2);
315
- tcg_temp_free_i32(tmp3);
316
- break;
317
- }
318
- break;
319
case NEON_3R_VHSUB:
320
GEN_NEON_INTEGER_OP(hsub);
321
break;
322
--
148
--
323
2.19.1
149
2.20.1
324
150
325
151
diff view generated by jsdifflib