1
As promised, another pullreq... This one's mostly RTH's patches.
1
The following changes since commit a97978bcc2d1f650c7d411428806e5b03082b8c7:
2
2
3
thanks
3
Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.1-20210603' into staging (2021-06-03 10:00:35 +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-20210603
13
8
14
for you to fetch changes up to 88c9add25e7120e8622796c81ad3f3fb7f8d40e7:
9
for you to fetch changes up to 1c861885894d840235954060050d240259f5340b:
15
10
16
target/arm: Only flush tlb if ASID changes (2018-10-19 17:38:48 +0100)
11
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed (2021-06-03 16:43:27 +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
* Some not-yet-enabled preliminaries for M-profile MVE support
21
* Add support for VCPU event states
16
* Consistently use "Cortex-Axx", not "Cortex Axx" in docs, comments
22
* Move towards making ID registers the source of truth for
17
* docs: Fix installation of man pages with Sphinx 4.x
23
whether a guest CPU implements a feature, rather than having
18
* Mark LDS{MIN,MAX} as signed operations
24
parallel ID registers and feature bit flags
19
* Fix missing syndrome value for DAIF and PAC check exceptions
25
* Implement various HCR hypervisor trap/config bits
20
* Implement BFloat16 extensions
26
* Get IL bit correct for v7 syndrome values
21
* Refactoring of hvf accelerator code in preparation for aarch64 support
27
* Report correct syndrome for FP/SIMD traps to Hyp mode
22
* Fix some coverity nits in test code
28
* hw/arm/boot: Increase compliance with kernel arm64 boot protocol
29
* Refactor A32 Neon to use generic vector infrastructure
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
23
34
----------------------------------------------------------------
24
----------------------------------------------------------------
35
Dongjiu Geng (1):
25
Alexander Graf (12):
36
target/arm: Add support for VCPU event states
26
hvf: Move assert_hvf_ok() into common directory
27
hvf: Move vcpu thread functions into common directory
28
hvf: Move cpu functions into common directory
29
hvf: Move hvf internal definitions into common header
30
hvf: Make hvf_set_phys_mem() static
31
hvf: Remove use of hv_uvaddr_t and hv_gpaddr_t
32
hvf: Split out common code on vcpu init and destroy
33
hvf: Use cpu_synchronize_state()
34
hvf: Make synchronize functions static
35
hvf: Remove hvf-accel-ops.h
36
hvf: Introduce hvf vcpu struct
37
hvf: Simplify post reset/init/loadvm hooks
37
38
38
Edgar E. Iglesias (2):
39
Damien Goutte-Gattat (1):
39
net: cadence_gem: Announce availability of priority queues
40
docs: Fix installation of man pages with Sphinx 4.x
40
net: cadence_gem: Announce 64bit addressing support
41
41
42
Markus Armbruster (1):
42
Jamie Iles (4):
43
ssi-sd: Make devices picking up backends unavailable with -device
43
target/arm: fix missing exception class
44
target/arm: fold do_raise_exception into raise_exception
45
target/arm: use raise_exception_ra for MTE check failure
46
target/arm: use raise_exception_ra for stack limit exception
44
47
45
Peter Maydell (10):
48
Peter Maydell (15):
46
target/arm: Improve debug logging of AArch32 exception return
49
target/arm: Add isar feature check functions for MVE
47
target/arm: Make switch_mode() file-local
50
target/arm: Update feature checks for insns which are "MVE or FP"
48
target/arm: Implement HCR.FB
51
target/arm: Move fpsp/fpdp isar check into callers of do_vfp_2op_sp/dp
49
target/arm: Implement HCR.DC
52
target/arm: Add MVE check to VMOV_reg_sp and VMOV_reg_dp
50
target/arm: ISR_EL1 bits track virtual interrupts if IMO/FMO set
53
target/arm: Fix return values in fp_sysreg_checks()
51
target/arm: Implement HCR.VI and VF
54
target/arm: Implement M-profile VPR register
52
target/arm: Implement HCR.PTW
55
target/arm: Make FPSCR.LTPSIZE writable for MVE
53
target/arm: New utility function to extract EC from syndrome
56
target/arm: Allow board models to specify initial NS VTOR
54
target/arm: Get IL bit correct for v7 syndrome values
57
arm: Consistently use "Cortex-Axx", not "Cortex Axx"
55
target/arm: Report correct syndrome for FP/SIMD traps to Hyp mode
58
tests/qtest/bios-tables-test: Check for dup2() failure
59
tests/qtest/e1000e-test: Check qemu_recv() succeeded
60
tests/qtest/hd-geo-test: Fix checks on mkstemp() return value
61
tests/qtest/pflash-cfi02-test: Avoid potential integer overflow
62
tests/qtest/tpm-tests: Remove unnecessary NULL checks
63
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed
56
64
57
Richard Henderson (30):
65
Richard Henderson (13):
58
target/arm: Move some system registers into a substructure
66
target/arm: Mark LDS{MIN,MAX} as signed operations
59
target/arm: V8M should not imply V7VE
67
target/arm: Add isar_feature_{aa32, aa64, aa64_sve}_bf16
60
target/arm: Convert v8 extensions from feature bits to isar tests
68
target/arm: Unify unallocated path in disas_fp_1src
61
target/arm: Convert division from feature bits to isar0 tests
69
target/arm: Implement scalar float32 to bfloat16 conversion
62
target/arm: Convert jazelle from feature bit to isar1 test
70
target/arm: Implement vector float32 to bfloat16 conversion
63
target/arm: Convert t32ee from feature bit to isar3 test
71
softfpu: Add float_round_to_odd_inf
64
target/arm: Convert sve from feature bit to aa64pfr0 test
72
target/arm: Implement bfloat16 dot product (vector)
65
target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test
73
target/arm: Implement bfloat16 dot product (indexed)
66
target/arm: Hoist address increment for vector memory ops
74
target/arm: Implement bfloat16 matrix multiply accumulate
67
target/arm: Don't call tcg_clear_temp_count
75
target/arm: Implement bfloat widening fma (vector)
68
target/arm: Use tcg_gen_gvec_dup_i64 for LD[1-4]R
76
target/arm: Implement bfloat widening fma (indexed)
69
target/arm: Promote consecutive memory ops for aa64
77
linux-user/aarch64: Enable hwcap bits for bfloat16
70
target/arm: Mark some arrays const
78
target/arm: Enable BFloat16 extensions
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
79
89
Stewart Hildebrand (1):
80
docs/conf.py | 1 +
90
hw/arm/boot: Increase compliance with kernel arm64 boot protocol
81
docs/system/arm/aspeed.rst | 4 +-
82
docs/system/arm/nuvoton.rst | 6 +-
83
docs/system/arm/sabrelite.rst | 2 +-
84
include/fpu/softfloat-types.h | 4 +-
85
include/hw/arm/allwinner-h3.h | 2 +-
86
include/hw/arm/armv7m.h | 2 +
87
include/hw/core/cpu.h | 3 +-
88
include/sysemu/hvf_int.h | 58 +++++
89
target/arm/cpu.h | 48 +++-
90
target/arm/helper-sve.h | 4 +
91
target/arm/helper.h | 15 ++
92
target/i386/hvf/hvf-accel-ops.h | 23 --
93
target/i386/hvf/hvf-i386.h | 33 +--
94
target/i386/hvf/vmx.h | 24 +-
95
target/i386/hvf/x86hvf.h | 2 -
96
target/arm/neon-dp.decode | 1 +
97
target/arm/neon-shared.decode | 11 +
98
target/arm/sve.decode | 19 +-
99
target/arm/vfp.decode | 2 +
100
accel/hvf/hvf-accel-ops.c | 471 ++++++++++++++++++++++++++++++++++++++++
101
accel/hvf/hvf-all.c | 47 ++++
102
hw/arm/armv7m.c | 7 +
103
hw/arm/aspeed.c | 6 +-
104
hw/arm/mcimx6ul-evk.c | 2 +-
105
hw/arm/mcimx7d-sabre.c | 2 +-
106
hw/arm/npcm7xx_boards.c | 4 +-
107
hw/arm/sabrelite.c | 2 +-
108
hw/misc/npcm7xx_clk.c | 2 +-
109
linux-user/elfload.c | 2 +
110
target/arm/cpu.c | 13 ++
111
target/arm/cpu64.c | 3 +
112
target/arm/cpu_tcg.c | 1 +
113
target/arm/m_helper.c | 5 +-
114
target/arm/machine.c | 20 ++
115
target/arm/mte_helper.c | 12 +-
116
target/arm/op_helper.c | 32 ++-
117
target/arm/sve_helper.c | 2 +
118
target/arm/translate-a64.c | 155 +++++++++++--
119
target/arm/translate-neon.c | 91 ++++++++
120
target/arm/translate-sve.c | 112 ++++++++++
121
target/arm/translate-vfp.c | 164 ++++++++++----
122
target/arm/vec_helper.c | 140 +++++++++++-
123
target/arm/vfp_helper.c | 21 +-
124
target/i386/hvf/hvf-accel-ops.c | 146 -------------
125
target/i386/hvf/hvf.c | 464 +++++----------------------------------
126
target/i386/hvf/x86.c | 28 +--
127
target/i386/hvf/x86_descr.c | 26 +--
128
target/i386/hvf/x86_emu.c | 62 +++---
129
target/i386/hvf/x86_mmu.c | 4 +-
130
target/i386/hvf/x86_task.c | 12 +-
131
target/i386/hvf/x86hvf.c | 222 +++++++++----------
132
tests/qtest/bios-tables-test.c | 8 +-
133
tests/qtest/e1000e-test.c | 3 +-
134
tests/qtest/hd-geo-test.c | 4 +-
135
tests/qtest/pflash-cfi02-test.c | 2 +-
136
tests/qtest/tpm-tests.c | 12 +-
137
tests/unit/test-vmstate.c | 5 +-
138
fpu/softfloat-parts.c.inc | 6 +-
139
MAINTAINERS | 8 +
140
accel/hvf/meson.build | 7 +
141
accel/meson.build | 1 +
142
target/i386/hvf/meson.build | 1 -
143
63 files changed, 1666 insertions(+), 935 deletions(-)
144
create mode 100644 include/sysemu/hvf_int.h
145
delete mode 100644 target/i386/hvf/hvf-accel-ops.h
146
create mode 100644 accel/hvf/hvf-accel-ops.c
147
create mode 100644 accel/hvf/hvf-all.c
148
delete mode 100644 target/i386/hvf/hvf-accel-ops.c
149
create mode 100644 accel/hvf/meson.build
91
150
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
For AArch32, exception return happens through certain kinds
1
Add the isar feature check functions we will need for v8.1M MVE:
2
of CPSR write. We don't currently have any CPU_LOG_INT logging
2
* a check for MVE present: this corresponds to the pseudocode's
3
of these events (unlike AArch64, where we log in the ERET
3
CheckDecodeFaults(ExtType_Mve)
4
instruction). Add some suitable logging.
4
* a check for the optional floating-point part of MVE: this
5
5
corresponds to CheckDecodeFaults(ExtType_MveFp)
6
This will log exception returns like this:
7
Exception return from AArch32 hyp to usr PC 0x80100374
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
6
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20181012144235.19646-2-peter.maydell@linaro.org
9
Message-id: 20210520152840.24453-2-peter.maydell@linaro.org
20
---
10
---
21
target/arm/internals.h | 18 ++++++++++++++++++
11
target/arm/cpu.h | 22 ++++++++++++++++++++++
22
target/arm/helper.c | 10 ++++++++++
12
1 file changed, 22 insertions(+)
23
target/arm/translate.c | 7 +------
24
3 files changed, 29 insertions(+), 6 deletions(-)
25
13
26
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/internals.h
16
--- a/target/arm/cpu.h
29
+++ b/target/arm/internals.h
17
+++ b/target/arm/cpu.h
30
@@ -XXX,XX +XXX,XX @@ static inline uint32_t v7m_sp_limit(CPUARMState *env)
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
31
}
19
}
32
}
20
}
33
21
34
+/**
22
+static inline bool isar_feature_aa32_mve(const ARMISARegisters *id)
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
+{
23
+{
44
+ static const char cpu_mode_names[16][4] = {
24
+ /*
45
+ "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
25
+ * Return true if MVE is supported (either integer or floating point).
46
+ "???", "???", "hyp", "und", "???", "???", "???", "sys"
26
+ * We must check for M-profile as the MVFR1 field means something
47
+ };
27
+ * else for A-profile.
48
+
28
+ */
49
+ return cpu_mode_names[psr & 0xf];
29
+ return isar_feature_aa32_mprofile(id) &&
30
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0;
50
+}
31
+}
51
+
32
+
52
#endif
33
+static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id)
53
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
+{
54
index XXXXXXX..XXXXXXX 100644
35
+ /*
55
--- a/target/arm/helper.c
36
+ * Return true if MVE is supported (either integer or floating point).
56
+++ b/target/arm/helper.c
37
+ * We must check for M-profile as the MVFR1 field means something
57
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
38
+ * else for A-profile.
58
mask |= CPSR_IL;
39
+ */
59
val |= CPSR_IL;
40
+ return isar_feature_aa32_mprofile(id) &&
60
}
41
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2;
61
+ qemu_log_mask(LOG_GUEST_ERROR,
42
+}
62
+ "Illegal AArch32 mode switch attempt from %s to %s\n",
43
+
63
+ aarch32_mode_name(env->uncached_cpsr),
44
static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
64
+ aarch32_mode_name(val));
65
} else {
66
+ qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
67
+ write_type == CPSRWriteExceptionReturn ?
68
+ "Exception return from AArch32" :
69
+ "AArch32 mode switch from",
70
+ aarch32_mode_name(env->uncached_cpsr),
71
+ aarch32_mode_name(val), env->regs[15]);
72
switch_mode(env, val & CPSR_M);
73
}
74
}
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
80
translator_loop(ops, &dc.base, cpu, tb);
81
}
82
83
-static const char *cpu_mode_names[16] = {
84
- "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
85
- "???", "???", "hyp", "und", "???", "???", "???", "sys"
86
-};
87
-
88
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
89
int flags)
90
{
45
{
91
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
46
/*
92
psr & CPSR_V ? 'V' : '-',
93
psr & CPSR_T ? 'T' : 'A',
94
ns_status,
95
- cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
96
+ aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
97
}
98
99
if (flags & CPU_DUMP_FPU) {
100
--
47
--
101
2.19.1
48
2.20.1
102
49
103
50
diff view generated by jsdifflib
1
The HCR.DC virtualization configuration register bit has the
1
Some v8M instructions are present if either the floating point
2
following effects:
2
extension or MVE is implemented. Update our implementation of them
3
* SCTLR.M behaves as if it is 0 for all purposes except
3
to check for MVE as well as for FP.
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
4
12
Implement this behaviour.
5
This is all the insns which use CheckDecodeFaults(ExtType_MveOrFp) or
6
CheckDecodeFaults(ExtType_MveOrDpFp) in their pseudocode, which are
7
essentially the loads and stores, moves and sysreg accesses, except
8
for VMOV_reg_sp and VMOV_reg_dp, which we handle in subsequent
9
patches because they need a refactor to provide a place to put the
10
new MVE check.
13
11
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20181012144235.19646-5-peter.maydell@linaro.org
14
Message-id: 20210520152840.24453-3-peter.maydell@linaro.org
17
---
15
---
18
target/arm/helper.c | 23 +++++++++++++++++++++--
16
target/arm/translate-vfp.c | 48 +++++++++++++++++++++++---------------
19
1 file changed, 21 insertions(+), 2 deletions(-)
17
1 file changed, 29 insertions(+), 19 deletions(-)
20
18
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
21
--- a/target/arm/translate-vfp.c
24
+++ b/target/arm/helper.c
22
+++ b/target/arm/translate-vfp.c
25
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
26
* * The Non-secure TTBCR.EAE bit is set to 1
24
/* VMOV scalar to general purpose register */
27
* * The implementation includes EL2, and the value of HCR.VM is 1
25
TCGv_i32 tmp;
28
*
26
29
+ * (Note that HCR.DC makes HCR.VM behave as if it is 1.)
27
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
30
+ *
28
- if (a->size == MO_32
31
* ATS1Hx always uses the 64bit format (not supported yet).
29
- ? !dc_isar_feature(aa32_fpsp_v2, s)
32
*/
30
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
33
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
31
- return false;
34
32
+ /*
35
if (arm_feature(env, ARM_FEATURE_EL2)) {
33
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
36
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
34
+ * all sizes, whether the CPU has fp or not.
37
- format64 |= env->cp15.hcr_el2 & HCR_VM;
35
+ */
38
+ format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
36
+ if (!dc_isar_feature(aa32_mve, s)) {
39
} else {
37
+ if (a->size == MO_32
40
format64 |= arm_current_el(env) == 2;
38
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
41
}
39
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
42
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
40
+ return false;
41
+ }
43
}
42
}
44
43
45
if (mmu_idx == ARMMMUIdx_S2NS) {
44
/* UNDEF accesses to D16-D31 if they don't exist */
46
- return (env->cp15.hcr_el2 & HCR_VM) == 0;
45
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
47
+ /* HCR.DC means HCR.VM behaves as 1 */
46
/* VMOV general purpose register to scalar */
48
+ return (env->cp15.hcr_el2 & (HCR_DC | HCR_VM)) == 0;
47
TCGv_i32 tmp;
48
49
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
50
- if (a->size == MO_32
51
- ? !dc_isar_feature(aa32_fpsp_v2, s)
52
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
53
- return false;
54
+ /*
55
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
56
+ * all sizes, whether the CPU has fp or not.
57
+ */
58
+ if (!dc_isar_feature(aa32_mve, s)) {
59
+ if (a->size == MO_32
60
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
61
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
+ return false;
63
+ }
49
}
64
}
50
65
51
if (env->cp15.hcr_el2 & HCR_TGE) {
66
/* UNDEF accesses to D16-D31 if they don't exist */
52
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
67
@@ -XXX,XX +XXX,XX @@ typedef enum FPSysRegCheckResult {
53
}
68
69
static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
70
{
71
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
72
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
73
return FPSysRegCheckFailed;
54
}
74
}
55
75
56
+ if ((env->cp15.hcr_el2 & HCR_DC) &&
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
57
+ (mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1)) {
77
{
58
+ /* HCR.DC means SCTLR_EL1.M behaves as 0 */
78
TCGv_i32 tmp;
59
+ return true;
79
60
+ }
80
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
61
+
81
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
62
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
82
return false;
63
}
83
}
64
84
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
85
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
66
86
{
67
/* Combine the S1 and S2 cache attributes, if needed */
87
TCGv_i32 tmp;
68
if (!ret && cacheattrs != NULL) {
88
69
+ if (env->cp15.hcr_el2 & HCR_DC) {
89
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
70
+ /*
90
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
71
+ * HCR.DC forces the first stage attributes to
91
return false;
72
+ * Normal Non-Shareable,
92
}
73
+ * Inner Write-Back Read-Allocate Write-Allocate,
93
74
+ * Outer Write-Back Read-Allocate Write-Allocate.
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
75
+ */
95
* floating point register. Note that this does not require support
76
+ cacheattrs->attrs = 0xff;
96
* for double precision arithmetic.
77
+ cacheattrs->shareability = 0;
97
*/
78
+ }
98
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
79
*cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
99
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
80
}
100
return false;
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
104
uint32_t offset;
105
TCGv_i32 addr, tmp;
106
107
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
108
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
109
return false;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
113
uint32_t offset;
114
TCGv_i32 addr, tmp;
115
116
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
117
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
118
return false;
119
}
120
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
122
TCGv_i64 tmp;
123
124
/* Note that this does not require support for double arithmetic. */
125
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
126
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
127
return false;
128
}
129
130
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
131
TCGv_i32 addr, tmp;
132
int i, n;
133
134
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
135
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
136
return false;
137
}
138
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
140
int i, n;
141
142
/* Note that this does not require support for double arithmetic. */
143
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
145
return false;
146
}
81
147
82
--
148
--
83
2.19.1
149
2.20.1
84
150
85
151
diff view generated by jsdifflib
1
The switch_mode() function is defined in target/arm/helper.c and used
1
The do_vfp_2op_sp() and do_vfp_2op_dp() functions currently check
2
only in that file and nowhere else, so we can make it file-local
2
whether floating point is supported via the aa32_fpdp_v2 and
3
rather than global.
3
aa32_fpsp_v2 isar checks. For v8.1M MVE support, the VMOV_reg trans
4
functions (but not any of the others) need to update this to also
5
allow the insn if MVE is implemented. Move the check out of the do_
6
function and into its callsites (which are all implemented via the
7
DO_VFP_2OP macro), so we have a place to change the check for the
8
VMOV insns.
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20181012144235.19646-3-peter.maydell@linaro.org
12
Message-id: 20210520152840.24453-4-peter.maydell@linaro.org
8
---
13
---
9
target/arm/internals.h | 1 -
14
target/arm/translate-vfp.c | 37 +++++++++++++++++++------------------
10
target/arm/helper.c | 6 ++++--
15
1 file changed, 19 insertions(+), 18 deletions(-)
11
2 files changed, 4 insertions(+), 3 deletions(-)
12
16
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
19
--- a/target/arm/translate-vfp.c
16
+++ b/target/arm/internals.h
20
+++ b/target/arm/translate-vfp.c
17
@@ -XXX,XX +XXX,XX @@ static inline int bank_number(int mode)
21
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
18
g_assert_not_reached();
22
int veclen = s->vec_len;
23
TCGv_i32 f0, fd;
24
25
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
26
- return false;
27
- }
28
+ /* Note that the caller must check the aa32_fpsp_v2 feature. */
29
30
if (!dc_isar_feature(aa32_fpshvec, s) &&
31
(veclen != 0 || s->vec_stride != 0)) {
32
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
33
*/
34
TCGv_i32 f0;
35
36
+ /* Note that the caller must check the aa32_fp16_arith feature */
37
+
38
if (!dc_isar_feature(aa32_fp16_arith, s)) {
39
return false;
40
}
41
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
42
int veclen = s->vec_len;
43
TCGv_i64 f0, fd;
44
45
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
46
- return false;
47
- }
48
+ /* Note that the caller must check the aa32_fpdp_v2 feature. */
49
50
/* UNDEF accesses to D16-D31 if they don't exist */
51
if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
53
return true;
19
}
54
}
20
55
21
-void switch_mode(CPUARMState *, int);
56
-#define DO_VFP_2OP(INSN, PREC, FN) \
22
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
57
+#define DO_VFP_2OP(INSN, PREC, FN, CHECK) \
23
void arm_translate_init(void);
58
static bool trans_##INSN##_##PREC(DisasContext *s, \
24
59
arg_##INSN##_##PREC *a) \
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
{ \
26
index XXXXXXX..XXXXXXX 100644
61
+ if (!dc_isar_feature(CHECK, s)) { \
27
--- a/target/arm/helper.c
62
+ return false; \
28
+++ b/target/arm/helper.c
63
+ } \
29
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
64
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
30
V8M_SAttributes *sattrs);
65
}
31
#endif
66
32
67
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32)
33
+static void switch_mode(CPUARMState *env, int mode);
68
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64)
34
+
69
+DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
35
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
70
+DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
71
72
-DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh)
73
-DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss)
74
-DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd)
75
+DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
76
+DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
77
+DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd, aa32_fpdp_v2)
78
79
-DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh)
80
-DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs)
81
-DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd)
82
+DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh, aa32_fp16_arith)
83
+DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs, aa32_fpsp_v2)
84
+DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd, aa32_fpdp_v2)
85
86
static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm)
36
{
87
{
37
int nregs;
88
@@ -XXX,XX +XXX,XX @@ static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm)
38
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
89
gen_helper_vfp_sqrtd(vd, vm, cpu_env);
39
return 0;
40
}
90
}
41
91
42
-void switch_mode(CPUARMState *env, int mode)
92
-DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp)
43
+static void switch_mode(CPUARMState *env, int mode)
93
-DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp)
94
-DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp)
95
+DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith)
96
+DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp, aa32_fpsp_v2)
97
+DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp, aa32_fpdp_v2)
98
99
static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
44
{
100
{
45
ARMCPU *cpu = arm_env_get_cpu(env);
46
47
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
48
49
#else
50
51
-void switch_mode(CPUARMState *env, int mode)
52
+static void switch_mode(CPUARMState *env, int mode)
53
{
54
int old_mode;
55
int i;
56
--
101
--
57
2.19.1
102
2.20.1
58
103
59
104
diff view generated by jsdifflib
1
For the v7 version of the Arm architecture, the IL bit in
1
Split out the handling of VMOV_reg_sp and VMOV_reg_dp so that we can
2
syndrome register values where the field is not valid was
2
permit the insns if either FP or MVE are present.
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
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
3
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20181012144235.19646-10-peter.maydell@linaro.org
6
Message-id: 20210520152840.24453-5-peter.maydell@linaro.org
19
---
7
---
20
target/arm/internals.h | 7 ++-----
8
target/arm/translate-vfp.c | 15 +++++++++++++--
21
target/arm/helper.c | 13 +++++++++++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
22
2 files changed, 15 insertions(+), 5 deletions(-)
23
10
24
diff --git a/target/arm/internals.h b/target/arm/internals.h
11
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
25
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/internals.h
13
--- a/target/arm/translate-vfp.c
27
+++ b/target/arm/internals.h
14
+++ b/target/arm/translate-vfp.c
28
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_get_ec(uint32_t syn)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
29
/* Utility functions for constructing various kinds of syndrome value.
16
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
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
}
17
}
48
18
49
if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
19
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
50
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
20
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
51
+ /*
21
+#define DO_VFP_VMOV(INSN, PREC, FN) \
52
+ * QEMU syndrome values are v8-style. v7 has the IL bit
22
+ static bool trans_##INSN##_##PREC(DisasContext *s, \
53
+ * UNK/SBZP for "field not valid" cases, where v8 uses RES1.
23
+ arg_##INSN##_##PREC *a) \
54
+ * If this is a v7 CPU, squash the IL bit in those cases.
24
+ { \
55
+ */
25
+ if (!dc_isar_feature(aa32_fp##PREC##_v2, s) && \
56
+ if (cs->exception_index == EXCP_PREFETCH_ABORT ||
26
+ !dc_isar_feature(aa32_mve, s)) { \
57
+ (cs->exception_index == EXCP_DATA_ABORT &&
27
+ return false; \
58
+ !(env->exception.syndrome & ARM_EL_ISV)) ||
28
+ } \
59
+ syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
29
+ return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
60
+ env->exception.syndrome &= ~ARM_EL_IL;
30
+ }
61
+ }
31
+
62
+ }
32
+DO_VFP_VMOV(VMOV_reg, sp, tcg_gen_mov_i32)
63
env->cp15.esr_el[2] = env->exception.syndrome;
33
+DO_VFP_VMOV(VMOV_reg, dp, tcg_gen_mov_i64)
64
}
34
65
35
DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
36
DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
66
--
37
--
67
2.19.1
38
2.20.1
68
39
69
40
diff view generated by jsdifflib
1
If the HCR_EL2 PTW virtualizaiton configuration register bit
1
The fp_sysreg_checks() function is supposed to be returning an
2
is set, then this means that a stage 2 Permission fault must
2
FPSysRegCheckResult, which is an enum with three possible values.
3
be generated if a stage 1 translation table access is made
3
However, three places in the function "return false" (a hangover from
4
to an address that is mapped as Device memory in stage 2.
4
a previous iteration of the design where the function just returned a
5
Implement this.
5
bool). Make these return FPSysRegCheckFailed instead (for no
6
functional change, since both false and FPSysRegCheckFailed are
7
zero).
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181012144235.19646-8-peter.maydell@linaro.org
11
Message-id: 20210520152840.24453-6-peter.maydell@linaro.org
10
---
12
---
11
target/arm/helper.c | 21 ++++++++++++++++++++-
13
target/arm/translate-vfp.c | 6 +++---
12
1 file changed, 20 insertions(+), 1 deletion(-)
14
1 file changed, 3 insertions(+), 3 deletions(-)
13
15
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
18
--- a/target/arm/translate-vfp.c
17
+++ b/target/arm/helper.c
19
+++ b/target/arm/translate-vfp.c
18
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
20
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
19
hwaddr s2pa;
21
break;
20
int s2prot;
22
case ARM_VFP_FPSCR_NZCVQC:
21
int ret;
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
22
+ ARMCacheAttrs cacheattrs = {};
24
- return false;
23
+ ARMCacheAttrs *pcacheattrs = NULL;
25
+ return FPSysRegCheckFailed;
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
}
26
}
44
+ if (pcacheattrs && (pcacheattrs->attrs & 0xf0) == 0) {
27
break;
45
+ /* Access was to Device memory: generate Permission fault */
28
case ARM_VFP_FPCXT_S:
46
+ fi->type = ARMFault_Permission;
29
case ARM_VFP_FPCXT_NS:
47
+ fi->s2addr = addr;
30
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
48
+ fi->stage2 = true;
31
- return false;
49
+ fi->s1ptw = true;
32
+ return FPSysRegCheckFailed;
50
+ return ~0;
33
}
51
+ }
34
if (!s->v8m_secure) {
52
addr = s2pa;
35
- return false;
53
}
36
+ return FPSysRegCheckFailed;
54
return addr;
37
}
38
break;
39
default:
55
--
40
--
56
2.19.1
41
2.20.1
57
42
58
43
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
If MVE is implemented for an M-profile CPU then it has a VPR
2
register, which tracks predication information.
2
3
3
This patch extends the qemu-kvm state sync logic with support for
4
Implement the read and write handling of this register, and
4
KVM_GET/SET_VCPU_EVENTS, giving access to yet missing SError exception.
5
the migration of its state.
5
And also it can support the exception state migration.
6
6
7
The SError exception states include SError pending state and ESR value,
8
the kvm_put/get_vcpu_events() will be called when set or get system
9
registers. When do migration, if source machine has SError pending,
10
QEMU will do this migration regardless whether the target machine supports
11
to specify guest ESR value, because if target machine does not support that,
12
it can also inject the SError with zero ESR value.
13
14
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
15
Reviewed-by: Andrew Jones <drjones@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 1538067351-23931-3-git-send-email-gengdongjiu@huawei.com
18
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: 20210520152840.24453-7-peter.maydell@linaro.org
19
---
10
---
20
target/arm/cpu.h | 7 ++++++
11
target/arm/cpu.h | 6 ++++++
21
target/arm/kvm_arm.h | 24 ++++++++++++++++++
12
target/arm/machine.c | 19 +++++++++++++++++++
22
target/arm/kvm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++
13
target/arm/translate-vfp.c | 38 ++++++++++++++++++++++++++++++++++++++
23
target/arm/kvm32.c | 13 ++++++++++
14
3 files changed, 63 insertions(+)
24
target/arm/kvm64.c | 13 ++++++++++
25
target/arm/machine.c | 22 ++++++++++++++++
26
6 files changed, 139 insertions(+)
27
15
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
33
*/
21
uint32_t cpacr[M_REG_NUM_BANKS];
34
} exception;
22
uint32_t nsacr;
35
23
int ltpsize;
36
+ /* Information associated with an SError */
24
+ uint32_t vpr;
37
+ struct {
25
} v7m;
38
+ uint8_t pending;
26
39
+ uint8_t has_esr;
27
/* Information associated with an exception about to be taken:
40
+ uint64_t esr;
28
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_FPCCR, ASPEN, 31, 1)
41
+ } serror;
29
R_V7M_FPCCR_UFRDY_MASK | \
30
R_V7M_FPCCR_ASPEN_MASK)
31
32
+/* v7M VPR bits */
33
+FIELD(V7M_VPR, P0, 0, 16)
34
+FIELD(V7M_VPR, MASK01, 16, 4)
35
+FIELD(V7M_VPR, MASK23, 20, 4)
42
+
36
+
43
/* Thumb-2 EE state. */
37
/*
44
uint32_t teecr;
38
* System register ID fields.
45
uint32_t teehbr;
46
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/kvm_arm.h
49
+++ b/target/arm/kvm_arm.h
50
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu);
51
*/
39
*/
52
void kvm_arm_reset_vcpu(ARMCPU *cpu);
53
54
+/**
55
+ * kvm_arm_init_serror_injection:
56
+ * @cs: CPUState
57
+ *
58
+ * Check whether KVM can set guest SError syndrome.
59
+ */
60
+void kvm_arm_init_serror_injection(CPUState *cs);
61
+
62
+/**
63
+ * kvm_get_vcpu_events:
64
+ * @cpu: ARMCPU
65
+ *
66
+ * Get VCPU related state from kvm.
67
+ */
68
+int kvm_get_vcpu_events(ARMCPU *cpu);
69
+
70
+/**
71
+ * kvm_put_vcpu_events:
72
+ * @cpu: ARMCPU
73
+ *
74
+ * Put VCPU related state to kvm.
75
+ */
76
+int kvm_put_vcpu_events(ARMCPU *cpu);
77
+
78
#ifdef CONFIG_KVM
79
/**
80
* kvm_arm_create_scratch_host_vcpu:
81
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/kvm.c
84
+++ b/target/arm/kvm.c
85
@@ -XXX,XX +XXX,XX @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
86
};
87
88
static bool cap_has_mp_state;
89
+static bool cap_has_inject_serror_esr;
90
91
static ARMHostCPUFeatures arm_host_cpu_features;
92
93
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs)
94
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
95
}
96
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
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/kvm64.c
207
+++ b/target/arm/kvm64.c
208
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
209
210
kvm_arm_init_debug(cs);
211
212
+ /* Check whether user space can specify guest syndrome value */
213
+ kvm_arm_init_serror_injection(cs);
214
+
215
return kvm_arm_init_cpreg_list(cpu);
216
}
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
40
diff --git a/target/arm/machine.c b/target/arm/machine.c
243
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
244
--- a/target/arm/machine.c
42
--- a/target/arm/machine.c
245
+++ b/target/arm/machine.c
43
+++ b/target/arm/machine.c
246
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sve = {
44
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_fp = {
45
}
247
};
46
};
248
#endif /* AARCH64 */
47
249
48
+static bool mve_needed(void *opaque)
250
+static bool serror_needed(void *opaque)
251
+{
49
+{
252
+ ARMCPU *cpu = opaque;
50
+ ARMCPU *cpu = opaque;
253
+ CPUARMState *env = &cpu->env;
254
+
51
+
255
+ return env->serror.pending != 0;
52
+ return cpu_isar_feature(aa32_mve, cpu);
256
+}
53
+}
257
+
54
+
258
+static const VMStateDescription vmstate_serror = {
55
+static const VMStateDescription vmstate_m_mve = {
259
+ .name = "cpu/serror",
56
+ .name = "cpu/m/mve",
260
+ .version_id = 1,
57
+ .version_id = 1,
261
+ .minimum_version_id = 1,
58
+ .minimum_version_id = 1,
262
+ .needed = serror_needed,
59
+ .needed = mve_needed,
263
+ .fields = (VMStateField[]) {
60
+ .fields = (VMStateField[]) {
264
+ VMSTATE_UINT8(env.serror.pending, ARMCPU),
61
+ VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
265
+ VMSTATE_UINT8(env.serror.has_esr, ARMCPU),
266
+ VMSTATE_UINT64(env.serror.esr, ARMCPU),
267
+ VMSTATE_END_OF_LIST()
62
+ VMSTATE_END_OF_LIST()
268
+ }
63
+ },
269
+};
64
+};
270
+
65
+
271
static bool m_needed(void *opaque)
66
static const VMStateDescription vmstate_m = {
272
{
67
.name = "cpu/m",
273
ARMCPU *cpu = opaque;
68
.version_id = 4,
274
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
69
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
275
#ifdef TARGET_AARCH64
70
&vmstate_m_other_sp,
276
&vmstate_sve,
71
&vmstate_m_v8m,
277
#endif
72
&vmstate_m_fp,
278
+ &vmstate_serror,
73
+ &vmstate_m_mve,
279
NULL
74
NULL
280
}
75
}
281
};
76
};
77
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate-vfp.c
80
+++ b/target/arm/translate-vfp.c
81
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
82
return FPSysRegCheckFailed;
83
}
84
break;
85
+ case ARM_VFP_VPR:
86
+ case ARM_VFP_P0:
87
+ if (!dc_isar_feature(aa32_mve, s)) {
88
+ return FPSysRegCheckFailed;
89
+ }
90
+ break;
91
default:
92
return FPSysRegCheckFailed;
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
95
tcg_temp_free_i32(sfpa);
96
break;
97
}
98
+ case ARM_VFP_VPR:
99
+ /* Behaves as NOP if not privileged */
100
+ if (IS_USER(s)) {
101
+ break;
102
+ }
103
+ tmp = loadfn(s, opaque);
104
+ store_cpu_field(tmp, v7m.vpr);
105
+ break;
106
+ case ARM_VFP_P0:
107
+ {
108
+ TCGv_i32 vpr;
109
+ tmp = loadfn(s, opaque);
110
+ vpr = load_cpu_field(v7m.vpr);
111
+ tcg_gen_deposit_i32(vpr, vpr, tmp,
112
+ R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
113
+ store_cpu_field(vpr, v7m.vpr);
114
+ tcg_temp_free_i32(tmp);
115
+ break;
116
+ }
117
default:
118
g_assert_not_reached();
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
121
tcg_temp_free_i32(fpscr);
122
break;
123
}
124
+ case ARM_VFP_VPR:
125
+ /* Behaves as NOP if not privileged */
126
+ if (IS_USER(s)) {
127
+ break;
128
+ }
129
+ tmp = load_cpu_field(v7m.vpr);
130
+ storefn(s, opaque, tmp);
131
+ break;
132
+ case ARM_VFP_P0:
133
+ tmp = load_cpu_field(v7m.vpr);
134
+ tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
135
+ storefn(s, opaque, tmp);
136
+ break;
137
default:
138
g_assert_not_reached();
139
}
282
--
140
--
283
2.19.1
141
2.20.1
284
142
285
143
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile FPSCR has an LTPSIZE field, but if MVE is not
2
implemented it is read-only and always reads as 4; this is how QEMU
3
currently handles it.
2
4
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Make the field writable when MVE is implemented.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
5
Message-id: 20181016223115.24100-8-richard.henderson@linaro.org
7
We can safely add the field to the MVE migration struct because
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
currently no CPUs enable MVE and so the migration struct is never
9
used.
10
7
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: 20210520152840.24453-8-peter.maydell@linaro.org
8
---
14
---
9
target/arm/cpu.h | 16 +++++++++++++++-
15
target/arm/cpu.h | 3 ++-
10
linux-user/aarch64/signal.c | 4 ++--
16
target/arm/machine.c | 1 +
11
linux-user/elfload.c | 2 +-
17
target/arm/vfp_helper.c | 9 ++++++---
12
linux-user/syscall.c | 10 ++++++----
18
3 files changed, 9 insertions(+), 4 deletions(-)
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/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
24
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
FIELD(ID_AA64ISAR1, SB, 36, 4)
25
uint32_t fpdscr[M_REG_NUM_BANKS];
25
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
26
uint32_t cpacr[M_REG_NUM_BANKS];
26
27
uint32_t nsacr;
27
+FIELD(ID_AA64PFR0, EL0, 0, 4)
28
- int ltpsize;
28
+FIELD(ID_AA64PFR0, EL1, 4, 4)
29
+ uint32_t ltpsize;
29
+FIELD(ID_AA64PFR0, EL2, 8, 4)
30
uint32_t vpr;
30
+FIELD(ID_AA64PFR0, EL3, 12, 4)
31
} v7m;
31
+FIELD(ID_AA64PFR0, FP, 16, 4)
32
32
+FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
33
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
33
+FIELD(ID_AA64PFR0, GIC, 24, 4)
34
34
+FIELD(ID_AA64PFR0, RAS, 28, 4)
35
#define FPCR_LTPSIZE_SHIFT 16 /* LTPSIZE, M-profile only */
35
+FIELD(ID_AA64PFR0, SVE, 32, 4)
36
#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
36
+
37
+#define FPCR_LTPSIZE_LENGTH 3
37
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
38
38
39
#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
39
/* If adding a feature bit which corresponds to a Linux ELF
40
#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
40
@@ -XXX,XX +XXX,XX @@ enum arm_features {
41
ARM_FEATURE_PMU, /* has PMU support */
42
ARM_FEATURE_VBAR, /* has cp15 VBAR */
43
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
44
- ARM_FEATURE_SVE, /* has Scalable Vector Extension */
45
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
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
+
57
/*
58
* Forward to the above feature tests given an ARMCPU pointer.
59
*/
60
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/linux-user/aarch64/signal.c
63
+++ b/linux-user/aarch64/signal.c
64
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
65
break;
66
67
case TARGET_SVE_MAGIC:
68
- if (arm_feature(env, ARM_FEATURE_SVE)) {
69
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
70
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
71
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
72
if (!sve && size == sve_size) {
73
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
74
&layout);
75
76
/* SVE state needs saving only if it exists. */
77
- if (arm_feature(env, ARM_FEATURE_SVE)) {
78
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
79
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
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
+
135
/* Replicate the same data to the 32-bit id registers. */
136
u = cpu->isar.id_isar5;
137
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
138
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
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;
188
}
189
190
diff --git a/target/arm/machine.c b/target/arm/machine.c
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
191
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
192
--- a/target/arm/machine.c
43
--- a/target/arm/machine.c
193
+++ b/target/arm/machine.c
44
+++ b/target/arm/machine.c
194
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
45
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_mve = {
195
static bool sve_needed(void *opaque)
46
.needed = mve_needed,
47
.fields = (VMStateField[]) {
48
VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
49
+ VMSTATE_UINT32(env.v7m.ltpsize, ARMCPU),
50
VMSTATE_END_OF_LIST()
51
},
52
};
53
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/vfp_helper.c
56
+++ b/target/arm/vfp_helper.c
57
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
58
59
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
196
{
60
{
197
ARMCPU *cpu = opaque;
61
+ ARMCPU *cpu = env_archcpu(env);
198
- CPUARMState *env = &cpu->env;
62
+
199
63
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
200
- return arm_feature(env, ARM_FEATURE_SVE);
64
- if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
201
+ return cpu_isar_feature(aa64_sve, cpu);
65
+ if (!cpu_isar_feature(any_fp16, cpu)) {
202
}
66
val &= ~FPCR_FZ16;
203
67
}
204
/* The first two words of each Zreg is stored in VFP state. */
68
205
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
206
index XXXXXXX..XXXXXXX 100644
70
* because in v7A no-short-vector-support cores still had to
207
--- a/target/arm/translate-a64.c
71
* allow Stride/Len to be written with the only effect that
208
+++ b/target/arm/translate-a64.c
72
* some insns are required to UNDEF if the guest sets them.
209
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
73
- *
210
cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
74
- * TODO: if M-profile MVE implemented, set LTPSIZE.
211
vfp_get_fpcr(env), vfp_get_fpsr(env));
75
*/
212
76
env->vfp.vec_len = extract32(val, 16, 3);
213
- if (arm_feature(env, ARM_FEATURE_SVE) && sve_exception_el(env, el) == 0) {
77
env->vfp.vec_stride = extract32(val, 20, 2);
214
+ if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
78
+ } else if (cpu_isar_feature(aa32_mve, cpu)) {
215
int j, zcr_len = sve_zcr_len_for_el(env, el);
79
+ env->v7m.ltpsize = extract32(val, FPCR_LTPSIZE_SHIFT,
216
80
+ FPCR_LTPSIZE_LENGTH);
217
for (i = 0; i <= FFR_PRED_NUM; i++) {
81
}
218
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
82
219
unallocated_encoding(s);
83
if (arm_feature(env, ARM_FEATURE_NEON)) {
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
--
84
--
228
2.19.1
85
2.20.1
229
86
230
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently we allow board models to specify the initial value of the
2
Secure VTOR register, using an init-svtor property on the TYPE_ARMV7M
3
object which is plumbed through to the CPU. Allow board models to
4
also specify the initial value of the Non-secure VTOR via a similar
5
init-nsvtor property.
2
6
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20181016223115.24100-7-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
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: 20210520152840.24453-10-peter.maydell@linaro.org
8
---
10
---
9
target/arm/cpu.h | 6 +++++-
11
include/hw/arm/armv7m.h | 2 ++
10
linux-user/elfload.c | 2 +-
12
target/arm/cpu.h | 2 ++
11
target/arm/cpu.c | 4 ----
13
hw/arm/armv7m.c | 7 +++++++
12
target/arm/helper.c | 2 +-
14
target/arm/cpu.c | 10 ++++++++++
13
target/arm/machine.c | 3 +--
15
4 files changed, 21 insertions(+)
14
5 files changed, 8 insertions(+), 9 deletions(-)
15
16
17
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armv7m.h
20
+++ b/include/hw/arm/armv7m.h
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
22
* devices will be automatically layered on top of this view.)
23
* + Property "idau": IDAU interface (forwarded to CPU object)
24
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
25
+ * + Property "init-nsvtor": non-secure VTOR reset value (forwarded to CPU object)
26
* + Property "vfp": enable VFP (forwarded to CPU object)
27
* + Property "dsp": enable DSP (forwarded to CPU object)
28
* + Property "enable-bitband": expose bitbanded IO
29
@@ -XXX,XX +XXX,XX @@ struct ARMv7MState {
30
MemoryRegion *board_memory;
31
Object *idau;
32
uint32_t init_svtor;
33
+ uint32_t init_nsvtor;
34
bool enable_bitband;
35
bool start_powered_off;
36
bool vfp;
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
39
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
40
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
41
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
ARM_FEATURE_NEON,
42
22
ARM_FEATURE_M, /* Microcontroller profile. */
43
/* For v8M, initial value of the Secure VTOR */
23
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
44
uint32_t init_svtor;
24
- ARM_FEATURE_THUMB2EE,
45
+ /* For v8M, initial value of the Non-secure VTOR */
25
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
46
+ uint32_t init_nsvtor;
26
ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
47
27
ARM_FEATURE_V4T,
48
/* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_jazelle(const ARMISARegisters *id)
49
* QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
29
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
50
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
30
}
31
32
+static inline bool isar_feature_t32ee(const ARMISARegisters *id)
33
+{
34
+ return FIELD_EX32(id->id_isar3, ID_ISAR3, T32EE) != 0;
35
+}
36
+
37
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
38
{
39
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
40
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
41
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
42
--- a/linux-user/elfload.c
52
--- a/hw/arm/armv7m.c
43
+++ b/linux-user/elfload.c
53
+++ b/hw/arm/armv7m.c
44
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
54
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
45
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
55
return;
46
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
56
}
47
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
57
}
48
- GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
58
+ if (object_property_find(OBJECT(s->cpu), "init-nsvtor")) {
49
+ GET_FEATURE_ID(t32ee, ARM_HWCAP_ARM_THUMBEE);
59
+ if (!object_property_set_uint(OBJECT(s->cpu), "init-nsvtor",
50
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
60
+ s->init_nsvtor, errp)) {
51
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
61
+ return;
52
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
62
+ }
63
+ }
64
if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
65
if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
66
s->start_powered_off, errp)) {
67
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
68
MemoryRegion *),
69
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
70
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
71
+ DEFINE_PROP_UINT32("init-nsvtor", ARMv7MState, init_nsvtor, 0),
72
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
73
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
74
false),
53
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
54
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/cpu.c
77
--- a/target/arm/cpu.c
56
+++ b/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
57
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
58
set_feature(&cpu->env, ARM_FEATURE_V7);
80
env->regs[14] = 0xffffffff;
59
set_feature(&cpu->env, ARM_FEATURE_VFP3);
81
60
set_feature(&cpu->env, ARM_FEATURE_NEON);
82
env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80;
61
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
83
+ env->v7m.vecbase[M_REG_NS] = cpu->init_nsvtor & 0xffffff80;
62
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
84
63
set_feature(&cpu->env, ARM_FEATURE_EL3);
85
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
64
cpu->midr = 0x410fc080;
86
vecbase = env->v7m.vecbase[env->v7m.secure];
65
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
87
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
66
set_feature(&cpu->env, ARM_FEATURE_VFP3);
88
&cpu->init_svtor,
67
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
89
OBJ_PROP_FLAG_READWRITE);
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
}
90
}
97
- if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
91
+ if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
98
+ if (cpu_isar_feature(t32ee, cpu)) {
92
+ /*
99
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
93
+ * Initial value of the NS VTOR (for cores without the Security
100
}
94
+ * extension, this is the only VTOR)
101
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
95
+ */
102
diff --git a/target/arm/machine.c b/target/arm/machine.c
96
+ object_property_add_uint32_ptr(obj, "init-nsvtor",
103
index XXXXXXX..XXXXXXX 100644
97
+ &cpu->init_nsvtor,
104
--- a/target/arm/machine.c
98
+ OBJ_PROP_FLAG_READWRITE);
105
+++ b/target/arm/machine.c
99
+ }
106
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
100
107
static bool thumb2ee_needed(void *opaque)
101
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
108
{
102
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
--
103
--
118
2.19.1
104
2.20.1
119
105
120
106
diff view generated by jsdifflib
1
The HCR_EL2 VI and VF bits are supposed to track whether there is
1
The official punctuation for Arm CPU names uses a hyphen, like
2
a pending virtual IRQ or virtual FIQ. For QEMU we store the
2
"Cortex-A9". We mostly follow this, but in a few places usage
3
pending VIRQ/VFIQ status in cs->interrupt_request, so this means:
3
without the hyphen has crept in. Fix those so we consistently
4
* if the register is read we must get these bit values from
4
use the same way of writing the CPU name.
5
cs->interrupt_request
5
6
* if the register is written then we must write the bit
6
This commit was created with:
7
values back into cs->interrupt_request
7
git grep -z -l 'Cortex ' | xargs -0 sed -i 's/Cortex /Cortex-/'
8
8
9
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>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181012144235.19646-7-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20210527095152.10968-1-peter.maydell@linaro.org
12
---
14
---
13
target/arm/helper.c | 47 +++++++++++++++++++++++++++++++++++++++++----
15
docs/system/arm/aspeed.rst | 4 ++--
14
1 file changed, 43 insertions(+), 4 deletions(-)
16
docs/system/arm/nuvoton.rst | 6 +++---
15
17
docs/system/arm/sabrelite.rst | 2 +-
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
include/hw/arm/allwinner-h3.h | 2 +-
17
index XXXXXXX..XXXXXXX 100644
19
hw/arm/aspeed.c | 6 +++---
18
--- a/target/arm/helper.c
20
hw/arm/mcimx6ul-evk.c | 2 +-
19
+++ b/target/arm/helper.c
21
hw/arm/mcimx7d-sabre.c | 2 +-
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
22
hw/arm/npcm7xx_boards.c | 4 ++--
21
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
23
hw/arm/sabrelite.c | 2 +-
24
hw/misc/npcm7xx_clk.c | 2 +-
25
10 files changed, 16 insertions(+), 16 deletions(-)
26
27
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
28
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/system/arm/aspeed.rst
30
+++ b/docs/system/arm/aspeed.rst
31
@@ -XXX,XX +XXX,XX @@ The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
32
Aspeed evaluation boards. They are based on different releases of the
33
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
34
AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
35
-with dual cores ARM Cortex A7 CPUs (1.2GHz).
36
+with dual cores ARM Cortex-A7 CPUs (1.2GHz).
37
38
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
39
etc.
40
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
41
42
AST2600 SoC based machines :
43
44
-- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7)
45
+- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
46
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
47
48
Supported devices
49
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
50
index XXXXXXX..XXXXXXX 100644
51
--- a/docs/system/arm/nuvoton.rst
52
+++ b/docs/system/arm/nuvoton.rst
53
@@ -XXX,XX +XXX,XX @@ Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
54
55
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
56
designed to be used as Baseboard Management Controllers (BMCs) in various
57
-servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
58
+servers. They all feature one or two ARM Cortex-A9 CPU cores, as well as an
59
assortment of peripherals targeted for either Enterprise or Data Center /
60
Hyperscale applications. The former is a superset of the latter, so NPCM750 has
61
all the peripherals of NPCM730 and more.
62
63
.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
64
65
-The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
66
+The NPCM750 SoC has two Cortex-A9 cores and is targeted for the Enterprise
67
segment. The following machines are based on this chip :
68
69
- ``npcm750-evb`` Nuvoton NPCM750 Evaluation board
70
71
-The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
72
+The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
73
Hyperscale applications. The following machines are based on this chip :
74
75
- ``quanta-gsj`` Quanta GSJ server BMC
76
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
77
index XXXXXXX..XXXXXXX 100644
78
--- a/docs/system/arm/sabrelite.rst
79
+++ b/docs/system/arm/sabrelite.rst
80
@@ -XXX,XX +XXX,XX @@ Supported devices
81
82
The SABRE Lite machine supports the following devices:
83
84
- * Up to 4 Cortex A9 cores
85
+ * Up to 4 Cortex-A9 cores
86
* Generic Interrupt Controller
87
* 1 Clock Controller Module
88
* 1 System Reset Controller
89
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/hw/arm/allwinner-h3.h
92
+++ b/include/hw/arm/allwinner-h3.h
93
@@ -XXX,XX +XXX,XX @@
94
*/
95
96
/*
97
- * The Allwinner H3 is a System on Chip containing four ARM Cortex A7
98
+ * The Allwinner H3 is a System on Chip containing four ARM Cortex-A7
99
* processor cores. Features and specifications include DDR2/DDR3 memory,
100
* SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and
101
* various I/O modules.
102
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/arm/aspeed.c
105
+++ b/hw/arm/aspeed.c
106
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
107
MachineClass *mc = MACHINE_CLASS(oc);
108
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
109
110
- mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
111
+ mc->desc = "Aspeed AST2600 EVB (Cortex-A7)";
112
amc->soc_name = "ast2600-a1";
113
amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
114
amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
116
MachineClass *mc = MACHINE_CLASS(oc);
117
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
118
119
- mc->desc = "OpenPOWER Tacoma BMC (Cortex A7)";
120
+ mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)";
121
amc->soc_name = "ast2600-a1";
122
amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
123
amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
124
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
125
MachineClass *mc = MACHINE_CLASS(oc);
126
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
127
128
- mc->desc = "IBM Rainier BMC (Cortex A7)";
129
+ mc->desc = "IBM Rainier BMC (Cortex-A7)";
130
amc->soc_name = "ast2600-a1";
131
amc->hw_strap1 = RAINIER_BMC_HW_STRAP1;
132
amc->hw_strap2 = RAINIER_BMC_HW_STRAP2;
133
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/arm/mcimx6ul-evk.c
136
+++ b/hw/arm/mcimx6ul-evk.c
137
@@ -XXX,XX +XXX,XX @@ static void mcimx6ul_evk_init(MachineState *machine)
138
139
static void mcimx6ul_evk_machine_init(MachineClass *mc)
22
{
140
{
23
ARMCPU *cpu = arm_env_get_cpu(env);
141
- mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
24
+ CPUState *cs = ENV_GET_CPU(env);
142
+ mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex-A7)";
25
uint64_t valid_mask = HCR_MASK;
143
mc->init = mcimx6ul_evk_init;
26
144
mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
27
if (arm_feature(env, ARM_FEATURE_EL3)) {
145
mc->default_ram_id = "mcimx6ul-evk.ram";
28
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
146
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
29
/* Clear RES0 bits. */
147
index XXXXXXX..XXXXXXX 100644
30
value &= valid_mask;
148
--- a/hw/arm/mcimx7d-sabre.c
31
149
+++ b/hw/arm/mcimx7d-sabre.c
32
+ /*
150
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
33
+ * VI and VF are kept in cs->interrupt_request. Modifying that
151
34
+ * requires that we have the iothread lock, which is done by
152
static void mcimx7d_sabre_machine_init(MachineClass *mc)
35
+ * marking the reginfo structs as ARM_CP_IO.
153
{
36
+ * Note that if a write to HCR pends a VIRQ or VFIQ it is never
154
- mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
37
+ * possible for it to be taken immediately, because VIRQ and
155
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex-A7)";
38
+ * VFIQ are masked unless running at EL0 or EL1, and HCR
156
mc->init = mcimx7d_sabre_init;
39
+ * can only be written at EL2.
157
mc->max_cpus = FSL_IMX7_NUM_CPUS;
40
+ */
158
mc->default_ram_id = "mcimx7d-sabre.ram";
41
+ g_assert(qemu_mutex_iothread_locked());
159
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
42
+ if (value & HCR_VI) {
160
index XXXXXXX..XXXXXXX 100644
43
+ cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
161
--- a/hw/arm/npcm7xx_boards.c
44
+ } else {
162
+++ b/hw/arm/npcm7xx_boards.c
45
+ cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
163
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
46
+ }
164
47
+ if (value & HCR_VF) {
165
npcm7xx_set_soc_type(nmc, TYPE_NPCM750);
48
+ cs->interrupt_request |= CPU_INTERRUPT_VFIQ;
166
49
+ } else {
167
- mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex A9)";
50
+ cs->interrupt_request &= ~CPU_INTERRUPT_VFIQ;
168
+ mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex-A9)";
51
+ }
169
mc->init = npcm750_evb_init;
52
+ value &= ~(HCR_VI | HCR_VF);
170
mc->default_ram_size = 512 * MiB;
53
+
171
};
54
/* These bits change the MMU setup:
172
@@ -XXX,XX +XXX,XX @@ static void gsj_machine_class_init(ObjectClass *oc, void *data)
55
* HCR_VM enables stage 2 translation
173
56
* HCR_PTW forbids certain page-table setups
174
npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
57
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
175
58
hcr_write(env, NULL, value);
176
- mc->desc = "Quanta GSJ (Cortex A9)";
59
}
177
+ mc->desc = "Quanta GSJ (Cortex-A9)";
60
178
mc->init = quanta_gsj_init;
61
+static uint64_t hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
179
mc->default_ram_size = 512 * MiB;
62
+{
180
};
63
+ /* The VI and VF bits live in cs->interrupt_request */
181
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
64
+ uint64_t ret = env->cp15.hcr_el2 & ~(HCR_VI | HCR_VF);
182
index XXXXXXX..XXXXXXX 100644
65
+ CPUState *cs = ENV_GET_CPU(env);
183
--- a/hw/arm/sabrelite.c
66
+
184
+++ b/hw/arm/sabrelite.c
67
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
185
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
68
+ ret |= HCR_VI;
186
69
+ }
187
static void sabrelite_machine_init(MachineClass *mc)
70
+ if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
188
{
71
+ ret |= HCR_VF;
189
- mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
72
+ }
190
+ mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex-A9)";
73
+ return ret;
191
mc->init = sabrelite_init;
74
+}
192
mc->max_cpus = FSL_IMX6_NUM_CPUS;
75
+
193
mc->ignore_memory_transaction_failures = true;
76
static const ARMCPRegInfo el2_cp_reginfo[] = {
194
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
77
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
195
index XXXXXXX..XXXXXXX 100644
78
+ .type = ARM_CP_IO,
196
--- a/hw/misc/npcm7xx_clk.c
79
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
197
+++ b/hw/misc/npcm7xx_clk.c
80
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
198
@@ -XXX,XX +XXX,XX @@
81
- .writefn = hcr_write },
199
#define NPCM7XX_CLOCK_REF_HZ (25000000)
82
+ .writefn = hcr_write, .readfn = hcr_read },
200
83
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
201
/* Register Field Definitions */
84
- .type = ARM_CP_ALIAS,
202
-#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex A9 Cores */
85
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
203
+#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex-A9 Cores */
86
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
204
87
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
205
#define PLLCON_LOKI BIT(31)
88
- .writefn = hcr_writelow },
206
#define PLLCON_LOKS BIT(30)
89
+ .writefn = hcr_writelow, .readfn = hcr_read },
90
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
91
.type = ARM_CP_ALIAS,
92
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
93
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
94
95
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
96
{ .name = "HCR2", .state = ARM_CP_STATE_AA32,
97
- .type = ARM_CP_ALIAS,
98
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
99
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
100
.access = PL2_RW,
101
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
102
--
207
--
103
2.19.1
208
2.20.1
104
209
105
210
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Damien Goutte-Gattat <dgouttegattat@incenp.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
The 4.x branch of Sphinx introduces a breaking change, as generated man
4
Message-id: 20181011205206.3552-13-richard.henderson@linaro.org
4
pages are now written to subdirectories corresponding to the manual
5
section they belong to. This results in `make install` erroring out when
6
attempting to install the man pages, because they are not where it
7
expects to find them.
8
9
This patch restores the behavior of Sphinx 3.x regarding man pages.
10
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/256
12
Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
13
Message-id: 20210503161422.15028-1-dgouttegattat@incenp.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
16
---
8
target/arm/translate.c | 70 +++++++++++++++++++++++++++++-------------
17
docs/conf.py | 1 +
9
1 file changed, 48 insertions(+), 22 deletions(-)
18
1 file changed, 1 insertion(+)
10
19
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/docs/conf.py b/docs/conf.py
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
22
--- a/docs/conf.py
14
+++ b/target/arm/translate.c
23
+++ b/docs/conf.py
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
24
@@ -XXX,XX +XXX,XX @@
16
size--;
25
['Stefan Hajnoczi <stefanha@redhat.com>',
17
}
26
'Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>'], 1),
18
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
27
]
19
- /* To avoid excessive duplication of ops we implement shift
28
+man_make_section_directory = False
20
- by immediate using the variable shift operations. */
29
21
if (op < 8) {
30
# -- Options for Texinfo output -------------------------------------------
22
/* Shift by immediate:
23
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
25
}
26
/* Right shifts are encoded as N - shift, where N is the
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) {
102
- case 0: /* VSHR */
103
case 1: /* VSRA */
104
if (u)
105
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
107
cpu_V0, cpu_V1);
108
}
109
break;
110
+ default:
111
+ g_assert_not_reached();
112
}
113
if (op == 1 || op == 3) {
114
/* Accumulate. */
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
116
tmp2 = tcg_temp_new_i32();
117
tcg_gen_movi_i32(tmp2, imm);
118
switch (op) {
119
- case 0: /* VSHR */
120
case 1: /* VSRA */
121
GEN_NEON_INTEGER_OP(shl);
122
break;
123
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
124
case 7: /* VQSHL */
125
GEN_NEON_INTEGER_OP_ENV(qshl);
126
break;
127
+ default:
128
+ g_assert_not_reached();
129
}
130
tcg_temp_free_i32(tmp2);
131
31
132
--
32
--
133
2.19.1
33
2.20.1
134
34
135
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is done generically in translator_loop.
3
The operands to tcg_gen_atomic_fetch_s{min,max}_i64 must
4
be signed, so that the inputs are properly extended.
5
Zero extend the result afterward, as needed.
4
6
5
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/364
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20181011205206.3552-3-richard.henderson@linaro.org
10
Message-id: 20210602020720.47679-1-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/translate-a64.c | 1 -
13
target/arm/translate-a64.c | 13 ++++++++++---
13
target/arm/translate.c | 1 -
14
1 file changed, 10 insertions(+), 3 deletions(-)
14
2 files changed, 2 deletions(-)
15
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
18
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
20
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
21
21
int o3_opc = extract32(insn, 12, 4);
22
static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
22
bool r = extract32(insn, 22, 1);
23
{
23
bool a = extract32(insn, 23, 1);
24
- tcg_clear_temp_count();
24
- TCGv_i64 tcg_rs, clean_addr;
25
+ TCGv_i64 tcg_rs, tcg_rt, clean_addr;
26
AtomicThreeOpFn *fn = NULL;
27
+ MemOp mop = s->be_data | size | MO_ALIGN;
28
29
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
30
unallocated_encoding(s);
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
32
break;
33
case 004: /* LDSMAX */
34
fn = tcg_gen_atomic_fetch_smax_i64;
35
+ mop |= MO_SIGN;
36
break;
37
case 005: /* LDSMIN */
38
fn = tcg_gen_atomic_fetch_smin_i64;
39
+ mop |= MO_SIGN;
40
break;
41
case 006: /* LDUMAX */
42
fn = tcg_gen_atomic_fetch_umax_i64;
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
44
}
45
46
tcg_rs = read_cpu_reg(s, rs, true);
47
+ tcg_rt = cpu_reg(s, rt);
48
49
if (o3_opc == 1) { /* LDCLR */
50
tcg_gen_not_i64(tcg_rs, tcg_rs);
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
52
/* The tcg atomic primitives are all full barriers. Therefore we
53
* can ignore the Acquire and Release bits of this instruction.
54
*/
55
- fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
56
- s->be_data | size | MO_ALIGN);
57
+ fn(tcg_rt, clean_addr, tcg_rs, get_mem_index(s), mop);
58
+
59
+ if ((mop & MO_SIGN) && size != MO_64) {
60
+ tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
61
+ }
25
}
62
}
26
63
27
static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
64
/*
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
--
65
--
41
2.19.1
66
2.20.1
42
67
43
68
diff view generated by jsdifflib
1
Create and use a utility function to extract the EC field
1
From: Jamie Iles <jamie@nuviainc.com>
2
from a syndrome, rather than open-coding the shift.
3
2
3
The DAIF and PAC checks used raise_exception_ra to raise an exception
4
and unwind CPU state but raise_exception_ra is currently designed for
5
handling data aborts as the syndrome is partially precomputed and
6
encoded in the TB and then merged in merge_syn_data_abort when handling
7
the data abort. Using raise_exception_ra for DAIF and PAC checks
8
results in an empty syndrome being retrieved from data[2] in
9
restore_state_to_opc and setting ESR to 0. This manifested as:
10
11
kvm [571]: Unknown exception class: esr: 0x000000 –
12
Unknown/Uncategorized
13
14
when launching a KVM guest when the host qemu used a CPU supporting
15
EL2+pointer authentication and enabling pointer authentication in the
16
guest.
17
18
Rework raise_exception_ra such that the state is restored before raising
19
the exception so that the exception is not clobbered by
20
restore_state_to_opc.
21
22
Fixes: 0d43e1a2d29a ("target/arm: Add PAuth helpers")
23
Cc: Richard Henderson <richard.henderson@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
26
[PMM: added comment]
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181012144235.19646-9-peter.maydell@linaro.org
7
---
29
---
8
target/arm/internals.h | 5 +++++
30
target/arm/op_helper.c | 11 +++++++++--
9
target/arm/helper.c | 4 ++--
31
1 file changed, 9 insertions(+), 2 deletions(-)
10
target/arm/kvm64.c | 2 +-
11
target/arm/op_helper.c | 2 +-
12
4 files changed, 9 insertions(+), 4 deletions(-)
13
32
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
19
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
20
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
21
22
+static inline uint32_t syn_get_ec(uint32_t syn)
23
+{
24
+ return syn >> ARM_EL_EC_SHIFT;
25
+}
26
+
27
/* Utility functions for constructing various kinds of syndrome value.
28
* Note that in general we follow the AArch64 syndrome values; in a
29
* few cases the value in HSR for exceptions taken to AArch32 Hyp
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
35
uint32_t moe;
36
37
/* If this is a debug exception we must update the DBGDSCR.MOE bits */
38
- switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) {
39
+ switch (syn_get_ec(env->exception.syndrome)) {
40
case EC_BREAKPOINT:
41
case EC_BREAKPOINT_SAME_EL:
42
moe = 1;
43
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
44
if (qemu_loglevel_mask(CPU_LOG_INT)
45
&& !excp_is_internal(cs->exception_index)) {
46
qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
47
- env->exception.syndrome >> ARM_EL_EC_SHIFT,
48
+ syn_get_ec(env->exception.syndrome),
49
env->exception.syndrome);
50
}
51
52
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/kvm64.c
55
+++ b/target/arm/kvm64.c
56
@@ -XXX,XX +XXX,XX @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
57
58
bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
59
{
60
- int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
61
+ int hsr_ec = syn_get_ec(debug_exit->hsr);
62
ARMCPU *cpu = ARM_CPU(cs);
63
CPUClass *cc = CPU_GET_CLASS(cs);
64
CPUARMState *env = &cpu->env;
65
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
66
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/op_helper.c
35
--- a/target/arm/op_helper.c
68
+++ b/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
69
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
37
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
70
* (see DDI0478C.a D1.10.4)
38
void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
71
*/
39
uint32_t target_el, uintptr_t ra)
72
target_el = 2;
40
{
73
- if (syndrome >> ARM_EL_EC_SHIFT == EC_ADVSIMDFPACCESSTRAP) {
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
74
+ if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
42
- cpu_loop_exit_restore(cs, ra);
75
syndrome = syn_uncategorized();
43
+ CPUState *cs = env_cpu(env);
76
}
44
+
77
}
45
+ /*
46
+ * restore_state_to_opc() will set env->exception.syndrome, so
47
+ * we must restore CPU state here before setting the syndrome
48
+ * the caller passed us, and cannot use cpu_loop_exit_restore().
49
+ */
50
+ cpu_restore_state(cs, ra, true);
51
+ raise_exception(env, excp, syndrome, target_el);
52
}
53
54
uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,
78
--
55
--
79
2.19.1
56
2.20.1
80
57
81
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jamie Iles <jamie@nuviainc.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Now that there are no other users of do_raise_exception, fold it into
4
Message-id: 20181011205206.3552-18-richard.henderson@linaro.org
4
raise_exception.
5
[PMM: added parens in ?: expression]
5
6
Cc: Richard Henderson <richard.henderson@linaro.org>
7
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
target/arm/translate.c | 81 ++++++++++++++----------------------------
12
target/arm/op_helper.c | 12 ++----------
10
1 file changed, 26 insertions(+), 55 deletions(-)
13
1 file changed, 2 insertions(+), 10 deletions(-)
11
14
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate.c
17
--- a/target/arm/op_helper.c
15
+++ b/target/arm/translate.c
18
+++ b/target/arm/op_helper.c
16
@@ -XXX,XX +XXX,XX @@ static void gen_vfp_msr(TCGv_i32 tmp)
19
@@ -XXX,XX +XXX,XX @@
17
tcg_temp_free_i32(tmp);
20
#define SIGNBIT (uint32_t)0x80000000
18
}
21
#define SIGNBIT64 ((uint64_t)1 << 63)
19
22
20
-static void gen_neon_dup_u8(TCGv_i32 var, int shift)
23
-static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
21
-{
24
- uint32_t syndrome, uint32_t target_el)
22
- TCGv_i32 tmp = tcg_temp_new_i32();
25
+void raise_exception(CPUARMState *env, uint32_t excp,
23
- if (shift)
26
+ uint32_t syndrome, uint32_t target_el)
24
- tcg_gen_shri_i32(var, var, shift);
27
{
25
- tcg_gen_ext8u_i32(var, var);
28
CPUState *cs = env_cpu(env);
26
- tcg_gen_shli_i32(tmp, var, 8);
29
27
- tcg_gen_or_i32(var, var, tmp);
30
@@ -XXX,XX +XXX,XX @@ static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
28
- tcg_gen_shli_i32(tmp, var, 16);
31
cs->exception_index = excp;
29
- tcg_gen_or_i32(var, var, tmp);
32
env->exception.syndrome = syndrome;
30
- tcg_temp_free_i32(tmp);
33
env->exception.target_el = target_el;
34
-
35
- return cs;
31
-}
36
-}
32
-
37
-
33
static void gen_neon_dup_low16(TCGv_i32 var)
38
-void raise_exception(CPUARMState *env, uint32_t excp,
34
{
39
- uint32_t syndrome, uint32_t target_el)
35
TCGv_i32 tmp = tcg_temp_new_i32();
40
-{
36
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
37
tcg_temp_free_i32(tmp);
42
cpu_loop_exit(cs);
38
}
43
}
39
44
40
-static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
41
-{
42
- /* Load a single Neon element and replicate into a 32 bit TCG reg */
43
- TCGv_i32 tmp = tcg_temp_new_i32();
44
- switch (size) {
45
- case 0:
46
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
47
- gen_neon_dup_u8(tmp, 0);
48
- break;
49
- case 1:
50
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
51
- gen_neon_dup_low16(tmp);
52
- break;
53
- case 2:
54
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
55
- break;
56
- default: /* Avoid compiler warnings. */
57
- abort();
58
- }
59
- return tmp;
60
-}
61
-
62
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
63
uint32_t dp)
64
{
65
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
66
int load;
67
int shift;
68
int n;
69
+ int vec_size;
70
TCGv_i32 addr;
71
TCGv_i32 tmp;
72
TCGv_i32 tmp2;
73
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
74
}
75
addr = tcg_temp_new_i32();
76
load_reg_var(s, addr, rn);
77
- if (nregs == 1) {
78
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
79
- tmp = gen_load_and_replicate(s, addr, size);
80
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
81
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
82
- if (insn & (1 << 5)) {
83
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
84
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
85
- }
86
- tcg_temp_free_i32(tmp);
87
- } else {
88
- /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
89
- stride = (insn & (1 << 5)) ? 2 : 1;
90
- for (reg = 0; reg < nregs; reg++) {
91
- tmp = gen_load_and_replicate(s, addr, size);
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
--
45
--
128
2.19.1
46
2.20.1
129
47
130
48
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jamie Iles <jamie@nuviainc.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Now that raise_exception_ra restores the state before raising the
4
Message-id: 20181011205206.3552-12-richard.henderson@linaro.org
4
exception we can use restore_exception_ra to perform the state restore +
5
exception raising without clobbering the syndrome.
6
7
Cc: Richard Henderson <richard.henderson@linaro.org>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
10
[PMM: Keep the one line of the comment that is still relevant]
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/translate.c | 31 +++++++++++++++----------------
14
target/arm/mte_helper.c | 12 +++---------
9
1 file changed, 15 insertions(+), 16 deletions(-)
15
1 file changed, 3 insertions(+), 9 deletions(-)
10
16
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
19
--- a/target/arm/mte_helper.c
14
+++ b/target/arm/translate.c
20
+++ b/target/arm/mte_helper.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
16
vec_size, vec_size);
22
17
}
23
switch (tcf) {
18
return 0;
24
case 1:
19
+
25
- /*
20
+ case NEON_3R_VMUL: /* VMUL */
26
- * Tag check fail causes a synchronous exception.
21
+ if (u) {
27
- *
22
+ /* Polynomial case allows only P8 and is handled below. */
28
- * In restore_state_to_opc, we set the exception syndrome
23
+ if (size != 0) {
29
- * for the load or store operation. Unwind first so we
24
+ return 1;
30
- * may overwrite that with the syndrome for the tag check.
25
+ }
31
- */
26
+ } else {
32
- cpu_restore_state(env_cpu(env), ra, true);
27
+ tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
33
+ /* Tag check fail causes a synchronous exception. */
28
+ vec_size, vec_size);
34
env->exception.vaddress = dirty_ptr;
29
+ return 0;
35
30
+ }
36
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
31
+ break;
37
syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
32
}
38
is_write, 0x11);
33
if (size == 3) {
39
- raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
34
/* 64-bit element instructions. */
40
+ raise_exception_ra(env, EXCP_DATA_ABORT, syn,
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
+ exception_target_el(env), ra);
36
return 1;
42
/* noreturn, but fall through to the assert anyway */
37
}
43
38
break;
44
case 0:
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
--
45
--
68
2.19.1
46
2.20.1
69
47
70
48
diff view generated by jsdifflib
1
From: Markus Armbruster <armbru@redhat.com>
1
From: Jamie Iles <jamie@nuviainc.com>
2
2
3
Device models aren't supposed to go on fishing expeditions for
3
The sequence cpu_restore_state() + raise_exception() is equivalent to
4
backends. They should expose suitable properties for the user to set.
4
raise_exception_ra(), so use that instead. (In this case we never
5
For onboard devices, board code sets them.
5
cared about the syndrome value, because M-profile doesn't use the
6
syndrome; the old code was just written unnecessarily awkwardly.)
6
7
7
Device ssi-sd picks up its block backend in its init() method with
8
Cc: Richard Henderson <richard.henderson@linaro.org>
8
drive_get_next() instead. This mistake is already marked FIXME since
9
Cc: Peter Maydell <peter.maydell@linaro.org>
9
commit af9e40a.
10
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
10
11
[PMM: Retain edited version of comment; rewrite commit message]
11
Unset user_creatable to remove the mistake from our external
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
interface. Since the SSI bus doesn't support hotplug, only -device
13
can be affected. Only certain ARM machines have ssi-sd and provide an
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>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
14
---
23
hw/sd/ssi-sd.c | 2 ++
15
target/arm/m_helper.c | 5 +----
24
1 file changed, 2 insertions(+)
16
target/arm/op_helper.c | 9 +++------
17
2 files changed, 4 insertions(+), 10 deletions(-)
25
18
26
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
19
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
27
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/sd/ssi-sd.c
21
--- a/target/arm/m_helper.c
29
+++ b/hw/sd/ssi-sd.c
22
+++ b/target/arm/m_helper.c
30
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
23
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
31
k->cs_polarity = SSI_CS_LOW;
24
limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false];
32
dc->vmsd = &vmstate_ssi_sd;
25
33
dc->reset = ssi_sd_reset;
26
if (val < limit) {
34
+ /* Reason: init() method uses drive_get_next() */
27
- CPUState *cs = env_cpu(env);
35
+ dc->user_creatable = false;
28
-
29
- cpu_restore_state(cs, GETPC(), true);
30
- raise_exception(env, EXCP_STKOF, 0, 1);
31
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
32
}
33
34
if (is_psp) {
35
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/op_helper.c
38
+++ b/target/arm/op_helper.c
39
@@ -XXX,XX +XXX,XX @@ void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
40
* raising an exception if the limit is breached.
41
*/
42
if (newvalue < v7m_sp_limit(env)) {
43
- CPUState *cs = env_cpu(env);
44
-
45
/*
46
* Stack limit exceptions are a rare case, so rather than syncing
47
- * PC/condbits before the call, we use cpu_restore_state() to
48
- * get them right before raising the exception.
49
+ * PC/condbits before the call, we use raise_exception_ra() so
50
+ * that cpu_restore_state() will sort them out.
51
*/
52
- cpu_restore_state(cs, GETPC(), true);
53
- raise_exception(env, EXCP_STKOF, 0, 1);
54
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
55
}
36
}
56
}
37
57
38
static const TypeInfo ssi_sd_info = {
39
--
58
--
40
2.19.1
59
2.20.1
41
60
42
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Having V6 alone imply jazelle was wrong for cortex-m0.
3
Note that the SVE BFLOAT16 support does not require SVE2,
4
Change to an assertion for V6 & !M.
4
it is an independent extension.
5
5
6
This was harmless, because the only place we tested ARM_FEATURE_JAZELLE
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
was for 'bxj' in disas_arm(), which is unreachable for M-profile cores.
8
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181016223115.24100-6-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-2-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/cpu.h | 6 +++++-
11
target/arm/cpu.h | 15 +++++++++++++++
16
target/arm/cpu.c | 17 ++++++++++++++---
12
1 file changed, 15 insertions(+)
17
target/arm/translate.c | 2 +-
18
3 files changed, 20 insertions(+), 5 deletions(-)
19
13
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
25
ARM_FEATURE_PMU, /* has PMU support */
19
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
26
ARM_FEATURE_VBAR, /* has cp15 VBAR */
27
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
28
- ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
29
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
30
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_arm_div(const ARMISARegisters *id)
33
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
34
}
20
}
35
21
36
+static inline bool isar_feature_jazelle(const ARMISARegisters *id)
22
+static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
37
+{
23
+{
38
+ return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
24
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
39
+}
25
+}
40
+
26
+
41
static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
27
static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
42
{
28
{
43
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
45
index XXXXXXX..XXXXXXX 100644
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
46
--- a/target/arm/cpu.c
32
}
47
+++ b/target/arm/cpu.c
33
48
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
34
+static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
49
}
35
+{
50
if (arm_feature(env, ARM_FEATURE_V6)) {
36
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
51
set_feature(env, ARM_FEATURE_V5);
37
+}
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
}
57
}
58
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
59
set_feature(&cpu->env, ARM_FEATURE_VFP);
60
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
61
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
62
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
63
cpu->midr = 0x41069265;
64
cpu->reset_fpsid = 0x41011090;
65
cpu->ctr = 0x1dd20d2;
66
cpu->reset_sctlr = 0x00090078;
67
+
38
+
68
+ /*
39
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
69
+ * ARMv5 does not have the ID_ISAR registers, but we can still
40
{
70
+ * set the field to indicate Jazelle support within QEMU.
41
/* We always set the AdvSIMD and FP fields identically. */
71
+ */
42
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
72
+ cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
43
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
73
}
44
}
74
45
75
static void arm946_initfn(Object *obj)
46
+static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
76
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
47
+{
77
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
48
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
78
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
49
+}
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
+
50
+
87
+ /*
51
static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
88
+ * ARMv5 does not have the ID_ISAR registers, but we can still
52
{
89
+ * set the field to indicate Jazelle support within QEMU.
53
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
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
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@
101
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
102
/* currently all emulated v5 cores are also v5TE, so don't bother */
103
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
104
-#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
105
+#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
106
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
107
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
108
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
109
--
54
--
110
2.19.1
55
2.20.1
111
56
112
57
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For a sequence of loads or stores from a single register,
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20181011205206.3552-5-richard.henderson@linaro.org
5
Message-id: 20210525225817.400336-3-richard.henderson@linaro.org
9
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/translate-a64.c | 66 +++++++++++++++++++++++---------------
8
target/arm/translate-a64.c | 15 ++++++---------
13
1 file changed, 40 insertions(+), 26 deletions(-)
9
1 file changed, 6 insertions(+), 9 deletions(-)
14
10
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
13
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
15
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
20
16
int rd = extract32(insn, 0, 5);
21
/* Store from vector register to memory */
17
22
static void do_vec_st(DisasContext *s, int srcidx, int element,
18
if (mos) {
23
- TCGv_i64 tcg_addr, int size)
19
- unallocated_encoding(s);
24
+ TCGv_i64 tcg_addr, int size, TCGMemOp endian)
20
- return;
25
{
21
+ goto do_unallocated;
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
}
22
}
65
23
66
+ /* For our purposes, bytes are always little-endian. */
24
switch (opcode) {
67
+ if (size == 0) {
25
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
68
+ endian = MO_LE;
26
/* FCVT between half, single and double precision */
69
+ }
27
int dtype = extract32(opcode, 0, 2);
70
+
28
if (type == 2 || dtype == type) {
71
+ /* Consecutive little-endian elements from a single register
29
- unallocated_encoding(s);
72
+ * can be promoted to a larger little-endian operation.
30
- return;
73
+ */
31
+ goto do_unallocated;
74
+ if (selem == 1 && endian == MO_LE) {
32
}
75
+ size = 3;
33
if (!fp_access_check(s)) {
76
+ }
34
return;
77
+ ebytes = 1 << size;
35
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
78
+ elements = (is_q ? 16 : 8) / ebytes;
36
79
+
37
case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
80
tcg_rn = cpu_reg_sp(s, rn);
38
if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
81
tcg_addr = tcg_temp_new_i64();
39
- unallocated_encoding(s);
82
tcg_gen_mov_i64(tcg_addr, tcg_rn);
40
- return;
83
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
41
+ goto do_unallocated;
84
for (r = 0; r < rpt; r++) {
42
}
85
int e;
43
/* fall through */
86
for (e = 0; e < elements; e++) {
44
case 0x0 ... 0x3:
87
- int tt = (rt + r) % 32;
45
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
88
int xs;
46
break;
89
for (xs = 0; xs < selem; xs++) {
47
case 3:
90
+ int tt = (rt + r + xs) % 32;
48
if (!dc_isar_feature(aa64_fp16, s)) {
91
if (is_store) {
49
- unallocated_encoding(s);
92
- do_vec_st(s, tt, e, tcg_addr, size);
50
- return;
93
+ do_vec_st(s, tt, e, tcg_addr, size, endian);
51
+ goto do_unallocated;
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
}
52
}
53
54
if (!fp_access_check(s)) {
55
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
56
handle_fp_1src_half(s, opcode, rd, rn);
57
break;
58
default:
59
- unallocated_encoding(s);
60
+ goto do_unallocated;
113
}
61
}
62
break;
63
64
default:
65
+ do_unallocated:
66
unallocated_encoding(s);
67
break;
114
}
68
}
115
116
+ if (!is_store) {
117
+ /* For non-quad operations, setting a slice of the low
118
+ * 64 bits of the register clears the high 64 bits (in
119
+ * the ARM ARM pseudocode this is implicit in the fact
120
+ * that 'rval' is a 64 bit wide variable).
121
+ * For quad operations, we might still need to zero the
122
+ * high bits of SVE.
123
+ */
124
+ for (r = 0; r < rpt * selem; r++) {
125
+ int tt = (rt + r) % 32;
126
+ clear_vec_high(s, is_q, tt);
127
+ }
128
+ }
129
+
130
if (is_postidx) {
131
int rm = extract32(insn, 16, 5);
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
--
69
--
146
2.19.1
70
2.20.1
147
71
148
72
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Instead of shifts and masks, use direct loads and stores from the neon
3
This is the 64-bit BFCVT and the 32-bit VCVT{B,T}.BF16.F32.
4
register file. Mirror the iteration structure of the ARM pseudocode
5
more closely. Correct the parameters of the VLD2 A2 insn.
6
4
7
Note that this includes a bugfix for handling of the insn
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20181011205206.3552-19-richard.henderson@linaro.org
7
Message-id: 20210525225817.400336-4-richard.henderson@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
target/arm/translate.c | 170 ++++++++++++++++++-----------------------
10
target/arm/helper.h | 1 +
17
1 file changed, 74 insertions(+), 96 deletions(-)
11
target/arm/vfp.decode | 2 ++
12
target/arm/translate-a64.c | 19 +++++++++++++++++++
13
target/arm/translate-vfp.c | 24 ++++++++++++++++++++++++
14
target/arm/vfp_helper.c | 5 +++++
15
5 files changed, 51 insertions(+)
18
16
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
19
--- a/target/arm/helper.h
22
+++ b/target/arm/translate.c
20
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
24
return tmp;
22
23
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
24
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
25
+DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
26
27
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
28
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
29
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/vfp.decode
32
+++ b/target/arm/vfp.decode
33
@@ -XXX,XX +XXX,XX @@ VCVT_f64_f16 ---- 1110 1.11 0010 .... 1011 t:1 1.0 .... \
34
35
# VCVTB and VCVTT to f16: Vd format is always vd_sp;
36
# Vm format depends on size bit
37
+VCVT_b16_f32 ---- 1110 1.11 0011 .... 1001 t:1 1.0 .... \
38
+ vd=%vd_sp vm=%vm_sp
39
VCVT_f16_f32 ---- 1110 1.11 0011 .... 1010 t:1 1.0 .... \
40
vd=%vd_sp vm=%vm_sp
41
VCVT_f16_f64 ---- 1110 1.11 0011 .... 1011 t:1 1.0 .... \
42
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate-a64.c
45
+++ b/target/arm/translate-a64.c
46
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
47
case 0x3: /* FSQRT */
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
49
goto done;
50
+ case 0x6: /* BFCVT */
51
+ gen_fpst = gen_helper_bfcvt;
52
+ break;
53
case 0x8: /* FRINTN */
54
case 0x9: /* FRINTP */
55
case 0xa: /* FRINTM */
56
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
57
}
58
break;
59
60
+ case 0x6:
61
+ switch (type) {
62
+ case 1: /* BFCVT */
63
+ if (!dc_isar_feature(aa64_bf16, s)) {
64
+ goto do_unallocated;
65
+ }
66
+ if (!fp_access_check(s)) {
67
+ return;
68
+ }
69
+ handle_fp_1src_single(s, opcode, rd, rn);
70
+ break;
71
+ default:
72
+ goto do_unallocated;
73
+ }
74
+ break;
75
+
76
default:
77
do_unallocated:
78
unallocated_encoding(s);
79
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-vfp.c
82
+++ b/target/arm/translate-vfp.c
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
84
return true;
25
}
85
}
26
86
27
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
87
+static bool trans_VCVT_b16_f32(DisasContext *s, arg_VCVT_b16_f32 *a)
28
+{
88
+{
29
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
89
+ TCGv_ptr fpst;
90
+ TCGv_i32 tmp;
30
+
91
+
31
+ switch (mop) {
92
+ if (!dc_isar_feature(aa32_bf16, s)) {
32
+ case MO_UB:
93
+ return false;
33
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
34
+ break;
35
+ case MO_UW:
36
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
37
+ break;
38
+ case MO_UL:
39
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
40
+ break;
41
+ case MO_Q:
42
+ tcg_gen_ld_i64(var, cpu_env, offset);
43
+ break;
44
+ default:
45
+ g_assert_not_reached();
46
+ }
94
+ }
95
+
96
+ if (!vfp_access_check(s)) {
97
+ return true;
98
+ }
99
+
100
+ fpst = fpstatus_ptr(FPST_FPCR);
101
+ tmp = tcg_temp_new_i32();
102
+
103
+ vfp_load_reg32(tmp, a->vm);
104
+ gen_helper_bfcvt(tmp, tmp, fpst);
105
+ tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
106
+ tcg_temp_free_ptr(fpst);
107
+ tcg_temp_free_i32(tmp);
108
+ return true;
47
+}
109
+}
48
+
110
+
49
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
111
static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
50
{
112
{
51
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
113
TCGv_ptr fpst;
52
tcg_temp_free_i32(var);
114
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/vfp_helper.c
117
+++ b/target/arm/vfp_helper.c
118
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
119
return float64_to_float32(x, &env->vfp.fp_status);
53
}
120
}
54
121
55
+static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
122
+uint32_t HELPER(bfcvt)(float32 x, void *status)
56
+{
123
+{
57
+ long offset = neon_element_offset(reg, ele, size);
124
+ return float32_to_bfloat16(x, status);
58
+
59
+ switch (size) {
60
+ case MO_8:
61
+ tcg_gen_st8_i64(var, cpu_env, offset);
62
+ break;
63
+ case MO_16:
64
+ tcg_gen_st16_i64(var, cpu_env, offset);
65
+ break;
66
+ case MO_32:
67
+ tcg_gen_st32_i64(var, cpu_env, offset);
68
+ break;
69
+ case MO_64:
70
+ tcg_gen_st_i64(var, cpu_env, offset);
71
+ break;
72
+ default:
73
+ g_assert_not_reached();
74
+ }
75
+}
125
+}
76
+
126
+
77
static inline void neon_load_reg64(TCGv_i64 var, int reg)
127
/*
78
{
128
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
79
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
129
* must always round-to-nearest; the AArch64 ones honour the FPSCR
80
@@ -XXX,XX +XXX,XX @@ static struct {
81
int interleave;
82
int spacing;
83
} const neon_ls_element_type[11] = {
84
- {4, 4, 1},
85
- {4, 4, 2},
86
+ {1, 4, 1},
87
+ {1, 4, 2},
88
{4, 1, 1},
89
- {4, 2, 1},
90
- {3, 3, 1},
91
- {3, 3, 2},
92
+ {2, 2, 2},
93
+ {1, 3, 1},
94
+ {1, 3, 2},
95
{3, 1, 1},
96
{1, 1, 1},
97
- {2, 2, 1},
98
- {2, 2, 2},
99
+ {1, 2, 1},
100
+ {1, 2, 2},
101
{2, 1, 1}
102
};
103
104
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
105
int shift;
106
int n;
107
int vec_size;
108
+ int mmu_idx;
109
+ TCGMemOp endian;
110
TCGv_i32 addr;
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 {
162
- tmp = neon_load_reg(rd, pass);
163
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
164
- tcg_temp_free_i32(tmp);
165
- }
166
- tcg_gen_addi_i32(addr, addr, stride);
167
- } else if (size == 1) {
168
- if (load) {
169
- tmp = tcg_temp_new_i32();
170
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
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
--
130
--
247
2.19.1
131
2.20.1
248
132
249
133
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move mla_op and mls_op expanders from translate-a64.c.
3
This is BFCVT{N,T} for both AArch64 AdvSIMD and SVE,
4
4
and VCVT.BF16.F32 for AArch32 NEON.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-16-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-5-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.h | 2 +
11
target/arm/helper-sve.h | 4 ++++
11
target/arm/translate-a64.c | 106 -----------------------------
12
target/arm/helper.h | 1 +
12
target/arm/translate.c | 134 ++++++++++++++++++++++++++++++++-----
13
target/arm/neon-dp.decode | 1 +
13
3 files changed, 120 insertions(+), 122 deletions(-)
14
target/arm/sve.decode | 2 ++
14
15
target/arm/sve_helper.c | 2 ++
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
target/arm/translate-a64.c | 17 ++++++++++++++
16
index XXXXXXX..XXXXXXX 100644
17
target/arm/translate-neon.c | 45 +++++++++++++++++++++++++++++++++++++
17
--- a/target/arm/translate.h
18
target/arm/translate-sve.c | 16 +++++++++++++
18
+++ b/target/arm/translate.h
19
target/arm/vfp_helper.c | 7 ++++++
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
20
9 files changed, 95 insertions(+)
20
extern const GVecGen3 bsl_op;
21
21
extern const GVecGen3 bit_op;
22
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
22
extern const GVecGen3 bif_op;
23
index XXXXXXX..XXXXXXX 100644
23
+extern const GVecGen3 mla_op[4];
24
--- a/target/arm/helper-sve.h
24
+extern const GVecGen3 mls_op[4];
25
+++ b/target/arm/helper-sve.h
25
extern const GVecGen2i ssra_op[4];
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
26
extern const GVecGen2i usra_op[4];
27
void, ptr, ptr, ptr, ptr, i32)
27
extern const GVecGen2i sri_op[4];
28
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
29
void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve_bfcvt, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
33
DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
34
void, ptr, ptr, ptr, ptr, i32)
35
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_fcvtnt_sh, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve2_fcvtnt_ds, TCG_CALL_NO_RWG,
38
void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(sve_bfcvtnt, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_5(sve2_fcvtlt_hs, TCG_CALL_NO_RWG,
43
void, ptr, ptr, ptr, ptr, i32)
44
diff --git a/target/arm/helper.h b/target/arm/helper.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper.h
47
+++ b/target/arm/helper.h
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
49
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
50
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
51
DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
52
+DEF_HELPER_FLAGS_2(bfcvt_pair, TCG_CALL_NO_RWG, i32, i64, ptr)
53
54
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
55
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
56
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/neon-dp.decode
59
+++ b/target/arm/neon-dp.decode
60
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
61
VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
62
63
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
64
+ VCVT_B16_F32 1111 001 11 . 11 .. 10 .... 0 1100 1 . 0 .... @2misc_q0
65
66
VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
67
68
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/sve.decode
71
+++ b/target/arm/sve.decode
72
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
73
# SVE floating-point convert precision
74
FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
75
FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
76
+BFCVT 01100101 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
77
FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
78
FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
79
FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
80
@@ -XXX,XX +XXX,XX @@ RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
81
FCVTXNT_ds 01100100 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
82
FCVTX_ds 01100101 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
83
FCVTNT_sh 01100100 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
84
+BFCVTNT 01100100 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
85
FCVTLT_hs 01100100 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
86
FCVTNT_ds 01100100 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
87
FCVTLT_sd 01100100 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
88
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/sve_helper.c
91
+++ b/target/arm/sve_helper.c
92
@@ -XXX,XX +XXX,XX @@ static inline uint64_t vfp_float64_to_uint64_rtz(float64 f, float_status *s)
93
94
DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_bfcvt, uint32_t, H1_4, float32_to_bfloat16)
97
DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
98
DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
99
DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
100
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
101
} while (i != 0); \
102
}
103
104
+DO_FCVTNT(sve_bfcvtnt, uint32_t, uint16_t, H1_4, H1_2, float32_to_bfloat16)
105
DO_FCVTNT(sve2_fcvtnt_sh, uint32_t, uint16_t, H1_4, H1_2, sve_f32_to_f16)
106
DO_FCVTNT(sve2_fcvtnt_ds, uint64_t, uint32_t, , H1_4, float64_to_float32)
107
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
108
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
110
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
111
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
112
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
33
}
113
tcg_temp_free_i32(ahp);
34
}
35
36
-static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
37
-{
38
- gen_helper_neon_mul_u8(a, a, b);
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
{
99
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
100
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
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
}
114
}
286
break;
115
break;
287
+
116
+ case 0x36: /* BFCVTN, BFCVTN2 */
288
+ case NEON_3R_VML: /* VMLA, VMLS */
117
+ {
289
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
118
+ TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
290
+ u ? &mls_op[size] : &mla_op[size]);
119
+ gen_helper_bfcvt_pair(tcg_res[pass], tcg_op, fpst);
291
+ return 0;
120
+ tcg_temp_free_ptr(fpst);
292
}
121
+ }
293
+
122
+ break;
294
if (size == 3) {
123
case 0x56: /* FCVTXN, FCVTXN2 */
295
/* 64-bit element instructions. */
124
/* 64 bit to 32 bit float conversion
296
for (pass = 0; pass < (q ? 2 : 1); pass++) {
125
* with von Neumann rounding (round to odd)
297
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
126
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
298
}
299
}
127
}
300
break;
128
handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
301
- case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
129
return;
302
- switch (size) {
130
+ case 0x36: /* BFCVTN, BFCVTN2 */
303
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
131
+ if (!dc_isar_feature(aa64_bf16, s) || size != 2) {
304
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
132
+ unallocated_encoding(s);
305
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
133
+ return;
306
- default: abort();
134
+ }
307
- }
135
+ if (!fp_access_check(s)) {
308
- tcg_temp_free_i32(tmp2);
136
+ return;
309
- tmp2 = neon_load_reg(rd, pass);
137
+ }
310
- if (u) { /* VMLS */
138
+ handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
311
- gen_neon_rsb(size, tmp, tmp2);
139
+ return;
312
- } else { /* VMLA */
140
case 0x17: /* FCVTL, FCVTL2 */
313
- gen_neon_add(size, tmp, tmp2);
141
if (!fp_access_check(s)) {
314
- }
142
return;
315
- break;
143
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
316
case NEON_3R_VMUL:
144
index XXXXXXX..XXXXXXX 100644
317
/* VMUL.P8; other cases already eliminated. */
145
--- a/target/arm/translate-neon.c
318
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
146
+++ b/target/arm/translate-neon.c
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
148
return true;
149
}
150
151
+static bool trans_VCVT_B16_F32(DisasContext *s, arg_2misc *a)
152
+{
153
+ TCGv_ptr fpst;
154
+ TCGv_i64 tmp;
155
+ TCGv_i32 dst0, dst1;
156
+
157
+ if (!dc_isar_feature(aa32_bf16, s)) {
158
+ return false;
159
+ }
160
+
161
+ /* UNDEF accesses to D16-D31 if they don't exist. */
162
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
163
+ ((a->vd | a->vm) & 0x10)) {
164
+ return false;
165
+ }
166
+
167
+ if ((a->vm & 1) || (a->size != 1)) {
168
+ return false;
169
+ }
170
+
171
+ if (!vfp_access_check(s)) {
172
+ return true;
173
+ }
174
+
175
+ fpst = fpstatus_ptr(FPST_STD);
176
+ tmp = tcg_temp_new_i64();
177
+ dst0 = tcg_temp_new_i32();
178
+ dst1 = tcg_temp_new_i32();
179
+
180
+ read_neon_element64(tmp, a->vm, 0, MO_64);
181
+ gen_helper_bfcvt_pair(dst0, tmp, fpst);
182
+
183
+ read_neon_element64(tmp, a->vm, 1, MO_64);
184
+ gen_helper_bfcvt_pair(dst1, tmp, fpst);
185
+
186
+ write_neon_element32(dst0, a->vd, 0, MO_32);
187
+ write_neon_element32(dst1, a->vd, 1, MO_32);
188
+
189
+ tcg_temp_free_i64(tmp);
190
+ tcg_temp_free_i32(dst0);
191
+ tcg_temp_free_i32(dst1);
192
+ tcg_temp_free_ptr(fpst);
193
+ return true;
194
+}
195
+
196
static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
197
{
198
TCGv_ptr fpst;
199
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/target/arm/translate-sve.c
202
+++ b/target/arm/translate-sve.c
203
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a)
204
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
205
}
206
207
+static bool trans_BFCVT(DisasContext *s, arg_rpr_esz *a)
208
+{
209
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
210
+ return false;
211
+ }
212
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvt);
213
+}
214
+
215
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a)
216
{
217
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
218
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTNT_sh(DisasContext *s, arg_rpr_esz *a)
219
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve2_fcvtnt_sh);
220
}
221
222
+static bool trans_BFCVTNT(DisasContext *s, arg_rpr_esz *a)
223
+{
224
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
225
+ return false;
226
+ }
227
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvtnt);
228
+}
229
+
230
static bool trans_FCVTNT_ds(DisasContext *s, arg_rpr_esz *a)
231
{
232
if (!dc_isar_feature(aa64_sve2, s)) {
233
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/target/arm/vfp_helper.c
236
+++ b/target/arm/vfp_helper.c
237
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(bfcvt)(float32 x, void *status)
238
return float32_to_bfloat16(x, status);
239
}
240
241
+uint32_t HELPER(bfcvt_pair)(uint64_t pair, void *status)
242
+{
243
+ bfloat16 lo = float32_to_bfloat16(extract64(pair, 0, 32), status);
244
+ bfloat16 hi = float32_to_bfloat16(extract64(pair, 32, 32), status);
245
+ return deposit32(lo, 16, 16, hi);
246
+}
247
+
248
/*
249
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
250
* must always round-to-nearest; the AArch64 ones honour the FPSCR
319
--
251
--
320
2.19.1
252
2.20.1
321
253
322
254
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For Arm BFDOT and BFMMLA, we need a version of round-to-odd
4
that overflows to infinity, instead of the max normal number.
5
6
Cc: Alex Bennée <alex.bennee@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-11-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-6-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate.c | 16 ++++++++--------
12
include/fpu/softfloat-types.h | 4 +++-
9
1 file changed, 8 insertions(+), 8 deletions(-)
13
fpu/softfloat-parts.c.inc | 6 ++++--
14
2 files changed, 7 insertions(+), 3 deletions(-)
10
15
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
18
--- a/include/fpu/softfloat-types.h
14
+++ b/target/arm/translate.c
19
+++ b/include/fpu/softfloat-types.h
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
16
tcg_temp_free_ptr(ptr1);
21
float_round_up = 2,
17
tcg_temp_free_ptr(ptr2);
22
float_round_to_zero = 3,
18
break;
23
float_round_ties_away = 4,
19
+
24
- /* Not an IEEE rounding mode: round to the closest odd mantissa value */
20
+ case NEON_2RM_VMVN:
25
+ /* Not an IEEE rounding mode: round to closest odd, overflow to max */
21
+ tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
26
float_round_to_odd = 5,
22
+ break;
27
+ /* Not an IEEE rounding mode: round to closest odd, overflow to inf */
23
+ case NEON_2RM_VNEG:
28
+ float_round_to_odd_inf = 6,
24
+ tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
29
} FloatRoundMode;
25
+ break;
30
26
+
31
/*
27
default:
32
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
28
elementwise:
33
index XXXXXXX..XXXXXXX 100644
29
for (pass = 0; pass < (q ? 4 : 2); pass++) {
34
--- a/fpu/softfloat-parts.c.inc
30
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
35
+++ b/fpu/softfloat-parts.c.inc
31
case NEON_2RM_VCNT:
36
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
32
gen_helper_neon_cnt_u8(tmp, tmp);
37
g_assert_not_reached();
33
break;
38
}
34
- case NEON_2RM_VMVN:
39
35
- tcg_gen_not_i32(tmp, tmp);
40
+ overflow_norm = false;
36
- break;
41
switch (s->float_rounding_mode) {
37
case NEON_2RM_VQABS:
42
case float_round_nearest_even:
38
switch (size) {
43
- overflow_norm = false;
39
case 0:
44
inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
40
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
45
break;
41
default: abort();
46
case float_round_ties_away:
42
}
47
- overflow_norm = false;
43
break;
48
inc = frac_lsbm1;
44
- case NEON_2RM_VNEG:
49
break;
45
- tmp2 = tcg_const_i32(0);
50
case float_round_to_zero:
46
- gen_neon_rsb(size, tmp, tmp2);
51
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
47
- tcg_temp_free_i32(tmp2);
52
break;
48
- break;
53
case float_round_to_odd:
49
case NEON_2RM_VCGT0_F:
54
overflow_norm = true;
50
{
55
+ /* fall through */
51
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
56
+ case float_round_to_odd_inf:
57
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
58
break;
59
default:
60
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
61
? frac_lsbm1 : 0);
62
break;
63
case float_round_to_odd:
64
+ case float_round_to_odd_inf:
65
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
66
break;
67
default:
52
--
68
--
53
2.19.1
69
2.20.1
54
70
55
71
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move cmtst_op expanders from translate-a64.c.
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
4
and VDOT.BF16 for AArch32 NEON.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-17-richard.henderson@linaro.org
7
Message-id: 20210525225817.400336-7-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.h | 2 +
11
target/arm/helper.h | 3 +++
11
target/arm/translate-a64.c | 38 ------------------
12
target/arm/neon-shared.decode | 2 ++
12
target/arm/translate.c | 81 +++++++++++++++++++++++++++-----------
13
target/arm/sve.decode | 3 +++
13
3 files changed, 60 insertions(+), 61 deletions(-)
14
target/arm/translate-a64.c | 20 ++++++++++++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 +++++++++++
17
target/arm/vec_helper.c | 40 +++++++++++++++++++++++++++++++++++
18
7 files changed, 89 insertions(+)
14
19
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
22
--- a/target/arm/helper.h
18
+++ b/target/arm/translate.h
23
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 bit_op;
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ummla_b, TCG_CALL_NO_RWG,
20
extern const GVecGen3 bif_op;
25
DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
21
extern const GVecGen3 mla_op[4];
26
void, ptr, ptr, ptr, ptr, i32)
22
extern const GVecGen3 mls_op[4];
27
23
+extern const GVecGen3 cmtst_op[4];
28
+DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
24
extern const GVecGen2i ssra_op[4];
29
+ void, ptr, ptr, ptr, ptr, i32)
25
extern const GVecGen2i usra_op[4];
30
+
26
extern const GVecGen2i sri_op[4];
31
#ifdef TARGET_AARCH64
27
extern const GVecGen2i sli_op[4];
32
#include "helper-a64.h"
28
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
33
#include "helper-sve.h"
29
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
30
/*
35
index XXXXXXX..XXXXXXX 100644
31
* Forward to the isar_feature_* tests given a DisasContext pointer.
36
--- a/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
38
@@ -XXX,XX +XXX,XX @@ VUDOT 1111 110 00 . 10 .... .... 1101 . q:1 . 1 .... \
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
VUSDOT 1111 110 01 . 10 .... .... 1101 . q:1 . 0 .... \
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
42
+VDOT_b16 1111 110 00 . 00 .... .... 1101 . q:1 . 0 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
# VFM[AS]L
46
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
52
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
53
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
54
55
+### SVE2 floating-point bfloat16 dot-product
56
+BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
57
+
58
### SVE2 floating-point multiply-add long (indexed)
59
FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
60
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
61
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
63
--- a/target/arm/translate-a64.c
35
+++ b/target/arm/translate-a64.c
64
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
65
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
66
}
67
feature = dc_isar_feature(aa64_fcma, s);
68
break;
69
+ case 0x1f: /* BFDOT */
70
+ switch (size) {
71
+ case 1:
72
+ feature = dc_isar_feature(aa64_bf16, s);
73
+ break;
74
+ default:
75
+ unallocated_encoding(s);
76
+ return;
77
+ }
78
+ break;
79
default:
80
unallocated_encoding(s);
81
return;
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
return;
85
86
+ case 0xf: /* BFDOT */
87
+ switch (size) {
88
+ case 1:
89
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
90
+ break;
91
+ default:
92
+ g_assert_not_reached();
93
+ }
94
+ return;
95
+
96
default:
97
g_assert_not_reached();
37
}
98
}
99
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-neon.c
102
+++ b/target/arm/translate-neon.c
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSDOT(DisasContext *s, arg_VUSDOT *a)
104
gen_helper_gvec_usdot_b);
38
}
105
}
39
106
40
-/* CMTST : test is "if (X & Y != 0)". */
107
+static bool trans_VDOT_b16(DisasContext *s, arg_VDOT_b16 *a)
41
-static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
42
-{
43
- tcg_gen_and_i32(d, a, b);
44
- tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
45
- tcg_gen_neg_i32(d, d);
46
-}
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
+{
108
+{
99
+ tcg_gen_and_i32(d, a, b);
109
+ if (!dc_isar_feature(aa32_bf16, s)) {
100
+ tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
110
+ return false;
101
+ tcg_gen_neg_i32(d, d);
111
+ }
112
+ return do_neon_ddda(s, a->q * 7, a->vd, a->vn, a->vm, 0,
113
+ gen_helper_gvec_bfdot);
102
+}
114
+}
103
+
115
+
104
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
116
static bool trans_VFML(DisasContext *s, arg_VFML *a)
117
{
118
int opr_sz;
119
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/translate-sve.c
122
+++ b/target/arm/translate-sve.c
123
@@ -XXX,XX +XXX,XX @@ static bool trans_UMMLA(DisasContext *s, arg_rrrr_esz *a)
124
{
125
return do_i8mm_zzzz_ool(s, a, gen_helper_gvec_ummla_b, 0);
126
}
127
+
128
+static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
105
+{
129
+{
106
+ tcg_gen_and_i64(d, a, b);
130
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
107
+ tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
131
+ return false;
108
+ tcg_gen_neg_i64(d, d);
132
+ }
133
+ if (sve_access_check(s)) {
134
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot,
135
+ a->rd, a->rn, a->rm, a->ra, 0);
136
+ }
137
+ return true;
138
+}
139
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/vec_helper.c
142
+++ b/target/arm/vec_helper.c
143
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
144
DO_MMLA_B(gvec_smmla_b, do_smmla_b)
145
DO_MMLA_B(gvec_ummla_b, do_ummla_b)
146
DO_MMLA_B(gvec_usmmla_b, do_usmmla_b)
147
+
148
+/*
149
+ * BFloat16 Dot Product
150
+ */
151
+
152
+static float32 bfdotadd(float32 sum, uint32_t e1, uint32_t e2)
153
+{
154
+ /* FPCR is ignored for BFDOT and BFMMLA. */
155
+ float_status bf_status = {
156
+ .tininess_before_rounding = float_tininess_before_rounding,
157
+ .float_rounding_mode = float_round_to_odd_inf,
158
+ .flush_to_zero = true,
159
+ .flush_inputs_to_zero = true,
160
+ .default_nan_mode = true,
161
+ };
162
+ float32 t1, t2;
163
+
164
+ /*
165
+ * Extract each BFloat16 from the element pair, and shift
166
+ * them such that they become float32.
167
+ */
168
+ t1 = float32_mul(e1 << 16, e2 << 16, &bf_status);
169
+ t2 = float32_mul(e1 & 0xffff0000u, e2 & 0xffff0000u, &bf_status);
170
+ t1 = float32_add(t1, t2, &bf_status);
171
+ t1 = float32_add(sum, t1, &bf_status);
172
+
173
+ return t1;
109
+}
174
+}
110
+
175
+
111
+static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
176
+void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
112
+{
177
+{
113
+ tcg_gen_and_vec(vece, d, a, b);
178
+ intptr_t i, opr_sz = simd_oprsz(desc);
114
+ tcg_gen_dupi_vec(vece, a, 0);
179
+ float32 *d = vd, *a = va;
115
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
180
+ uint32_t *n = vn, *m = vm;
181
+
182
+ for (i = 0; i < opr_sz / 4; ++i) {
183
+ d[i] = bfdotadd(a[i], n[i], m[i]);
184
+ }
185
+ clear_tail(d, opr_sz, simd_maxsz(desc));
116
+}
186
+}
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
--
187
--
202
2.19.1
188
2.20.1
203
189
204
190
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Most of the v8 extensions are self-contained within the ISAR
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
4
registers and are not implied by other feature bits, which
4
and VDOT.BF16 for AArch32 NEON.
5
makes them the easiest to convert.
6
5
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181016223115.24100-4-richard.henderson@linaro.org
7
Message-id: 20210525225817.400336-8-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.h | 131 +++++++++++++++++++++++++++++++++----
11
target/arm/helper.h | 2 ++
14
target/arm/translate.h | 7 ++
12
target/arm/neon-shared.decode | 2 ++
15
linux-user/elfload.c | 46 ++++++++-----
13
target/arm/sve.decode | 3 +++
16
target/arm/cpu.c | 27 +++++---
14
target/arm/translate-a64.c | 41 +++++++++++++++++++++++++++--------
17
target/arm/cpu64.c | 57 +++++++++-------
15
target/arm/translate-neon.c | 9 ++++++++
18
target/arm/translate-a64.c | 101 ++++++++++++++--------------
16
target/arm/translate-sve.c | 12 ++++++++++
19
target/arm/translate.c | 36 +++++-----
17
target/arm/vec_helper.c | 20 +++++++++++++++++
20
7 files changed, 273 insertions(+), 132 deletions(-)
18
7 files changed, 80 insertions(+), 9 deletions(-)
21
19
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
22
--- a/target/arm/helper.h
25
+++ b/target/arm/cpu.h
23
+++ b/target/arm/helper.h
26
@@ -XXX,XX +XXX,XX @@ typedef enum ARMPSCIState {
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
27
PSCI_ON_PENDING = 2
25
28
} ARMPSCIState;
26
DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
29
27
void, ptr, ptr, ptr, ptr, i32)
30
+typedef struct ARMISARegisters ARMISARegisters;
28
+DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/neon-shared.decode
36
+++ b/target/arm/neon-shared.decode
37
@@ -XXX,XX +XXX,XX @@ VUSDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
38
vn=%vn_dp vd=%vd_dp
39
VSUDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 1 vm:4 \
40
vn=%vn_dp vd=%vd_dp
41
+VDOT_b16_scal 1111 1110 0 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
42
+ vn=%vn_dp vd=%vd_dp
43
44
%vfml_scalar_q0_rm 0:3 5:1
45
%vfml_scalar_q1_index 5:1 3:1
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
51
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
52
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
53
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
31
+
54
+
32
/**
55
+### SVE2 floating-point bfloat16 dot-product (indexed)
33
* ARMCPU:
56
+BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
34
* @env: #CPUARMState
35
@@ -XXX,XX +XXX,XX @@ enum arm_features {
36
ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
37
ARM_FEATURE_V8,
38
ARM_FEATURE_AARCH64, /* supports 64 bit mode */
39
- ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
40
ARM_FEATURE_CBAR, /* has cp15 CBAR */
41
ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
42
ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */
43
ARM_FEATURE_EL2, /* has EL2 Virtualization support */
44
ARM_FEATURE_EL3, /* has EL3 Secure monitor support */
45
- ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */
46
- ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
47
- ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
48
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
49
ARM_FEATURE_PMU, /* has PMU support */
50
ARM_FEATURE_VBAR, /* has cp15 VBAR */
51
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
52
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
53
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
54
- ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
55
- ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
56
- ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
57
- ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
58
- ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
59
- ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
60
- ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
61
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
62
- ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
63
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
64
};
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
+{
75
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
76
+}
77
+
78
+static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
79
+{
80
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
81
+}
82
+
83
+static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
84
+{
85
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
86
+}
87
+
88
+static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
89
+{
90
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
91
+}
92
+
93
+static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
94
+{
95
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
96
+}
97
+
98
+static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
99
+{
100
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
101
+}
102
+
103
+static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
104
+{
105
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
106
+}
107
+
108
+static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
109
+{
110
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
111
+}
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
57
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
429
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
430
--- a/target/arm/translate-a64.c
59
--- a/target/arm/translate-a64.c
431
+++ b/target/arm/translate-a64.c
60
+++ 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)
61
@@ -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;
62
return;
578
}
63
}
579
break;
64
break;
580
case 0x0e: /* SDOT */
65
- case 0x0f: /* SUDOT, USDOT */
581
case 0x1e: /* UDOT */
66
- if (is_scalar || (size & 1) || !dc_isar_feature(aa64_i8mm, s)) {
582
- if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
67
+ case 0x0f:
583
+ if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
68
+ switch (size) {
69
+ case 0: /* SUDOT */
70
+ case 2: /* USDOT */
71
+ if (is_scalar || !dc_isar_feature(aa64_i8mm, s)) {
72
+ unallocated_encoding(s);
73
+ return;
74
+ }
75
+ break;
76
+ case 1: /* BFDOT */
77
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
78
+ unallocated_encoding(s);
79
+ return;
80
+ }
81
+ break;
82
+ default:
584
unallocated_encoding(s);
83
unallocated_encoding(s);
585
return;
84
return;
586
}
85
}
587
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
86
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
87
u ? gen_helper_gvec_udot_idx_b
88
: gen_helper_gvec_sdot_idx_b);
89
return;
90
- case 0x0f: /* SUDOT, USDOT */
91
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
92
- extract32(insn, 23, 1)
93
- ? gen_helper_gvec_usdot_idx_b
94
- : gen_helper_gvec_sudot_idx_b);
95
- return;
96
-
97
+ case 0x0f:
98
+ switch (extract32(insn, 22, 2)) {
99
+ case 0: /* SUDOT */
100
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
101
+ gen_helper_gvec_sudot_idx_b);
102
+ return;
103
+ case 1: /* BFDOT */
104
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
105
+ gen_helper_gvec_bfdot_idx);
106
+ return;
107
+ case 2: /* USDOT */
108
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
109
+ gen_helper_gvec_usdot_idx_b);
110
+ return;
111
+ }
112
+ g_assert_not_reached();
113
case 0x11: /* FCMLA #0 */
588
case 0x13: /* FCMLA #90 */
114
case 0x13: /* FCMLA #90 */
589
case 0x15: /* FCMLA #180 */
115
case 0x15: /* FCMLA #180 */
590
case 0x17: /* FCMLA #270 */
116
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
591
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
117
index XXXXXXX..XXXXXXX 100644
592
+ if (!dc_isar_feature(aa64_fcma, s)) {
118
--- a/target/arm/translate-neon.c
593
unallocated_encoding(s);
119
+++ b/target/arm/translate-neon.c
594
return;
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUDOT_scalar(DisasContext *s, arg_VSUDOT_scalar *a)
595
}
121
gen_helper_gvec_sudot_idx_b);
596
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
122
}
597
TCGv_i32 tcg_decrypt;
123
598
CryptoThreeOpIntFn *genfn;
124
+static bool trans_VDOT_b16_scal(DisasContext *s, arg_VDOT_b16_scal *a)
599
125
+{
600
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
126
+ if (!dc_isar_feature(aa32_bf16, s)) {
601
- || size != 0) {
127
+ return false;
602
+ if (!dc_isar_feature(aa64_aes, s) || size != 0) {
128
+ }
603
unallocated_encoding(s);
129
+ return do_neon_ddda(s, a->q * 6, a->vd, a->vn, a->vm, a->index,
604
return;
130
+ gen_helper_gvec_bfdot_idx);
131
+}
132
+
133
static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
134
{
135
int opr_sz;
136
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate-sve.c
139
+++ b/target/arm/translate-sve.c
140
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
605
}
141
}
606
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
142
return true;
607
int rd = extract32(insn, 0, 5);
143
}
608
CryptoThreeOpFn *genfn;
144
+
609
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
145
+static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
610
- int feature = ARM_FEATURE_V8_SHA256;
146
+{
611
+ bool feature;
147
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
612
148
+ return false;
613
if (size != 0) {
149
+ }
614
unallocated_encoding(s);
150
+ if (sve_access_check(s)) {
615
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
151
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot_idx,
616
case 2: /* SHA1M */
152
+ a->rd, a->rn, a->rm, a->ra, a->index);
617
case 3: /* SHA1SU0 */
153
+ }
618
genfn = NULL;
154
+ return true;
619
- feature = ARM_FEATURE_V8_SHA1;
155
+}
620
+ feature = dc_isar_feature(aa64_sha1, s);
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
621
break;
157
index XXXXXXX..XXXXXXX 100644
622
case 4: /* SHA256H */
158
--- a/target/arm/vec_helper.c
623
genfn = gen_helper_crypto_sha256h;
159
+++ b/target/arm/vec_helper.c
624
+ feature = dc_isar_feature(aa64_sha256, s);
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
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
}
161
}
638
162
clear_tail(d, opr_sz, simd_maxsz(desc));
639
- if (!arm_dc_feature(s, feature)) {
163
}
640
+ if (!feature) {
164
+
641
unallocated_encoding(s);
165
+void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
642
return;
166
+ void *va, uint32_t desc)
643
}
167
+{
644
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
645
int rn = extract32(insn, 5, 5);
169
+ intptr_t index = simd_data(desc);
646
int rd = extract32(insn, 0, 5);
170
+ intptr_t elements = opr_sz / 4;
647
CryptoTwoOpFn *genfn;
171
+ intptr_t eltspersegment = MIN(16 / 4, elements);
648
- int feature;
172
+ float32 *d = vd, *a = va;
649
+ bool feature;
173
+ uint32_t *n = vn, *m = vm;
650
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
174
+
651
175
+ for (i = 0; i < elements; i += eltspersegment) {
652
if (size != 0) {
176
+ uint32_t m_idx = m[i + H4(index)];
653
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
177
+
654
178
+ for (j = i; j < i + eltspersegment; j++) {
655
switch (opcode) {
179
+ d[j] = bfdotadd(a[j], n[j], m_idx);
656
case 0: /* SHA1H */
180
+ }
657
- feature = ARM_FEATURE_V8_SHA1;
181
+ }
658
+ feature = dc_isar_feature(aa64_sha1, s);
182
+ clear_tail(d, opr_sz, simd_maxsz(desc));
659
genfn = gen_helper_crypto_sha1h;
183
+}
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
822
index XXXXXXX..XXXXXXX 100644
823
--- a/target/arm/translate.c
824
+++ 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)
835
return 1;
836
}
837
if (!u) { /* SHA-1 */
838
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
839
+ if (!dc_isar_feature(aa32_sha1, s)) {
840
return 1;
841
}
842
ptr1 = vfp_reg_ptr(true, rd);
843
@@ -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);
845
tcg_temp_free_i32(tmp4);
846
} else { /* SHA-256 */
847
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
848
+ if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
849
return 1;
850
}
851
ptr1 = vfp_reg_ptr(true, rd);
852
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
853
if (op == 14 && size == 2) {
854
TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
855
856
- if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
857
+ if (!dc_isar_feature(aa32_pmull, s)) {
858
return 1;
859
}
860
tcg_rn = tcg_temp_new_i64();
861
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
862
{
863
NeonGenThreeOpEnvFn *fn;
864
865
- if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
866
+ if (!dc_isar_feature(aa32_rdm, s)) {
867
return 1;
868
}
869
if (u && ((rd | rn) & 1)) {
870
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
871
break;
872
}
873
case NEON_2RM_AESE: case NEON_2RM_AESMC:
874
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
875
- || ((rm | rd) & 1)) {
876
+ if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
877
return 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
--
184
--
976
2.19.1
185
2.20.1
977
186
978
187
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFMMLA for both AArch64 AdvSIMD and SVE,
4
and VMMLA.BF16 for AArch32 NEON.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20181011205206.3552-4-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-9-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>
7
---
10
---
8
target/arm/translate-a64.c | 28 +++-------------------------
11
target/arm/helper.h | 3 +++
9
1 file changed, 3 insertions(+), 25 deletions(-)
12
target/arm/neon-shared.decode | 2 ++
13
target/arm/sve.decode | 6 +++--
14
target/arm/translate-a64.c | 10 +++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 ++++++++++
17
target/arm/vec_helper.c | 42 ++++++++++++++++++++++++++++++++++-
18
7 files changed, 81 insertions(+), 3 deletions(-)
10
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
25
DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
38
@@ -XXX,XX +XXX,XX @@ VUMMLA 1111 1100 0.10 .... .... 1100 .1.1 .... \
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
42
+VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
46
vn=%vn_dp vd=%vd_dp size=1
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
52
USDOT_zzzz 01000100 .. 0 ..... 011 110 ..... ..... @rda_rn_rm
53
54
### SVE2 floating point matrix multiply accumulate
55
-
56
-FMMLA 01100100 .. 1 ..... 111001 ..... ..... @rda_rn_rm
57
+{
58
+ BFMMLA 01100100 01 1 ..... 111 001 ..... ..... @rda_rn_rm_e0
59
+ FMMLA 01100100 .. 1 ..... 111 001 ..... ..... @rda_rn_rm
60
+}
61
62
### SVE2 Memory Gather Load Group
63
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
64
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
66
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
67
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
68
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
16
for (xs = 0; xs < selem; xs++) {
69
}
17
if (replicate) {
70
feature = dc_isar_feature(aa64_fcma, s);
18
/* Load and replicate to all elements */
71
break;
19
- uint64_t mulconst;
72
+ case 0x1d: /* BFMMLA */
20
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
73
+ if (size != MO_16 || !is_q) {
21
74
+ unallocated_encoding(s);
22
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
75
+ return;
23
get_mem_index(s), s->be_data + scale);
76
+ }
24
- switch (scale) {
77
+ feature = dc_isar_feature(aa64_bf16, s);
25
- case 0:
78
+ break;
26
- mulconst = 0x0101010101010101ULL;
79
case 0x1f: /* BFDOT */
27
- break;
80
switch (size) {
28
- case 1:
81
case 1:
29
- mulconst = 0x0001000100010001ULL;
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
30
- break;
83
}
31
- case 2:
84
return;
32
- mulconst = 0x0000000100000001ULL;
85
33
- break;
86
+ case 0xd: /* BFMMLA */
34
- case 3:
87
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
35
- mulconst = 0;
88
+ return;
36
- break;
89
case 0xf: /* BFDOT */
37
- default:
90
switch (size) {
38
- g_assert_not_reached();
91
case 1:
39
- }
92
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
40
- if (mulconst) {
93
index XXXXXXX..XXXXXXX 100644
41
- tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
94
--- a/target/arm/translate-neon.c
42
- }
95
+++ b/target/arm/translate-neon.c
43
- write_vec_element(s, tcg_tmp, rt, 0, MO_64);
96
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSMMLA(DisasContext *s, arg_VUSMMLA *a)
44
- if (is_q) {
97
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
45
- write_vec_element(s, tcg_tmp, rt, 1, MO_64);
98
gen_helper_gvec_usmmla_b);
46
- }
99
}
47
+ tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
100
+
48
+ (is_q + 1) * 8, vec_full_reg_size(s),
101
+static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
49
+ tcg_tmp);
102
+{
50
tcg_temp_free_i64(tcg_tmp);
103
+ if (!dc_isar_feature(aa32_bf16, s)) {
51
- clear_vec_high(s, is_q, rt);
104
+ return false;
52
} else {
105
+ }
53
/* Load/store one element per register */
106
+ return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
54
if (is_load) {
107
+ gen_helper_gvec_bfmmla);
108
+}
109
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate-sve.c
112
+++ b/target/arm/translate-sve.c
113
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
114
}
115
return true;
116
}
117
+
118
+static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
119
+{
120
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
121
+ return false;
122
+ }
123
+ if (sve_access_check(s)) {
124
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfmmla,
125
+ a->rd, a->rn, a->rm, a->ra, 0);
126
+ }
127
+ return true;
128
+}
129
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/vec_helper.c
132
+++ b/target/arm/vec_helper.c
133
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
134
* Process the entire segment at once, writing back the
135
* results only after we've consumed all of the inputs.
136
*
137
- * Key to indicies by column:
138
+ * Key to indices by column:
139
* i j i j
140
*/
141
sum0 = a[H4(0 + 0)];
142
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
143
}
144
clear_tail(d, opr_sz, simd_maxsz(desc));
145
}
146
+
147
+void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
148
+{
149
+ intptr_t s, opr_sz = simd_oprsz(desc);
150
+ float32 *d = vd, *a = va;
151
+ uint32_t *n = vn, *m = vm;
152
+
153
+ for (s = 0; s < opr_sz / 4; s += 4) {
154
+ float32 sum00, sum01, sum10, sum11;
155
+
156
+ /*
157
+ * Process the entire segment at once, writing back the
158
+ * results only after we've consumed all of the inputs.
159
+ *
160
+ * Key to indicies by column:
161
+ * i j i k j k
162
+ */
163
+ sum00 = a[s + H4(0 + 0)];
164
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 0)], m[s + H4(0 + 0)]);
165
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 1)], m[s + H4(0 + 1)]);
166
+
167
+ sum01 = a[s + H4(0 + 1)];
168
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 0)], m[s + H4(2 + 0)]);
169
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 1)], m[s + H4(2 + 1)]);
170
+
171
+ sum10 = a[s + H4(2 + 0)];
172
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 0)], m[s + H4(0 + 0)]);
173
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 1)], m[s + H4(0 + 1)]);
174
+
175
+ sum11 = a[s + H4(2 + 1)];
176
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 0)], m[s + H4(2 + 0)]);
177
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 1)], m[s + H4(2 + 1)]);
178
+
179
+ d[s + H4(0 + 0)] = sum00;
180
+ d[s + H4(0 + 1)] = sum01;
181
+ d[s + H4(2 + 0)] = sum10;
182
+ d[s + H4(2 + 1)] = sum11;
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
185
+}
55
--
186
--
56
2.19.1
187
2.20.1
57
188
58
189
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move ssra_op and usra_op expanders from translate-a64.c.
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
4
and VFMA{B,T}.BF16 for AArch32 NEON.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-14-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-10-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.h | 2 +
11
target/arm/helper.h | 3 +++
11
target/arm/translate-a64.c | 106 ----------------------------
12
target/arm/neon-shared.decode | 3 +++
12
target/arm/translate.c | 139 ++++++++++++++++++++++++++++++++++---
13
target/arm/sve.decode | 3 +++
13
3 files changed, 130 insertions(+), 117 deletions(-)
14
target/arm/translate-a64.c | 13 +++++++++----
15
target/arm/translate-neon.c | 9 +++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 16 ++++++++++++++++
18
7 files changed, 73 insertions(+), 4 deletions(-)
14
19
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
22
--- a/target/arm/helper.h
18
+++ b/target/arm/translate.h
23
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
20
extern const GVecGen3 bsl_op;
25
DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
21
extern const GVecGen3 bit_op;
26
void, ptr, ptr, ptr, ptr, i32)
22
extern const GVecGen3 bif_op;
27
23
+extern const GVecGen2i ssra_op[4];
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
24
+extern const GVecGen2i usra_op[4];
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
25
30
+
26
/*
31
#ifdef TARGET_AARCH64
27
* Forward to the isar_feature_* tests given a DisasContext pointer.
32
#include "helper-a64.h"
33
#include "helper-sve.h"
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
38
@@ -XXX,XX +XXX,XX @@ VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
39
VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
40
vm=%vm_dp vn=%vn_dp vd=%vd_dp
41
42
+VFMA_b16 1111 110 0 0.11 .... .... 1000 . q:1 . 1 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
+
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
46
vn=%vn_dp vd=%vd_dp size=1
47
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
48
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/sve.decode
51
+++ b/target/arm/sve.decode
52
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
53
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
54
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
55
56
+BFMLALB_zzzw 01100100 11 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
57
+BFMLALT_zzzw 01100100 11 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
58
+
59
### SVE2 floating-point bfloat16 dot-product
60
BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
61
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
62
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
64
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
65
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
66
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
67
}
68
feature = dc_isar_feature(aa64_bf16, s);
69
break;
70
- case 0x1f: /* BFDOT */
71
+ case 0x1f:
72
switch (size) {
73
- case 1:
74
+ case 1: /* BFDOT */
75
+ case 3: /* BFMLAL{B,T} */
76
feature = dc_isar_feature(aa64_bf16, s);
77
break;
78
default:
79
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
80
case 0xd: /* BFMMLA */
81
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
82
return;
83
- case 0xf: /* BFDOT */
84
+ case 0xf:
85
switch (size) {
86
- case 1:
87
+ case 1: /* BFDOT */
88
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
89
break;
90
+ case 3: /* BFMLAL{B,T} */
91
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
92
+ gen_helper_gvec_bfmlal);
93
+ break;
94
default:
95
g_assert_not_reached();
96
}
97
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/translate-neon.c
100
+++ b/target/arm/translate-neon.c
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
102
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
103
gen_helper_gvec_bfmmla);
104
}
105
+
106
+static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
107
+{
108
+ if (!dc_isar_feature(aa32_bf16, s)) {
109
+ return false;
110
+ }
111
+ return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
112
+ gen_helper_gvec_bfmlal);
113
+}
114
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate-sve.c
117
+++ b/target/arm/translate-sve.c
118
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
33
}
119
}
120
return true;
34
}
121
}
35
122
+
36
-static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
123
+static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
37
-{
38
- tcg_gen_vec_sar8i_i64(a, a, shift);
39
- tcg_gen_vec_add8_i64(d, d, a);
40
-}
41
-
42
-static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
43
-{
44
- tcg_gen_vec_sar16i_i64(a, a, shift);
45
- tcg_gen_vec_add16_i64(d, d, a);
46
-}
47
-
48
-static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
49
-{
50
- tcg_gen_sari_i32(a, a, shift);
51
- tcg_gen_add_i32(d, d, a);
52
-}
53
-
54
-static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
55
-{
56
- tcg_gen_sari_i64(a, a, shift);
57
- tcg_gen_add_i64(d, d, a);
58
-}
59
-
60
-static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
61
-{
62
- tcg_gen_sari_vec(vece, a, a, sh);
63
- tcg_gen_add_vec(vece, d, d, a);
64
-}
65
-
66
-static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
67
-{
68
- tcg_gen_vec_shr8i_i64(a, a, shift);
69
- tcg_gen_vec_add8_i64(d, d, a);
70
-}
71
-
72
-static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
73
-{
74
- tcg_gen_vec_shr16i_i64(a, a, shift);
75
- tcg_gen_vec_add16_i64(d, d, a);
76
-}
77
-
78
-static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
79
-{
80
- tcg_gen_shri_i32(a, a, shift);
81
- tcg_gen_add_i32(d, d, a);
82
-}
83
-
84
-static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
85
-{
86
- tcg_gen_shri_i64(a, a, shift);
87
- tcg_gen_add_i64(d, d, a);
88
-}
89
-
90
-static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
91
-{
92
- tcg_gen_shri_vec(vece, a, a, sh);
93
- tcg_gen_add_vec(vece, d, d, a);
94
-}
95
-
96
static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
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
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ 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
+{
124
+{
162
+ tcg_gen_vec_sar8i_i64(a, a, shift);
125
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
163
+ tcg_gen_vec_add8_i64(d, d, a);
126
+ return false;
127
+ }
128
+ if (sve_access_check(s)) {
129
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
130
+ unsigned vsz = vec_full_reg_size(s);
131
+
132
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
133
+ vec_full_reg_offset(s, a->rn),
134
+ vec_full_reg_offset(s, a->rm),
135
+ vec_full_reg_offset(s, a->ra),
136
+ status, vsz, vsz, sel,
137
+ gen_helper_gvec_bfmlal);
138
+ tcg_temp_free_ptr(status);
139
+ }
140
+ return true;
164
+}
141
+}
165
+
142
+
166
+static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
143
+static bool trans_BFMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
167
+{
144
+{
168
+ tcg_gen_vec_sar16i_i64(a, a, shift);
145
+ return do_BFMLAL_zzzw(s, a, false);
169
+ tcg_gen_vec_add16_i64(d, d, a);
170
+}
146
+}
171
+
147
+
172
+static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
148
+static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
173
+{
149
+{
174
+ tcg_gen_sari_i32(a, a, shift);
150
+ return do_BFMLAL_zzzw(s, a, true);
175
+ tcg_gen_add_i32(d, d, a);
176
+}
151
+}
152
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/vec_helper.c
155
+++ b/target/arm/vec_helper.c
156
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
157
}
158
clear_tail(d, opr_sz, simd_maxsz(desc));
159
}
177
+
160
+
178
+static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
161
+void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
162
+ void *stat, uint32_t desc)
179
+{
163
+{
180
+ tcg_gen_sari_i64(a, a, shift);
164
+ intptr_t i, opr_sz = simd_oprsz(desc);
181
+ tcg_gen_add_i64(d, d, a);
165
+ intptr_t sel = simd_data(desc);
166
+ float32 *d = vd, *a = va;
167
+ bfloat16 *n = vn, *m = vm;
168
+
169
+ for (i = 0; i < opr_sz / 4; ++i) {
170
+ float32 nn = n[H2(i * 2 + sel)] << 16;
171
+ float32 mm = m[H2(i * 2 + sel)] << 16;
172
+ d[H4(i)] = float32_muladd(nn, mm, a[H4(i)], 0, stat);
173
+ }
174
+ clear_tail(d, opr_sz, simd_maxsz(desc));
182
+}
175
+}
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)
271
}
272
return 0;
273
274
+ case 1: /* VSRA */
275
+ /* Right shift comes here negative. */
276
+ shift = -shift;
277
+ /* Shifts larger than the element size are architecturally
278
+ * valid. Unsigned results in all zeros; signed results
279
+ * in all sign bits.
280
+ */
281
+ if (!u) {
282
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
283
+ MIN(shift, (8 << size) - 1),
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)
297
neon_load_reg64(cpu_V0, rm + pass);
298
tcg_gen_movi_i64(cpu_V1, imm);
299
switch (op) {
300
- case 1: /* VSRA */
301
- if (u)
302
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
303
- else
304
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
305
- break;
306
case 2: /* VRSHR */
307
case 3: /* VRSRA */
308
if (u)
309
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
310
default:
311
g_assert_not_reached();
312
}
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
--
176
--
338
2.19.1
177
2.20.1
339
178
340
179
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move expanders for VBSL, VBIT, and VBIF from translate-a64.c.
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
4
and VFMA{B,T}.BF16 for AArch32 NEON.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181011205206.3552-9-richard.henderson@linaro.org
8
Message-id: 20210525225817.400336-11-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.h | 6 ++
11
target/arm/helper.h | 2 ++
11
target/arm/translate-a64.c | 61 --------------
12
target/arm/neon-shared.decode | 2 ++
12
target/arm/translate.c | 162 +++++++++++++++++++++++++++----------
13
target/arm/sve.decode | 2 ++
13
3 files changed, 124 insertions(+), 105 deletions(-)
14
target/arm/translate-a64.c | 15 ++++++++++++++-
15
target/arm/translate-neon.c | 10 ++++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 22 ++++++++++++++++++++++
18
7 files changed, 82 insertions(+), 1 deletion(-)
14
19
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
22
--- a/target/arm/helper.h
18
+++ b/target/arm/translate.h
23
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
20
return ret;
25
21
}
26
DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
22
27
void, ptr, ptr, ptr, ptr, ptr, i32)
23
+
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
24
+/* Vector operations shared between ARM and AArch64. */
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
25
+extern const GVecGen3 bsl_op;
30
26
+extern const GVecGen3 bit_op;
31
#ifdef TARGET_AARCH64
27
+extern const GVecGen3 bif_op;
32
#include "helper-a64.h"
28
+
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
29
/*
34
index XXXXXXX..XXXXXXX 100644
30
* Forward to the isar_feature_* tests given a DisasContext pointer.
35
--- a/target/arm/neon-shared.decode
31
*/
36
+++ b/target/arm/neon-shared.decode
37
@@ -XXX,XX +XXX,XX @@ VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
38
rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
39
VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
40
index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
41
+VFMA_b16_scal 1111 1110 0.11 .... .... 1000 . q:1 . 1 . vm:3 \
42
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp
43
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/sve.decode
46
+++ b/target/arm/sve.decode
47
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
48
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
49
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
50
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
51
+BFMLALB_zzxw 01100100 11 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
52
+BFMLALT_zzxw 01100100 11 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
53
54
### SVE2 floating-point bfloat16 dot-product (indexed)
55
BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
58
--- a/target/arm/translate-a64.c
35
+++ b/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
37
}
61
unallocated_encoding(s);
62
return;
63
}
64
+ size = MO_32;
65
break;
66
case 1: /* BFDOT */
67
if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
68
unallocated_encoding(s);
69
return;
70
}
71
+ size = MO_32;
72
+ break;
73
+ case 3: /* BFMLAL{B,T} */
74
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
75
+ unallocated_encoding(s);
76
+ return;
77
+ }
78
+ /* can't set is_fp without other incorrect size checks */
79
+ size = MO_16;
80
break;
81
default:
82
unallocated_encoding(s);
83
return;
84
}
85
- size = MO_32;
86
break;
87
case 0x11: /* FCMLA #0 */
88
case 0x13: /* FCMLA #90 */
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
90
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
91
gen_helper_gvec_usdot_idx_b);
92
return;
93
+ case 3: /* BFMLAL{B,T} */
94
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
95
+ gen_helper_gvec_bfmlal_idx);
96
+ return;
97
}
98
g_assert_not_reached();
99
case 0x11: /* FCMLA #0 */
100
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-neon.c
103
+++ b/target/arm/translate-neon.c
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
105
return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
106
gen_helper_gvec_bfmlal);
38
}
107
}
39
108
+
40
-static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
109
+static bool trans_VFMA_b16_scal(DisasContext *s, arg_VFMA_b16_scal *a)
41
-{
110
+{
42
- tcg_gen_xor_i64(rn, rn, rm);
111
+ if (!dc_isar_feature(aa32_bf16, s)) {
43
- tcg_gen_and_i64(rn, rn, rd);
112
+ return false;
44
- tcg_gen_xor_i64(rd, rm, rn);
113
+ }
45
-}
114
+ return do_neon_ddda_fpst(s, 6, a->vd, a->vn, a->vm,
46
-
115
+ (a->index << 1) | a->q, FPST_STD,
47
-static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
116
+ gen_helper_gvec_bfmlal_idx);
48
-{
117
+}
49
- tcg_gen_xor_i64(rn, rn, rd);
118
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
50
- tcg_gen_and_i64(rn, rn, rm);
119
index XXXXXXX..XXXXXXX 100644
51
- tcg_gen_xor_i64(rd, rd, rn);
120
--- a/target/arm/translate-sve.c
52
-}
121
+++ b/target/arm/translate-sve.c
53
-
122
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
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
{
123
{
85
- static const GVecGen3 bsl_op = {
124
return do_BFMLAL_zzzw(s, a, true);
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
}
125
}
114
126
+
115
-/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
127
+static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
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
+{
128
+{
135
+ tcg_gen_xor_i64(rn, rn, rm);
129
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
136
+ tcg_gen_and_i64(rn, rn, rd);
130
+ return false;
137
+ tcg_gen_xor_i64(rd, rm, rn);
131
+ }
132
+ if (sve_access_check(s)) {
133
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
134
+ unsigned vsz = vec_full_reg_size(s);
135
+
136
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
137
+ vec_full_reg_offset(s, a->rn),
138
+ vec_full_reg_offset(s, a->rm),
139
+ vec_full_reg_offset(s, a->ra),
140
+ status, vsz, vsz, (a->index << 1) | sel,
141
+ gen_helper_gvec_bfmlal_idx);
142
+ tcg_temp_free_ptr(status);
143
+ }
144
+ return true;
138
+}
145
+}
139
+
146
+
140
+static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
147
+static bool trans_BFMLALB_zzxw(DisasContext *s, arg_rrxr_esz *a)
141
+{
148
+{
142
+ tcg_gen_xor_i64(rn, rn, rd);
149
+ return do_BFMLAL_zzxw(s, a, false);
143
+ tcg_gen_and_i64(rn, rn, rm);
144
+ tcg_gen_xor_i64(rd, rd, rn);
145
+}
150
+}
146
+
151
+
147
+static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
152
+static bool trans_BFMLALT_zzxw(DisasContext *s, arg_rrxr_esz *a)
148
+{
153
+{
149
+ tcg_gen_xor_i64(rn, rn, rd);
154
+ return do_BFMLAL_zzxw(s, a, true);
150
+ tcg_gen_andc_i64(rn, rn, rm);
151
+ tcg_gen_xor_i64(rd, rd, rn);
152
+}
155
+}
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/vec_helper.c
159
+++ b/target/arm/vec_helper.c
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
161
}
162
clear_tail(d, opr_sz, simd_maxsz(desc));
163
}
153
+
164
+
154
+static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
165
+void HELPER(gvec_bfmlal_idx)(void *vd, void *vn, void *vm,
166
+ void *va, void *stat, uint32_t desc)
155
+{
167
+{
156
+ tcg_gen_xor_vec(vece, rn, rn, rm);
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
157
+ tcg_gen_and_vec(vece, rn, rn, rd);
169
+ intptr_t sel = extract32(desc, SIMD_DATA_SHIFT, 1);
158
+ tcg_gen_xor_vec(vece, rd, rm, rn);
170
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 1, 3);
171
+ intptr_t elements = opr_sz / 4;
172
+ intptr_t eltspersegment = MIN(16 / 4, elements);
173
+ float32 *d = vd, *a = va;
174
+ bfloat16 *n = vn, *m = vm;
175
+
176
+ for (i = 0; i < elements; i += eltspersegment) {
177
+ float32 m_idx = m[H2(2 * i + index)] << 16;
178
+
179
+ for (j = i; j < i + eltspersegment; j++) {
180
+ float32 n_j = n[H2(2 * j + sel)] << 16;
181
+ d[H4(j)] = float32_muladd(n_j, m_idx, a[H4(j)], 0, stat);
182
+ }
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
159
+}
185
+}
160
+
161
+static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
162
+{
163
+ tcg_gen_xor_vec(vece, rn, rn, rd);
164
+ tcg_gen_and_vec(vece, rn, rn, rm);
165
+ tcg_gen_xor_vec(vece, rd, rd, rn);
166
+}
167
+
168
+static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
169
+{
170
+ tcg_gen_xor_vec(vece, rn, rn, rd);
171
+ tcg_gen_andc_vec(vece, rn, rn, rm);
172
+ tcg_gen_xor_vec(vece, rd, rd, rn);
173
+}
174
+
175
+const GVecGen3 bsl_op = {
176
+ .fni8 = gen_bsl_i64,
177
+ .fniv = gen_bsl_vec,
178
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
179
+ .load_dest = true
180
+};
181
+
182
+const GVecGen3 bit_op = {
183
+ .fni8 = gen_bit_i64,
184
+ .fniv = gen_bit_vec,
185
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
186
+ .load_dest = 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
--
186
--
323
2.19.1
187
2.20.1
324
188
325
189
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Both arm and thumb2 division are controlled by the same ISAR field,
4
which takes care of the arm implies thumb case. Having M imply
5
thumb2 division was wrong for cortex-m0, which is v6m and does not
6
have thumb2 at all, much less thumb2 division.
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20181016223115.24100-5-richard.henderson@linaro.org
4
Message-id: 20210525225817.400336-12-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
target/arm/cpu.h | 12 ++++++++++--
8
linux-user/elfload.c | 2 ++
15
linux-user/elfload.c | 4 ++--
9
1 file changed, 2 insertions(+)
16
target/arm/cpu.c | 10 +---------
17
target/arm/translate.c | 4 ++--
18
4 files changed, 15 insertions(+), 15 deletions(-)
19
10
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
25
ARM_FEATURE_VFP3,
26
ARM_FEATURE_VFP_FP16,
27
ARM_FEATURE_NEON,
28
- ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
29
ARM_FEATURE_M, /* Microcontroller profile. */
30
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
31
ARM_FEATURE_THUMB2EE,
32
@@ -XXX,XX +XXX,XX @@ enum arm_features {
33
ARM_FEATURE_V5,
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
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
58
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
59
--- a/linux-user/elfload.c
13
--- a/linux-user/elfload.c
60
+++ b/linux-user/elfload.c
14
+++ b/linux-user/elfload.c
61
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
15
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
62
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
16
GET_FEATURE_ID(aa64_sve_i8mm, ARM_HWCAP2_A64_SVEI8MM);
63
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
17
GET_FEATURE_ID(aa64_sve_f32mm, ARM_HWCAP2_A64_SVEF32MM);
64
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
18
GET_FEATURE_ID(aa64_sve_f64mm, ARM_HWCAP2_A64_SVEF64MM);
65
- GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
19
+ GET_FEATURE_ID(aa64_sve_bf16, ARM_HWCAP2_A64_SVEBF16);
66
- GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
20
GET_FEATURE_ID(aa64_i8mm, ARM_HWCAP2_A64_I8MM);
67
+ GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
21
+ GET_FEATURE_ID(aa64_bf16, ARM_HWCAP2_A64_BF16);
68
+ GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
22
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
69
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
23
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
70
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
24
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
71
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
72
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/cpu.c
75
+++ b/target/arm/cpu.c
76
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
77
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
78
* Security Extensions is ARM_FEATURE_EL3.
79
*/
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
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
112
case 1:
113
case 3:
114
/* SDIV, UDIV */
115
- if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
116
+ if (!dc_isar_feature(arm_div, s)) {
117
goto illegal_op;
118
}
119
if (((insn >> 5) & 7) || (rd != 15)) {
120
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
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
--
25
--
130
2.19.1
26
2.20.1
131
27
132
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Instantiating mps2-an505 (cortex-m33) will fail make check when
3
Disable BF16 again for !have_neon and !have_vfp during realize.
4
V7VE asserts that ID_ISAR0.Divide includes ARM division. It is
5
also wrong to include ARM_FEATURE_LPAE.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20181016223115.24100-3-richard.henderson@linaro.org
6
Message-id: 20210525225817.400336-13-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/cpu.c | 6 +++++-
10
target/arm/cpu.c | 3 +++
13
1 file changed, 5 insertions(+), 1 deletion(-)
11
target/arm/cpu64.c | 3 +++
12
target/arm/cpu_tcg.c | 1 +
13
3 files changed, 7 insertions(+)
14
14
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
17
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
20
20
21
/* Some features automatically imply others: */
21
u = cpu->isar.id_isar6;
22
if (arm_feature(env, ARM_FEATURE_V8)) {
22
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
23
- set_feature(env, ARM_FEATURE_V7VE);
23
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
24
+ if (arm_feature(env, ARM_FEATURE_M)) {
24
cpu->isar.id_isar6 = u;
25
+ set_feature(env, ARM_FEATURE_V7);
25
26
+ } else {
26
u = cpu->isar.mvfr0;
27
+ set_feature(env, ARM_FEATURE_V7VE);
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
28
+ }
28
29
}
29
t = cpu->isar.id_aa64isar1;
30
if (arm_feature(env, ARM_FEATURE_V7VE)) {
30
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
31
/* v7 Virtualization Extensions. In real hardware this implies
31
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0);
32
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
33
cpu->isar.id_aa64isar1 = t;
34
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
36
u = cpu->isar.id_isar6;
37
u = FIELD_DP32(u, ID_ISAR6, DP, 0);
38
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
39
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
40
u = FIELD_DP32(u, ID_ISAR6, I8MM, 0);
41
cpu->isar.id_isar6 = u;
42
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu64.c
46
+++ b/target/arm/cpu64.c
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
48
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
49
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
51
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
52
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
53
t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
54
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
56
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
57
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
58
t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
59
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
60
t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
61
t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
62
t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
63
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
64
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
65
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
66
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
67
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
68
u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
69
cpu->isar.id_isar6 = u;
70
71
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu_tcg.c
74
+++ b/target/arm/cpu_tcg.c
75
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
76
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
77
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
78
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
79
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
80
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
81
cpu->isar.id_isar6 = t;
82
32
--
83
--
33
2.19.1
84
2.20.1
34
85
35
86
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
Message-id: 20181011205206.3552-10-richard.henderson@linaro.org
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
8
This patch moves assert_hvf_ok() and introduces generic build infrastructure.
9
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-2-agraf@csgraf.de
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
target/arm/translate.c | 29 ++++++++++-------------------
16
include/sysemu/hvf_int.h | 18 +++++++++++++++
9
1 file changed, 10 insertions(+), 19 deletions(-)
17
accel/hvf/hvf-all.c | 47 ++++++++++++++++++++++++++++++++++++++++
10
18
target/i386/hvf/hvf.c | 33 +---------------------------
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
MAINTAINERS | 8 +++++++
20
accel/hvf/meson.build | 6 +++++
21
accel/meson.build | 1 +
22
6 files changed, 81 insertions(+), 32 deletions(-)
23
create mode 100644 include/sysemu/hvf_int.h
24
create mode 100644 accel/hvf/hvf-all.c
25
create mode 100644 accel/hvf/meson.build
26
27
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
28
new file mode 100644
29
index XXXXXXX..XXXXXXX
30
--- /dev/null
31
+++ b/include/sysemu/hvf_int.h
32
@@ -XXX,XX +XXX,XX @@
33
+/*
34
+ * QEMU Hypervisor.framework (HVF) support
35
+ *
36
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
37
+ * See the COPYING file in the top-level directory.
38
+ *
39
+ */
40
+
41
+/* header to be included in HVF-specific code */
42
+
43
+#ifndef HVF_INT_H
44
+#define HVF_INT_H
45
+
46
+#include <Hypervisor/hv.h>
47
+
48
+void assert_hvf_ok(hv_return_t ret);
49
+
50
+#endif
51
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
52
new file mode 100644
53
index XXXXXXX..XXXXXXX
54
--- /dev/null
55
+++ b/accel/hvf/hvf-all.c
56
@@ -XXX,XX +XXX,XX @@
57
+/*
58
+ * QEMU Hypervisor.framework support
59
+ *
60
+ * This work is licensed under the terms of the GNU GPL, version 2. See
61
+ * the COPYING file in the top-level directory.
62
+ *
63
+ * Contributions after 2012-01-13 are licensed under the terms of the
64
+ * GNU GPL, version 2 or (at your option) any later version.
65
+ */
66
+
67
+#include "qemu/osdep.h"
68
+#include "qemu-common.h"
69
+#include "qemu/error-report.h"
70
+#include "sysemu/hvf.h"
71
+#include "sysemu/hvf_int.h"
72
+
73
+void assert_hvf_ok(hv_return_t ret)
74
+{
75
+ if (ret == HV_SUCCESS) {
76
+ return;
77
+ }
78
+
79
+ switch (ret) {
80
+ case HV_ERROR:
81
+ error_report("Error: HV_ERROR");
82
+ break;
83
+ case HV_BUSY:
84
+ error_report("Error: HV_BUSY");
85
+ break;
86
+ case HV_BAD_ARGUMENT:
87
+ error_report("Error: HV_BAD_ARGUMENT");
88
+ break;
89
+ case HV_NO_RESOURCES:
90
+ error_report("Error: HV_NO_RESOURCES");
91
+ break;
92
+ case HV_NO_DEVICE:
93
+ error_report("Error: HV_NO_DEVICE");
94
+ break;
95
+ case HV_UNSUPPORTED:
96
+ error_report("Error: HV_UNSUPPORTED");
97
+ break;
98
+ default:
99
+ error_report("Unknown Error");
100
+ }
101
+
102
+ abort();
103
+}
104
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
12
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
106
--- a/target/i386/hvf/hvf.c
14
+++ b/target/arm/translate.c
107
+++ b/target/i386/hvf/hvf.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
108
@@ -XXX,XX +XXX,XX @@
16
break;
109
#include "qemu/error-report.h"
17
}
110
18
return 0;
111
#include "sysemu/hvf.h"
19
+
112
+#include "sysemu/hvf_int.h"
20
+ case NEON_3R_VADD_VSUB:
113
#include "sysemu/runstate.h"
21
+ if (u) {
114
#include "hvf-i386.h"
22
+ tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
115
#include "vmcs.h"
23
+ vec_size, vec_size);
116
@@ -XXX,XX +XXX,XX @@
24
+ } else {
117
25
+ tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
118
HVFState *hvf_state;
26
+ vec_size, vec_size);
119
27
+ }
120
-static void assert_hvf_ok(hv_return_t ret)
28
+ return 0;
121
-{
29
}
122
- if (ret == HV_SUCCESS) {
30
if (size == 3) {
123
- return;
31
/* 64-bit element instructions. */
124
- }
32
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
-
33
cpu_V1, cpu_V0);
126
- switch (ret) {
34
}
127
- case HV_ERROR:
35
break;
128
- error_report("Error: HV_ERROR");
36
- case NEON_3R_VADD_VSUB:
129
- break;
37
- if (u) {
130
- case HV_BUSY:
38
- tcg_gen_sub_i64(CPU_V001);
131
- error_report("Error: HV_BUSY");
39
- } else {
132
- break;
40
- tcg_gen_add_i64(CPU_V001);
133
- case HV_BAD_ARGUMENT:
41
- }
134
- error_report("Error: HV_BAD_ARGUMENT");
42
- break;
135
- break;
43
default:
136
- case HV_NO_RESOURCES:
44
abort();
137
- error_report("Error: HV_NO_RESOURCES");
45
}
138
- break;
46
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
- case HV_NO_DEVICE:
47
tmp2 = neon_load_reg(rd, pass);
140
- error_report("Error: HV_NO_DEVICE");
48
gen_neon_add(size, tmp, tmp2);
141
- break;
49
break;
142
- case HV_UNSUPPORTED:
50
- case NEON_3R_VADD_VSUB:
143
- error_report("Error: HV_UNSUPPORTED");
51
- if (!u) { /* VADD */
144
- break;
52
- gen_neon_add(size, tmp, tmp2);
145
- default:
53
- } else { /* VSUB */
146
- error_report("Unknown Error");
54
- switch (size) {
147
- }
55
- case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
148
-
56
- case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
149
- abort();
57
- case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
150
-}
58
- default: abort();
151
-
59
- }
152
/* Memory slots */
60
- }
153
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
61
- break;
154
{
62
case NEON_3R_VTST_VCEQ:
155
diff --git a/MAINTAINERS b/MAINTAINERS
63
if (!u) { /* VTST */
156
index XXXXXXX..XXXXXXX 100644
64
switch (size) {
157
--- a/MAINTAINERS
158
+++ b/MAINTAINERS
159
@@ -XXX,XX +XXX,XX @@ M: Roman Bolshakov <r.bolshakov@yadro.com>
160
W: https://wiki.qemu.org/Features/HVF
161
S: Maintained
162
F: target/i386/hvf/
163
+
164
+HVF
165
+M: Cameron Esfahani <dirty@apple.com>
166
+M: Roman Bolshakov <r.bolshakov@yadro.com>
167
+W: https://wiki.qemu.org/Features/HVF
168
+S: Maintained
169
+F: accel/hvf/
170
F: include/sysemu/hvf.h
171
+F: include/sysemu/hvf_int.h
172
173
WHPX CPUs
174
M: Sunil Muthuswamy <sunilmut@microsoft.com>
175
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
176
new file mode 100644
177
index XXXXXXX..XXXXXXX
178
--- /dev/null
179
+++ b/accel/hvf/meson.build
180
@@ -XXX,XX +XXX,XX @@
181
+hvf_ss = ss.source_set()
182
+hvf_ss.add(files(
183
+ 'hvf-all.c',
184
+))
185
+
186
+specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
187
diff --git a/accel/meson.build b/accel/meson.build
188
index XXXXXXX..XXXXXXX 100644
189
--- a/accel/meson.build
190
+++ b/accel/meson.build
191
@@ -XXX,XX +XXX,XX @@ specific_ss.add(files('accel-common.c'))
192
softmmu_ss.add(files('accel-softmmu.c'))
193
user_ss.add(files('accel-user.c'))
194
195
+subdir('hvf')
196
subdir('qtest')
197
subdir('kvm')
198
subdir('tcg')
65
--
199
--
66
2.19.1
200
2.20.1
67
201
68
202
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
Message-id: 20181011205206.3552-8-richard.henderson@linaro.org
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
8
This patch moves the vCPU thread loop over.
9
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-3-agraf@csgraf.de
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
target/arm/translate.c | 67 ++++++++++++++++++++++++------------------
16
{target/i386 => accel}/hvf/hvf-accel-ops.h | 0
9
1 file changed, 39 insertions(+), 28 deletions(-)
17
{target/i386 => accel}/hvf/hvf-accel-ops.c | 0
18
target/i386/hvf/x86hvf.c | 2 +-
19
accel/hvf/meson.build | 1 +
20
target/i386/hvf/meson.build | 1 -
21
5 files changed, 2 insertions(+), 2 deletions(-)
22
rename {target/i386 => accel}/hvf/hvf-accel-ops.h (100%)
23
rename {target/i386 => accel}/hvf/hvf-accel-ops.c (100%)
10
24
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
diff --git a/target/i386/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
26
similarity index 100%
27
rename from target/i386/hvf/hvf-accel-ops.h
28
rename to accel/hvf/hvf-accel-ops.h
29
diff --git a/target/i386/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
30
similarity index 100%
31
rename from target/i386/hvf/hvf-accel-ops.c
32
rename to accel/hvf/hvf-accel-ops.c
33
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
12
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
35
--- a/target/i386/hvf/x86hvf.c
14
+++ b/target/arm/translate.c
36
+++ b/target/i386/hvf/x86hvf.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
37
@@ -XXX,XX +XXX,XX @@
16
return 1;
38
#include <Hypervisor/hv.h>
17
}
39
#include <Hypervisor/hv_vmx.h>
18
} else { /* (insn & 0x00380080) == 0 */
40
19
- int invert;
41
-#include "hvf-accel-ops.h"
20
+ int invert, reg_ofs, vec_size;
42
+#include "accel/hvf/hvf-accel-ops.h"
21
+
43
22
if (q && (rd & 1)) {
44
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
23
return 1;
45
SegmentCache *qseg, bool is_tr)
24
}
46
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
47
index XXXXXXX..XXXXXXX 100644
26
break;
48
--- a/accel/hvf/meson.build
27
case 14:
49
+++ b/accel/hvf/meson.build
28
imm |= (imm << 8) | (imm << 16) | (imm << 24);
50
@@ -XXX,XX +XXX,XX @@
29
- if (invert)
51
hvf_ss = ss.source_set()
30
+ if (invert) {
52
hvf_ss.add(files(
31
imm = ~imm;
53
'hvf-all.c',
32
+ }
54
+ 'hvf-accel-ops.c',
33
break;
55
))
34
case 15:
56
35
if (invert) {
57
specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
36
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
58
diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build
37
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
59
index XXXXXXX..XXXXXXX 100644
38
break;
60
--- a/target/i386/hvf/meson.build
39
}
61
+++ b/target/i386/hvf/meson.build
40
- if (invert)
62
@@ -XXX,XX +XXX,XX @@
41
+ if (invert) {
63
i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
42
imm = ~imm;
64
'hvf.c',
43
+ }
65
- 'hvf-accel-ops.c',
44
66
'x86.c',
45
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
67
'x86_cpuid.c',
46
- if (op & 1 && op < 12) {
68
'x86_decode.c',
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
--
69
--
109
2.19.1
70
2.20.1
110
71
111
72
diff view generated by jsdifflib
1
The HCR.FB virtualization configuration register bit requests that
1
From: Alexander Graf <agraf@csgraf.de>
2
TLB maintenance, branch predictor invalidate-all and icache
3
invalidate-all operations performed in NS EL1 should be upgraded
4
from "local CPU only to "broadcast within Inner Shareable domain".
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
2
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
8
This patch moves CPU and memory operations over. While at it, make sure
9
the code is consumable on non-i386 systems.
10
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
12
Reviewed-by: Sergio Lopez <slp@redhat.com>
13
Message-id: 20210519202253.76782-4-agraf@csgraf.de
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20181012144235.19646-4-peter.maydell@linaro.org
15
---
16
---
16
target/arm/helper.c | 191 +++++++++++++++++++++++++++-----------------
17
include/sysemu/hvf_int.h | 4 +
17
1 file changed, 116 insertions(+), 75 deletions(-)
18
target/i386/hvf/hvf-i386.h | 2 -
19
target/i386/hvf/x86hvf.h | 2 -
20
accel/hvf/hvf-accel-ops.c | 308 ++++++++++++++++++++++++++++++++++++-
21
target/i386/hvf/hvf.c | 302 ------------------------------------
22
5 files changed, 311 insertions(+), 307 deletions(-)
18
23
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
26
--- a/include/sysemu/hvf_int.h
22
+++ b/target/arm/helper.c
27
+++ b/include/sysemu/hvf_int.h
23
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
@@ -XXX,XX +XXX,XX @@
24
raw_write(env, ri, value);
29
25
}
30
#include <Hypervisor/hv.h>
26
31
27
-static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
+void hvf_set_phys_mem(MemoryRegionSection *, bool);
28
- uint64_t value)
33
void assert_hvf_ok(hv_return_t ret);
29
-{
34
+hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
30
- /* Invalidate all (TLBIALL) */
35
+int hvf_put_registers(CPUState *);
31
- ARMCPU *cpu = arm_env_get_cpu(env);
36
+int hvf_get_registers(CPUState *);
32
-
37
33
- tlb_flush(CPU(cpu));
38
#endif
34
-}
39
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
35
-
40
index XXXXXXX..XXXXXXX 100644
36
-static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
41
--- a/target/i386/hvf/hvf-i386.h
37
- uint64_t value)
42
+++ b/target/i386/hvf/hvf-i386.h
38
-{
43
@@ -XXX,XX +XXX,XX @@ struct HVFState {
39
- /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
44
};
40
- ARMCPU *cpu = arm_env_get_cpu(env);
45
extern HVFState *hvf_state;
41
-
46
42
- tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
47
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
43
-}
48
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
44
-
49
-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
45
-static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
50
46
- uint64_t value)
51
#ifdef NEED_CPU_H
47
-{
52
/* Functions exported to host specific mode */
48
- /* Invalidate by ASID (TLBIASID) */
53
diff --git a/target/i386/hvf/x86hvf.h b/target/i386/hvf/x86hvf.h
49
- ARMCPU *cpu = arm_env_get_cpu(env);
54
index XXXXXXX..XXXXXXX 100644
50
-
55
--- a/target/i386/hvf/x86hvf.h
51
- tlb_flush(CPU(cpu));
56
+++ b/target/i386/hvf/x86hvf.h
52
-}
57
@@ -XXX,XX +XXX,XX @@
53
-
58
#include "x86_descr.h"
54
-static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
59
55
- uint64_t value)
60
int hvf_process_events(CPUState *);
56
-{
61
-int hvf_put_registers(CPUState *);
57
- /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
62
-int hvf_get_registers(CPUState *);
58
- ARMCPU *cpu = arm_env_get_cpu(env);
63
bool hvf_inject_interrupts(CPUState *);
59
-
64
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
60
- tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
65
SegmentCache *qseg, bool is_tr);
61
-}
66
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
62
-
67
index XXXXXXX..XXXXXXX 100644
63
/* IS variants of TLB operations must affect all cores */
68
--- a/accel/hvf/hvf-accel-ops.c
64
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
+++ b/accel/hvf/hvf-accel-ops.c
65
uint64_t value)
70
@@ -XXX,XX +XXX,XX @@
66
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
71
#include "qemu/osdep.h"
67
tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
72
#include "qemu/error-report.h"
68
}
73
#include "qemu/main-loop.h"
69
74
+#include "exec/address-spaces.h"
70
+/*
75
+#include "exec/exec-all.h"
71
+ * Non-IS variants of TLB operations are upgraded to
76
+#include "sysemu/cpus.h"
72
+ * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
77
#include "sysemu/hvf.h"
73
+ * force broadcast of these operations.
78
+#include "sysemu/hvf_int.h"
74
+ */
79
#include "sysemu/runstate.h"
75
+static bool tlb_force_broadcast(CPUARMState *env)
80
-#include "target/i386/cpu.h"
76
+{
81
#include "qemu/guest-random.h"
77
+ return (env->cp15.hcr_el2 & HCR_FB) &&
82
78
+ arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
83
#include "hvf-accel-ops.h"
79
+}
84
80
+
85
+HVFState *hvf_state;
81
+static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
86
+
82
+ uint64_t value)
87
+/* Memory slots */
83
+{
88
+
84
+ /* Invalidate all (TLBIALL) */
89
+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
85
+ ARMCPU *cpu = arm_env_get_cpu(env);
90
+{
86
+
91
+ hvf_slot *slot;
87
+ if (tlb_force_broadcast(env)) {
92
+ int x;
88
+ tlbiall_is_write(env, NULL, value);
93
+ for (x = 0; x < hvf_state->num_slots; ++x) {
94
+ slot = &hvf_state->slots[x];
95
+ if (slot->size && start < (slot->start + slot->size) &&
96
+ (start + size) > slot->start) {
97
+ return slot;
98
+ }
99
+ }
100
+ return NULL;
101
+}
102
+
103
+struct mac_slot {
104
+ int present;
105
+ uint64_t size;
106
+ uint64_t gpa_start;
107
+ uint64_t gva;
108
+};
109
+
110
+struct mac_slot mac_slots[32];
111
+
112
+static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
113
+{
114
+ struct mac_slot *macslot;
115
+ hv_return_t ret;
116
+
117
+ macslot = &mac_slots[slot->slot_id];
118
+
119
+ if (macslot->present) {
120
+ if (macslot->size != slot->size) {
121
+ macslot->present = 0;
122
+ ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
123
+ assert_hvf_ok(ret);
124
+ }
125
+ }
126
+
127
+ if (!slot->size) {
128
+ return 0;
129
+ }
130
+
131
+ macslot->present = 1;
132
+ macslot->gpa_start = slot->start;
133
+ macslot->size = slot->size;
134
+ ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
135
+ assert_hvf_ok(ret);
136
+ return 0;
137
+}
138
+
139
+void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
140
+{
141
+ hvf_slot *mem;
142
+ MemoryRegion *area = section->mr;
143
+ bool writeable = !area->readonly && !area->rom_device;
144
+ hv_memory_flags_t flags;
145
+
146
+ if (!memory_region_is_ram(area)) {
147
+ if (writeable) {
148
+ return;
149
+ } else if (!memory_region_is_romd(area)) {
150
+ /*
151
+ * If the memory device is not in romd_mode, then we actually want
152
+ * to remove the hvf memory slot so all accesses will trap.
153
+ */
154
+ add = false;
155
+ }
156
+ }
157
+
158
+ mem = hvf_find_overlap_slot(
159
+ section->offset_within_address_space,
160
+ int128_get64(section->size));
161
+
162
+ if (mem && add) {
163
+ if (mem->size == int128_get64(section->size) &&
164
+ mem->start == section->offset_within_address_space &&
165
+ mem->mem == (memory_region_get_ram_ptr(area) +
166
+ section->offset_within_region)) {
167
+ return; /* Same region was attempted to register, go away. */
168
+ }
169
+ }
170
+
171
+ /* Region needs to be reset. set the size to 0 and remap it. */
172
+ if (mem) {
173
+ mem->size = 0;
174
+ if (do_hvf_set_memory(mem, 0)) {
175
+ error_report("Failed to reset overlapping slot");
176
+ abort();
177
+ }
178
+ }
179
+
180
+ if (!add) {
89
+ return;
181
+ return;
90
+ }
182
+ }
91
+
183
+
92
+ tlb_flush(CPU(cpu));
184
+ if (area->readonly ||
93
+}
185
+ (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
94
+
186
+ flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
95
+static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
187
+ } else {
96
+ uint64_t value)
188
+ flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
97
+{
189
+ }
98
+ /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
190
+
99
+ ARMCPU *cpu = arm_env_get_cpu(env);
191
+ /* Now make a new slot. */
100
+
192
+ int x;
101
+ if (tlb_force_broadcast(env)) {
193
+
102
+ tlbimva_is_write(env, NULL, value);
194
+ for (x = 0; x < hvf_state->num_slots; ++x) {
195
+ mem = &hvf_state->slots[x];
196
+ if (!mem->size) {
197
+ break;
198
+ }
199
+ }
200
+
201
+ if (x == hvf_state->num_slots) {
202
+ error_report("No free slots");
203
+ abort();
204
+ }
205
+
206
+ mem->size = int128_get64(section->size);
207
+ mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
208
+ mem->start = section->offset_within_address_space;
209
+ mem->region = area;
210
+
211
+ if (do_hvf_set_memory(mem, flags)) {
212
+ error_report("Error registering new memory slot");
213
+ abort();
214
+ }
215
+}
216
+
217
+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
218
+{
219
+ if (!cpu->vcpu_dirty) {
220
+ hvf_get_registers(cpu);
221
+ cpu->vcpu_dirty = true;
222
+ }
223
+}
224
+
225
+void hvf_cpu_synchronize_state(CPUState *cpu)
226
+{
227
+ if (!cpu->vcpu_dirty) {
228
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
229
+ }
230
+}
231
+
232
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
233
+ run_on_cpu_data arg)
234
+{
235
+ hvf_put_registers(cpu);
236
+ cpu->vcpu_dirty = false;
237
+}
238
+
239
+void hvf_cpu_synchronize_post_reset(CPUState *cpu)
240
+{
241
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
242
+}
243
+
244
+static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
245
+ run_on_cpu_data arg)
246
+{
247
+ hvf_put_registers(cpu);
248
+ cpu->vcpu_dirty = false;
249
+}
250
+
251
+void hvf_cpu_synchronize_post_init(CPUState *cpu)
252
+{
253
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
254
+}
255
+
256
+static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
257
+ run_on_cpu_data arg)
258
+{
259
+ cpu->vcpu_dirty = true;
260
+}
261
+
262
+void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
263
+{
264
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
265
+}
266
+
267
+static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
268
+{
269
+ hvf_slot *slot;
270
+
271
+ slot = hvf_find_overlap_slot(
272
+ section->offset_within_address_space,
273
+ int128_get64(section->size));
274
+
275
+ /* protect region against writes; begin tracking it */
276
+ if (on) {
277
+ slot->flags |= HVF_SLOT_LOG;
278
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
279
+ HV_MEMORY_READ);
280
+ /* stop tracking region*/
281
+ } else {
282
+ slot->flags &= ~HVF_SLOT_LOG;
283
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
284
+ HV_MEMORY_READ | HV_MEMORY_WRITE);
285
+ }
286
+}
287
+
288
+static void hvf_log_start(MemoryListener *listener,
289
+ MemoryRegionSection *section, int old, int new)
290
+{
291
+ if (old != 0) {
103
+ return;
292
+ return;
104
+ }
293
+ }
105
+
294
+
106
+ tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
295
+ hvf_set_dirty_tracking(section, 1);
107
+}
296
+}
108
+
297
+
109
+static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
298
+static void hvf_log_stop(MemoryListener *listener,
110
+ uint64_t value)
299
+ MemoryRegionSection *section, int old, int new)
111
+{
300
+{
112
+ /* Invalidate by ASID (TLBIASID) */
301
+ if (new != 0) {
113
+ ARMCPU *cpu = arm_env_get_cpu(env);
114
+
115
+ if (tlb_force_broadcast(env)) {
116
+ tlbiasid_is_write(env, NULL, value);
117
+ return;
302
+ return;
118
+ }
303
+ }
119
+
304
+
120
+ tlb_flush(CPU(cpu));
305
+ hvf_set_dirty_tracking(section, 0);
121
+}
306
+}
122
+
307
+
123
+static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
308
+static void hvf_log_sync(MemoryListener *listener,
124
+ uint64_t value)
309
+ MemoryRegionSection *section)
125
+{
310
+{
126
+ /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
311
+ /*
127
+ ARMCPU *cpu = arm_env_get_cpu(env);
312
+ * sync of dirty pages is handled elsewhere; just make sure we keep
128
+
313
+ * tracking the region.
129
+ if (tlb_force_broadcast(env)) {
314
+ */
130
+ tlbimvaa_is_write(env, NULL, value);
315
+ hvf_set_dirty_tracking(section, 1);
131
+ return;
316
+}
132
+ }
317
+
133
+
318
+static void hvf_region_add(MemoryListener *listener,
134
+ tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
319
+ MemoryRegionSection *section)
135
+}
320
+{
136
+
321
+ hvf_set_phys_mem(section, true);
137
static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
322
+}
138
uint64_t value)
323
+
324
+static void hvf_region_del(MemoryListener *listener,
325
+ MemoryRegionSection *section)
326
+{
327
+ hvf_set_phys_mem(section, false);
328
+}
329
+
330
+static MemoryListener hvf_memory_listener = {
331
+ .priority = 10,
332
+ .region_add = hvf_region_add,
333
+ .region_del = hvf_region_del,
334
+ .log_start = hvf_log_start,
335
+ .log_stop = hvf_log_stop,
336
+ .log_sync = hvf_log_sync,
337
+};
338
+
339
+static void dummy_signal(int sig)
340
+{
341
+}
342
+
343
+bool hvf_allowed;
344
+
345
+static int hvf_accel_init(MachineState *ms)
346
+{
347
+ int x;
348
+ hv_return_t ret;
349
+ HVFState *s;
350
+
351
+ ret = hv_vm_create(HV_VM_DEFAULT);
352
+ assert_hvf_ok(ret);
353
+
354
+ s = g_new0(HVFState, 1);
355
+
356
+ s->num_slots = 32;
357
+ for (x = 0; x < s->num_slots; ++x) {
358
+ s->slots[x].size = 0;
359
+ s->slots[x].slot_id = x;
360
+ }
361
+
362
+ hvf_state = s;
363
+ memory_listener_register(&hvf_memory_listener, &address_space_memory);
364
+ return 0;
365
+}
366
+
367
+static void hvf_accel_class_init(ObjectClass *oc, void *data)
368
+{
369
+ AccelClass *ac = ACCEL_CLASS(oc);
370
+ ac->name = "HVF";
371
+ ac->init_machine = hvf_accel_init;
372
+ ac->allowed = &hvf_allowed;
373
+}
374
+
375
+static const TypeInfo hvf_accel_type = {
376
+ .name = TYPE_HVF_ACCEL,
377
+ .parent = TYPE_ACCEL,
378
+ .class_init = hvf_accel_class_init,
379
+};
380
+
381
+static void hvf_type_init(void)
382
+{
383
+ type_register_static(&hvf_accel_type);
384
+}
385
+
386
+type_init(hvf_type_init);
387
+
388
/*
389
* The HVF-specific vCPU thread function. This one should only run when the host
390
* CPU supports the VMX "unrestricted guest" feature.
391
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/target/i386/hvf/hvf.c
394
+++ b/target/i386/hvf/hvf.c
395
@@ -XXX,XX +XXX,XX @@
396
397
#include "hvf-accel-ops.h"
398
399
-HVFState *hvf_state;
400
-
401
-/* Memory slots */
402
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
403
-{
404
- hvf_slot *slot;
405
- int x;
406
- for (x = 0; x < hvf_state->num_slots; ++x) {
407
- slot = &hvf_state->slots[x];
408
- if (slot->size && start < (slot->start + slot->size) &&
409
- (start + size) > slot->start) {
410
- return slot;
411
- }
412
- }
413
- return NULL;
414
-}
415
-
416
-struct mac_slot {
417
- int present;
418
- uint64_t size;
419
- uint64_t gpa_start;
420
- uint64_t gva;
421
-};
422
-
423
-struct mac_slot mac_slots[32];
424
-
425
-static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
426
-{
427
- struct mac_slot *macslot;
428
- hv_return_t ret;
429
-
430
- macslot = &mac_slots[slot->slot_id];
431
-
432
- if (macslot->present) {
433
- if (macslot->size != slot->size) {
434
- macslot->present = 0;
435
- ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
436
- assert_hvf_ok(ret);
437
- }
438
- }
439
-
440
- if (!slot->size) {
441
- return 0;
442
- }
443
-
444
- macslot->present = 1;
445
- macslot->gpa_start = slot->start;
446
- macslot->size = slot->size;
447
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
448
- assert_hvf_ok(ret);
449
- return 0;
450
-}
451
-
452
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
453
-{
454
- hvf_slot *mem;
455
- MemoryRegion *area = section->mr;
456
- bool writeable = !area->readonly && !area->rom_device;
457
- hv_memory_flags_t flags;
458
-
459
- if (!memory_region_is_ram(area)) {
460
- if (writeable) {
461
- return;
462
- } else if (!memory_region_is_romd(area)) {
463
- /*
464
- * If the memory device is not in romd_mode, then we actually want
465
- * to remove the hvf memory slot so all accesses will trap.
466
- */
467
- add = false;
468
- }
469
- }
470
-
471
- mem = hvf_find_overlap_slot(
472
- section->offset_within_address_space,
473
- int128_get64(section->size));
474
-
475
- if (mem && add) {
476
- if (mem->size == int128_get64(section->size) &&
477
- mem->start == section->offset_within_address_space &&
478
- mem->mem == (memory_region_get_ram_ptr(area) +
479
- section->offset_within_region)) {
480
- return; /* Same region was attempted to register, go away. */
481
- }
482
- }
483
-
484
- /* Region needs to be reset. set the size to 0 and remap it. */
485
- if (mem) {
486
- mem->size = 0;
487
- if (do_hvf_set_memory(mem, 0)) {
488
- error_report("Failed to reset overlapping slot");
489
- abort();
490
- }
491
- }
492
-
493
- if (!add) {
494
- return;
495
- }
496
-
497
- if (area->readonly ||
498
- (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
499
- flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
500
- } else {
501
- flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
502
- }
503
-
504
- /* Now make a new slot. */
505
- int x;
506
-
507
- for (x = 0; x < hvf_state->num_slots; ++x) {
508
- mem = &hvf_state->slots[x];
509
- if (!mem->size) {
510
- break;
511
- }
512
- }
513
-
514
- if (x == hvf_state->num_slots) {
515
- error_report("No free slots");
516
- abort();
517
- }
518
-
519
- mem->size = int128_get64(section->size);
520
- mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
521
- mem->start = section->offset_within_address_space;
522
- mem->region = area;
523
-
524
- if (do_hvf_set_memory(mem, flags)) {
525
- error_report("Error registering new memory slot");
526
- abort();
527
- }
528
-}
529
-
530
void vmx_update_tpr(CPUState *cpu)
139
{
531
{
140
@@ -XXX,XX +XXX,XX @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
532
/* TODO: need integrate APIC handling */
141
* Page D4-1736 (DDI0487A.b)
533
@@ -XXX,XX +XXX,XX @@ void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
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
}
534
}
165
}
535
}
166
536
167
+static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
537
-static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
168
+ uint64_t value)
538
-{
169
+{
539
- if (!cpu->vcpu_dirty) {
170
+ CPUState *cs = ENV_GET_CPU(env);
540
- hvf_get_registers(cpu);
171
+
541
- cpu->vcpu_dirty = true;
172
+ if (tlb_force_broadcast(env)) {
542
- }
173
+ tlbi_aa64_vmalle1_write(env, NULL, value);
543
-}
174
+ return;
544
-
175
+ }
545
-void hvf_cpu_synchronize_state(CPUState *cpu)
176
+
546
-{
177
+ if (arm_is_secure_below_el3(env)) {
547
- if (!cpu->vcpu_dirty) {
178
+ tlb_flush_by_mmuidx(cs,
548
- run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
179
+ ARMMMUIdxBit_S1SE1 |
549
- }
180
+ ARMMMUIdxBit_S1SE0);
550
-}
181
+ } else {
551
-
182
+ tlb_flush_by_mmuidx(cs,
552
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
183
+ ARMMMUIdxBit_S12NSE1 |
553
- run_on_cpu_data arg)
184
+ ARMMMUIdxBit_S12NSE0);
554
-{
185
+ }
555
- hvf_put_registers(cpu);
186
+}
556
- cpu->vcpu_dirty = false;
187
+
557
-}
188
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
558
-
189
uint64_t value)
559
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
560
-{
561
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
562
-}
563
-
564
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
565
- run_on_cpu_data arg)
566
-{
567
- hvf_put_registers(cpu);
568
- cpu->vcpu_dirty = false;
569
-}
570
-
571
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
572
-{
573
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
574
-}
575
-
576
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
577
- run_on_cpu_data arg)
578
-{
579
- cpu->vcpu_dirty = true;
580
-}
581
-
582
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
583
-{
584
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
585
-}
586
-
587
static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
190
{
588
{
191
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
589
int read, write;
192
tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
590
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
591
return false;
193
}
592
}
194
593
195
-static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
594
-static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
196
- uint64_t value)
595
-{
197
-{
596
- hvf_slot *slot;
198
- /* Invalidate by VA, EL1&0 (AArch64 version).
597
-
199
- * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
598
- slot = hvf_find_overlap_slot(
200
- * since we don't support flush-for-specific-ASID-only or
599
- section->offset_within_address_space,
201
- * flush-last-level-only.
600
- int128_get64(section->size));
601
-
602
- /* protect region against writes; begin tracking it */
603
- if (on) {
604
- slot->flags |= HVF_SLOT_LOG;
605
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
606
- HV_MEMORY_READ);
607
- /* stop tracking region*/
608
- } else {
609
- slot->flags &= ~HVF_SLOT_LOG;
610
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
611
- HV_MEMORY_READ | HV_MEMORY_WRITE);
612
- }
613
-}
614
-
615
-static void hvf_log_start(MemoryListener *listener,
616
- MemoryRegionSection *section, int old, int new)
617
-{
618
- if (old != 0) {
619
- return;
620
- }
621
-
622
- hvf_set_dirty_tracking(section, 1);
623
-}
624
-
625
-static void hvf_log_stop(MemoryListener *listener,
626
- MemoryRegionSection *section, int old, int new)
627
-{
628
- if (new != 0) {
629
- return;
630
- }
631
-
632
- hvf_set_dirty_tracking(section, 0);
633
-}
634
-
635
-static void hvf_log_sync(MemoryListener *listener,
636
- MemoryRegionSection *section)
637
-{
638
- /*
639
- * sync of dirty pages is handled elsewhere; just make sure we keep
640
- * tracking the region.
202
- */
641
- */
203
- ARMCPU *cpu = arm_env_get_cpu(env);
642
- hvf_set_dirty_tracking(section, 1);
204
- CPUState *cs = CPU(cpu);
643
-}
205
- uint64_t pageaddr = sextract64(value << 12, 0, 56);
644
-
206
-
645
-static void hvf_region_add(MemoryListener *listener,
207
- if (arm_is_secure_below_el3(env)) {
646
- MemoryRegionSection *section)
208
- tlb_flush_page_by_mmuidx(cs, pageaddr,
647
-{
209
- ARMMMUIdxBit_S1SE1 |
648
- hvf_set_phys_mem(section, true);
210
- ARMMMUIdxBit_S1SE0);
649
-}
211
- } else {
650
-
212
- tlb_flush_page_by_mmuidx(cs, pageaddr,
651
-static void hvf_region_del(MemoryListener *listener,
213
- ARMMMUIdxBit_S12NSE1 |
652
- MemoryRegionSection *section)
214
- ARMMMUIdxBit_S12NSE0);
653
-{
215
- }
654
- hvf_set_phys_mem(section, false);
216
-}
655
-}
217
-
656
-
218
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
657
-static MemoryListener hvf_memory_listener = {
219
uint64_t value)
658
- .priority = 10,
659
- .region_add = hvf_region_add,
660
- .region_del = hvf_region_del,
661
- .log_start = hvf_log_start,
662
- .log_stop = hvf_log_stop,
663
- .log_sync = hvf_log_sync,
664
-};
665
-
666
void hvf_vcpu_destroy(CPUState *cpu)
220
{
667
{
221
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
668
X86CPU *x86_cpu = X86_CPU(cpu);
222
}
669
@@ -XXX,XX +XXX,XX @@ void hvf_vcpu_destroy(CPUState *cpu)
670
assert_hvf_ok(ret);
223
}
671
}
224
672
225
+static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
673
-static void dummy_signal(int sig)
226
+ uint64_t value)
674
-{
227
+{
675
-}
228
+ /* Invalidate by VA, EL1&0 (AArch64 version).
676
-
229
+ * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
677
static void init_tsc_freq(CPUX86State *env)
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
{
678
{
679
size_t length;
680
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
681
682
return ret;
683
}
684
-
685
-bool hvf_allowed;
686
-
687
-static int hvf_accel_init(MachineState *ms)
688
-{
689
- int x;
690
- hv_return_t ret;
691
- HVFState *s;
692
-
693
- ret = hv_vm_create(HV_VM_DEFAULT);
694
- assert_hvf_ok(ret);
695
-
696
- s = g_new0(HVFState, 1);
697
-
698
- s->num_slots = 32;
699
- for (x = 0; x < s->num_slots; ++x) {
700
- s->slots[x].size = 0;
701
- s->slots[x].slot_id = x;
702
- }
703
-
704
- hvf_state = s;
705
- memory_listener_register(&hvf_memory_listener, &address_space_memory);
706
- return 0;
707
-}
708
-
709
-static void hvf_accel_class_init(ObjectClass *oc, void *data)
710
-{
711
- AccelClass *ac = ACCEL_CLASS(oc);
712
- ac->name = "HVF";
713
- ac->init_machine = hvf_accel_init;
714
- ac->allowed = &hvf_allowed;
715
-}
716
-
717
-static const TypeInfo hvf_accel_type = {
718
- .name = TYPE_HVF_ACCEL,
719
- .parent = TYPE_ACCEL,
720
- .class_init = hvf_accel_class_init,
721
-};
722
-
723
-static void hvf_type_init(void)
724
-{
725
- type_register_static(&hvf_accel_type);
726
-}
727
-
728
-type_init(hvf_type_init);
256
--
729
--
257
2.19.1
730
2.20.1
258
731
259
732
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Announce the availability of the various priority queues.
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
This fixes an issue where guest kernels would miss to
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
configure secondary queues due to inproper feature bits.
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
6
7
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
This patch moves a few internal struct and constant defines over.
8
Message-id: 20181017213932.19973-2-edgar.iglesias@gmail.com
9
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-5-agraf@csgraf.de
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/net/cadence_gem.c | 8 +++++++-
16
include/sysemu/hvf_int.h | 30 ++++++++++++++++++++++++++++++
13
1 file changed, 7 insertions(+), 1 deletion(-)
17
target/i386/hvf/hvf-i386.h | 31 +------------------------------
18
2 files changed, 31 insertions(+), 30 deletions(-)
14
19
15
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
20
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/cadence_gem.c
22
--- a/include/sysemu/hvf_int.h
18
+++ b/hw/net/cadence_gem.c
23
+++ b/include/sysemu/hvf_int.h
19
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
24
@@ -XXX,XX +XXX,XX @@
20
int i;
25
21
CadenceGEMState *s = CADENCE_GEM(d);
26
#include <Hypervisor/hv.h>
22
const uint8_t *a;
27
23
+ uint32_t queues_mask = 0;
28
+/* hvf_slot flags */
24
29
+#define HVF_SLOT_LOG (1 << 0)
25
DB_PRINT("\n");
26
27
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
28
s->regs[GEM_DESCONF] = 0x02500111;
29
s->regs[GEM_DESCONF2] = 0x2ab13fff;
30
s->regs[GEM_DESCONF5] = 0x002f2045;
31
- s->regs[GEM_DESCONF6] = 0x00000200;
32
+ s->regs[GEM_DESCONF6] = 0x0;
33
+
30
+
34
+ if (s->num_priority_queues > 1) {
31
+typedef struct hvf_slot {
35
+ queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
32
+ uint64_t start;
36
+ s->regs[GEM_DESCONF6] |= queues_mask;
33
+ uint64_t size;
37
+ }
34
+ uint8_t *mem;
38
35
+ int slot_id;
39
/* Set MAC address */
36
+ uint32_t flags;
40
a = &s->conf.macaddr.a[0];
37
+ MemoryRegion *region;
38
+} hvf_slot;
39
+
40
+typedef struct hvf_vcpu_caps {
41
+ uint64_t vmx_cap_pinbased;
42
+ uint64_t vmx_cap_procbased;
43
+ uint64_t vmx_cap_procbased2;
44
+ uint64_t vmx_cap_entry;
45
+ uint64_t vmx_cap_exit;
46
+ uint64_t vmx_cap_preemption_timer;
47
+} hvf_vcpu_caps;
48
+
49
+struct HVFState {
50
+ AccelState parent;
51
+ hvf_slot slots[32];
52
+ int num_slots;
53
+
54
+ hvf_vcpu_caps *hvf_caps;
55
+};
56
+extern HVFState *hvf_state;
57
+
58
void hvf_set_phys_mem(MemoryRegionSection *, bool);
59
void assert_hvf_ok(hv_return_t ret);
60
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
61
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/i386/hvf/hvf-i386.h
64
+++ b/target/i386/hvf/hvf-i386.h
65
@@ -XXX,XX +XXX,XX @@
66
67
#include "qemu/accel.h"
68
#include "sysemu/hvf.h"
69
+#include "sysemu/hvf_int.h"
70
#include "cpu.h"
71
#include "x86.h"
72
73
-/* hvf_slot flags */
74
-#define HVF_SLOT_LOG (1 << 0)
75
-
76
-typedef struct hvf_slot {
77
- uint64_t start;
78
- uint64_t size;
79
- uint8_t *mem;
80
- int slot_id;
81
- uint32_t flags;
82
- MemoryRegion *region;
83
-} hvf_slot;
84
-
85
-typedef struct hvf_vcpu_caps {
86
- uint64_t vmx_cap_pinbased;
87
- uint64_t vmx_cap_procbased;
88
- uint64_t vmx_cap_procbased2;
89
- uint64_t vmx_cap_entry;
90
- uint64_t vmx_cap_exit;
91
- uint64_t vmx_cap_preemption_timer;
92
-} hvf_vcpu_caps;
93
-
94
-struct HVFState {
95
- AccelState parent;
96
- hvf_slot slots[32];
97
- int num_slots;
98
-
99
- hvf_vcpu_caps *hvf_caps;
100
-};
101
-extern HVFState *hvf_state;
102
-
103
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
104
105
#ifdef NEED_CPU_H
41
--
106
--
42
2.19.1
107
2.20.1
43
108
44
109
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Also introduces neon_element_offset to find the env offset
3
The hvf_set_phys_mem() function is only called within the same file.
4
of a specific element within a neon register.
4
Make it static.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Message-id: 20181011205206.3552-7-richard.henderson@linaro.org
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-6-agraf@csgraf.de
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 63 ++++++++++++++++++++++++------------------
12
include/sysemu/hvf_int.h | 1 -
12
1 file changed, 36 insertions(+), 27 deletions(-)
13
accel/hvf/hvf-accel-ops.c | 2 +-
14
2 files changed, 1 insertion(+), 2 deletions(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/include/sysemu/hvf_int.h
17
+++ b/target/arm/translate.c
19
+++ b/include/sysemu/hvf_int.h
18
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
20
@@ -XXX,XX +XXX,XX @@ struct HVFState {
19
return vfp_reg_offset(0, sreg);
21
};
22
extern HVFState *hvf_state;
23
24
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
25
void assert_hvf_ok(hv_return_t ret);
26
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
27
int hvf_put_registers(CPUState *);
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/accel/hvf/hvf-accel-ops.c
31
+++ b/accel/hvf/hvf-accel-ops.c
32
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
33
return 0;
20
}
34
}
21
35
22
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
36
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
23
+ * where 0 is the least significant end of the register.
37
+static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
24
+ */
25
+static inline long
26
+neon_element_offset(int reg, int element, TCGMemOp size)
27
+{
28
+ int element_size = 1 << size;
29
+ int ofs = element * element_size;
30
+#ifdef HOST_WORDS_BIGENDIAN
31
+ /* Calculate the offset assuming fully little-endian,
32
+ * then XOR to account for the order of the 8-byte units.
33
+ */
34
+ if (element_size < 8) {
35
+ ofs ^= 8 - element_size;
36
+ }
37
+#endif
38
+ return neon_reg_offset(reg, 0) + ofs;
39
+}
40
+
41
static TCGv_i32 neon_load_reg(int reg, int pass)
42
{
38
{
43
TCGv_i32 tmp = tcg_temp_new_i32();
39
hvf_slot *mem;
44
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
40
MemoryRegion *area = section->mr;
45
tmp = load_reg(s, rd);
46
if (insn & (1 << 23)) {
47
/* VDUP */
48
- if (size == 0) {
49
- gen_neon_dup_u8(tmp, 0);
50
- } else if (size == 1) {
51
- gen_neon_dup_low16(tmp);
52
- }
53
- for (n = 0; n <= pass * 2; n++) {
54
- tmp2 = tcg_temp_new_i32();
55
- tcg_gen_mov_i32(tmp2, tmp);
56
- neon_store_reg(rn, n, tmp2);
57
- }
58
- neon_store_reg(rn, n, tmp);
59
+ int vec_size = pass ? 16 : 8;
60
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
61
+ vec_size, vec_size, tmp);
62
+ tcg_temp_free_i32(tmp);
63
} else {
64
/* VMOV */
65
switch (size) {
66
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
67
tcg_temp_free_i32(tmp);
68
} else if ((insn & 0x380) == 0) {
69
/* VDUP */
70
+ int element;
71
+ TCGMemOp size;
72
+
73
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
74
return 1;
75
}
76
- if (insn & (1 << 19)) {
77
- tmp = neon_load_reg(rm, 1);
78
- } else {
79
- tmp = neon_load_reg(rm, 0);
80
- }
81
if (insn & (1 << 16)) {
82
- gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
83
+ size = MO_8;
84
+ element = (insn >> 17) & 7;
85
} else if (insn & (1 << 17)) {
86
- if ((insn >> 18) & 1)
87
- gen_neon_dup_high16(tmp);
88
- else
89
- gen_neon_dup_low16(tmp);
90
+ size = MO_16;
91
+ element = (insn >> 18) & 3;
92
+ } else {
93
+ size = MO_32;
94
+ element = (insn >> 19) & 1;
95
}
96
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
97
- tmp2 = tcg_temp_new_i32();
98
- tcg_gen_mov_i32(tmp2, tmp);
99
- neon_store_reg(rd, pass, tmp2);
100
- }
101
- tcg_temp_free_i32(tmp);
102
+ tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
103
+ neon_element_offset(rm, element, size),
104
+ q ? 16 : 8, q ? 16 : 8);
105
} else {
106
return 1;
107
}
108
--
41
--
109
2.19.1
42
2.20.1
110
43
111
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
For a sequence of loads or stores from a single register,
3
The ARM version of Hypervisor.framework no longer defines these two
4
little-endian operations can be promoted to an 8-byte op.
4
types, so let's just revert to standard ones.
5
This can reduce the number of operations by a factor of 8.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Message-id: 20181011205206.3552-20-richard.henderson@linaro.org
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20210519202253.76782-7-agraf@csgraf.de
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/translate.c | 10 ++++++++++
12
accel/hvf/hvf-accel-ops.c | 6 +++---
14
1 file changed, 10 insertions(+)
13
1 file changed, 3 insertions(+), 3 deletions(-)
15
14
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
17
--- a/accel/hvf/hvf-accel-ops.c
19
+++ b/target/arm/translate.c
18
+++ b/accel/hvf/hvf-accel-ops.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
21
if (size == 3 && (interleave | spacing) != 1) {
20
macslot->present = 1;
22
return 1;
21
macslot->gpa_start = slot->start;
23
}
22
macslot->size = slot->size;
24
+ /* For our purposes, bytes are always little-endian. */
23
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
25
+ if (size == 0) {
24
+ ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
26
+ endian = MO_LE;
25
assert_hvf_ok(ret);
27
+ }
26
return 0;
28
+ /* Consecutive little-endian elements from a single register
27
}
29
+ * can be promoted to a larger little-endian operation.
28
@@ -XXX,XX +XXX,XX @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
30
+ */
29
/* protect region against writes; begin tracking it */
31
+ if (interleave == 1 && endian == MO_LE) {
30
if (on) {
32
+ size = 3;
31
slot->flags |= HVF_SLOT_LOG;
33
+ }
32
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
34
tmp64 = tcg_temp_new_i64();
33
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
35
addr = tcg_temp_new_i32();
34
HV_MEMORY_READ);
36
tmp2 = tcg_const_i32(1 << size);
35
/* stop tracking region*/
36
} else {
37
slot->flags &= ~HVF_SLOT_LOG;
38
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
39
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
40
HV_MEMORY_READ | HV_MEMORY_WRITE);
41
}
42
}
37
--
43
--
38
2.19.1
44
2.20.1
39
45
40
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Instead of shifts and masks, use direct loads and stores from
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
the neon register file.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
5
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
This patch splits the vcpu init and destroy functions into a generic and
7
Message-id: 20181011205206.3552-21-richard.henderson@linaro.org
9
an architecture specific portion. This also allows us to move the generic
10
functions into the generic hvf code, removing exported functions.
11
12
Signed-off-by: Alexander Graf <agraf@csgraf.de>
13
Reviewed-by: Sergio Lopez <slp@redhat.com>
14
Message-id: 20210519202253.76782-8-agraf@csgraf.de
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.c | 92 +++++++++++++++++++++++-------------------
18
accel/hvf/hvf-accel-ops.h | 2 --
12
1 file changed, 50 insertions(+), 42 deletions(-)
19
include/sysemu/hvf_int.h | 2 ++
20
accel/hvf/hvf-accel-ops.c | 30 ++++++++++++++++++++++++++++++
21
target/i386/hvf/hvf.c | 23 ++---------------------
22
4 files changed, 34 insertions(+), 23 deletions(-)
13
23
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
26
--- a/accel/hvf/hvf-accel-ops.h
17
+++ b/target/arm/translate.c
27
+++ b/accel/hvf/hvf-accel-ops.h
18
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
28
@@ -XXX,XX +XXX,XX @@
19
return tmp;
29
20
}
30
#include "sysemu/cpus.h"
21
31
22
+static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
32
-int hvf_init_vcpu(CPUState *);
33
int hvf_vcpu_exec(CPUState *);
34
void hvf_cpu_synchronize_state(CPUState *);
35
void hvf_cpu_synchronize_post_reset(CPUState *);
36
void hvf_cpu_synchronize_post_init(CPUState *);
37
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
38
-void hvf_vcpu_destroy(CPUState *);
39
40
#endif /* HVF_CPUS_H */
41
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/sysemu/hvf_int.h
44
+++ b/include/sysemu/hvf_int.h
45
@@ -XXX,XX +XXX,XX @@ struct HVFState {
46
extern HVFState *hvf_state;
47
48
void assert_hvf_ok(hv_return_t ret);
49
+int hvf_arch_init_vcpu(CPUState *cpu);
50
+void hvf_arch_vcpu_destroy(CPUState *cpu);
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
52
int hvf_put_registers(CPUState *);
53
int hvf_get_registers(CPUState *);
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/hvf/hvf-accel-ops.c
57
+++ b/accel/hvf/hvf-accel-ops.c
58
@@ -XXX,XX +XXX,XX @@ static void hvf_type_init(void)
59
60
type_init(hvf_type_init);
61
62
+static void hvf_vcpu_destroy(CPUState *cpu)
23
+{
63
+{
24
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
64
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
65
+ assert_hvf_ok(ret);
25
+
66
+
26
+ switch (mop) {
67
+ hvf_arch_vcpu_destroy(cpu);
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
+}
68
+}
40
+
69
+
41
static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
70
+static int hvf_init_vcpu(CPUState *cpu)
42
{
43
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
44
@@ -XXX,XX +XXX,XX @@ static void neon_store_reg(int reg, int pass, TCGv_i32 var)
45
tcg_temp_free_i32(var);
46
}
47
48
+static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
49
+{
71
+{
50
+ long offset = neon_element_offset(reg, ele, size);
72
+ int r;
51
+
73
+
52
+ switch (size) {
74
+ /* init cpu signals */
53
+ case MO_8:
75
+ sigset_t set;
54
+ tcg_gen_st8_i32(var, cpu_env, offset);
76
+ struct sigaction sigact;
55
+ break;
77
+
56
+ case MO_16:
78
+ memset(&sigact, 0, sizeof(sigact));
57
+ tcg_gen_st16_i32(var, cpu_env, offset);
79
+ sigact.sa_handler = dummy_signal;
58
+ break;
80
+ sigaction(SIG_IPI, &sigact, NULL);
59
+ case MO_32:
81
+
60
+ tcg_gen_st_i32(var, cpu_env, offset);
82
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
61
+ break;
83
+ sigdelset(&set, SIG_IPI);
62
+ default:
84
+
63
+ g_assert_not_reached();
85
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
64
+ }
86
+ cpu->vcpu_dirty = 1;
87
+ assert_hvf_ok(r);
88
+
89
+ return hvf_arch_init_vcpu(cpu);
65
+}
90
+}
66
+
91
+
67
static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
92
/*
93
* The HVF-specific vCPU thread function. This one should only run when the host
94
* CPU supports the VMX "unrestricted guest" feature.
95
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/i386/hvf/hvf.c
98
+++ b/target/i386/hvf/hvf.c
99
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
100
return false;
101
}
102
103
-void hvf_vcpu_destroy(CPUState *cpu)
104
+void hvf_arch_vcpu_destroy(CPUState *cpu)
68
{
105
{
69
long offset = neon_element_offset(reg, ele, size);
106
X86CPU *x86_cpu = X86_CPU(cpu);
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
107
CPUX86State *env = &x86_cpu->env;
71
int stride;
108
72
int size;
109
- hv_return_t ret = hv_vcpu_destroy((hv_vcpuid_t)cpu->hvf_fd);
73
int reg;
110
g_free(env->hvf_mmio_buf);
74
- int pass;
111
- assert_hvf_ok(ret);
75
int load;
112
}
76
- int shift;
113
77
int n;
114
static void init_tsc_freq(CPUX86State *env)
78
int vec_size;
115
@@ -XXX,XX +XXX,XX @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
79
int mmu_idx;
116
return env->apic_bus_freq != 0;
80
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
117
}
81
} else {
118
82
/* Single element. */
119
-int hvf_init_vcpu(CPUState *cpu)
83
int idx = (insn >> 4) & 0xf;
120
+int hvf_arch_init_vcpu(CPUState *cpu)
84
- pass = (insn >> 7) & 1;
121
{
85
+ int reg_idx;
122
-
86
switch (size) {
123
X86CPU *x86cpu = X86_CPU(cpu);
87
case 0:
124
CPUX86State *env = &x86cpu->env;
88
- shift = ((insn >> 5) & 3) * 8;
125
- int r;
89
+ reg_idx = (insn >> 5) & 7;
126
-
90
stride = 1;
127
- /* init cpu signals */
91
break;
128
- sigset_t set;
92
case 1:
129
- struct sigaction sigact;
93
- shift = ((insn >> 6) & 1) * 16;
130
-
94
+ reg_idx = (insn >> 6) & 3;
131
- memset(&sigact, 0, sizeof(sigact));
95
stride = (insn & (1 << 5)) ? 2 : 1;
132
- sigact.sa_handler = dummy_signal;
96
break;
133
- sigaction(SIG_IPI, &sigact, NULL);
97
case 2:
134
-
98
- shift = 0;
135
- pthread_sigmask(SIG_BLOCK, NULL, &set);
99
+ reg_idx = (insn >> 7) & 1;
136
- sigdelset(&set, SIG_IPI);
100
stride = (insn & (1 << 6)) ? 2 : 1;
137
101
break;
138
init_emu();
102
default:
139
init_decoder();
103
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
140
@@ -XXX,XX +XXX,XX @@ int hvf_init_vcpu(CPUState *cpu)
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
- }
126
- if (size != 2) {
127
- tmp2 = neon_load_reg(rd, pass);
128
- tcg_gen_deposit_i32(tmp, tmp2, tmp,
129
- shift, size ? 16 : 8);
130
- tcg_temp_free_i32(tmp2);
131
- }
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
}
141
}
163
}
142
}
143
144
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
145
- cpu->vcpu_dirty = 1;
146
- assert_hvf_ok(r);
147
-
148
if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,
149
&hvf_state->hvf_caps->vmx_cap_pinbased)) {
150
abort();
164
--
151
--
165
2.19.1
152
2.20.1
166
153
167
154
diff view generated by jsdifflib
1
From: Richard Henderson <rth@twiddle.net>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
This can reduce the number of opcodes required for certain
3
There is no reason to call the hvf specific hvf_cpu_synchronize_state()
4
complex forms of load-multiple (e.g. ld4.16b).
4
when we can just use the generic cpu_synchronize_state() instead. This
5
allows us to have less dependency on internal function definitions and
6
allows us to make hvf_cpu_synchronize_state() static.
5
7
6
Signed-off-by: Richard Henderson <rth@twiddle.net>
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Message-id: 20181011205206.3552-2-richard.henderson@linaro.org
9
Reviewed-by: Sergio Lopez <slp@redhat.com>
10
Message-id: 20210519202253.76782-9-agraf@csgraf.de
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate-a64.c | 12 ++++++++----
14
accel/hvf/hvf-accel-ops.h | 1 -
12
1 file changed, 8 insertions(+), 4 deletions(-)
15
accel/hvf/hvf-accel-ops.c | 2 +-
16
target/i386/hvf/x86hvf.c | 9 ++++-----
17
3 files changed, 5 insertions(+), 7 deletions(-)
13
18
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
21
--- a/accel/hvf/hvf-accel-ops.h
17
+++ b/target/arm/translate-a64.c
22
+++ b/accel/hvf/hvf-accel-ops.h
18
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
23
@@ -XXX,XX +XXX,XX @@
19
bool is_store = !extract32(insn, 22, 1);
24
#include "sysemu/cpus.h"
20
bool is_postidx = extract32(insn, 23, 1);
25
21
bool is_q = extract32(insn, 30, 1);
26
int hvf_vcpu_exec(CPUState *);
22
- TCGv_i64 tcg_addr, tcg_rn;
27
-void hvf_cpu_synchronize_state(CPUState *);
23
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
28
void hvf_cpu_synchronize_post_reset(CPUState *);
24
29
void hvf_cpu_synchronize_post_init(CPUState *);
25
int ebytes = 1 << size;
30
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
26
int elements = (is_q ? 128 : 64) / (8 << size);
31
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
32
index XXXXXXX..XXXXXXX 100644
28
tcg_rn = cpu_reg_sp(s, rn);
33
--- a/accel/hvf/hvf-accel-ops.c
29
tcg_addr = tcg_temp_new_i64();
34
+++ b/accel/hvf/hvf-accel-ops.c
30
tcg_gen_mov_i64(tcg_addr, tcg_rn);
35
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
31
+ tcg_ebytes = tcg_const_i64(ebytes);
32
33
for (r = 0; r < rpt; r++) {
34
int e;
35
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
36
clear_vec_high(s, is_q, tt);
37
}
38
}
39
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
40
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
41
tt = (tt + 1) % 32;
42
}
43
}
44
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
45
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
46
}
47
}
36
}
48
+ tcg_temp_free_i64(tcg_ebytes);
49
tcg_temp_free_i64(tcg_addr);
50
}
37
}
51
38
52
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
39
-void hvf_cpu_synchronize_state(CPUState *cpu)
53
bool replicate = false;
40
+static void hvf_cpu_synchronize_state(CPUState *cpu)
54
int index = is_q << 3 | S << 2 | size;
41
{
55
int ebytes, xs;
42
if (!cpu->vcpu_dirty) {
56
- TCGv_i64 tcg_addr, tcg_rn;
43
run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
57
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
44
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
58
45
index XXXXXXX..XXXXXXX 100644
59
switch (scale) {
46
--- a/target/i386/hvf/x86hvf.c
60
case 3:
47
+++ b/target/i386/hvf/x86hvf.c
61
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
48
@@ -XXX,XX +XXX,XX @@
62
tcg_rn = cpu_reg_sp(s, rn);
49
#include "cpu.h"
63
tcg_addr = tcg_temp_new_i64();
50
#include "x86_descr.h"
64
tcg_gen_mov_i64(tcg_addr, tcg_rn);
51
#include "x86_decode.h"
65
+ tcg_ebytes = tcg_const_i64(ebytes);
52
+#include "sysemu/hw_accel.h"
66
53
67
for (xs = 0; xs < selem; xs++) {
54
#include "hw/i386/apic_internal.h"
68
if (replicate) {
55
69
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
56
#include <Hypervisor/hv.h>
70
do_vec_st(s, rt, index, tcg_addr, scale);
57
#include <Hypervisor/hv_vmx.h>
71
}
58
72
}
59
-#include "accel/hvf/hvf-accel-ops.h"
73
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
60
-
74
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
61
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
75
rt = (rt + 1) % 32;
62
SegmentCache *qseg, bool is_tr)
63
{
64
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
65
env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
66
67
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
68
- hvf_cpu_synchronize_state(cpu_state);
69
+ cpu_synchronize_state(cpu_state);
70
do_cpu_init(cpu);
76
}
71
}
77
72
78
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
73
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
79
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
74
cpu_state->halted = 0;
80
}
81
}
75
}
82
+ tcg_temp_free_i64(tcg_ebytes);
76
if (cpu_state->interrupt_request & CPU_INTERRUPT_SIPI) {
83
tcg_temp_free_i64(tcg_addr);
77
- hvf_cpu_synchronize_state(cpu_state);
84
}
78
+ cpu_synchronize_state(cpu_state);
85
79
do_cpu_sipi(cpu);
80
}
81
if (cpu_state->interrupt_request & CPU_INTERRUPT_TPR) {
82
cpu_state->interrupt_request &= ~CPU_INTERRUPT_TPR;
83
- hvf_cpu_synchronize_state(cpu_state);
84
+ cpu_synchronize_state(cpu_state);
85
apic_handle_tpr_access_report(cpu->apic_state, env->eip,
86
env->tpr_access_type);
87
}
86
--
88
--
87
2.19.1
89
2.20.1
88
90
89
91
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Create struct ARMISARegisters, to be accessed during translation.
3
The hvf accel synchronize functions are only used as input for local
4
callback functions, so we can make them static.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Message-id: 20181016223115.24100-2-richard.henderson@linaro.org
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-10-agraf@csgraf.de
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/cpu.h | 32 ++++----
12
accel/hvf/hvf-accel-ops.h | 3 ---
11
hw/intc/armv7m_nvic.c | 12 +--
13
accel/hvf/hvf-accel-ops.c | 6 +++---
12
target/arm/cpu.c | 178 +++++++++++++++++++++---------------------
14
2 files changed, 3 insertions(+), 6 deletions(-)
13
target/arm/cpu64.c | 70 ++++++++---------
14
target/arm/helper.c | 28 +++----
15
5 files changed, 162 insertions(+), 158 deletions(-)
16
15
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
18
--- a/accel/hvf/hvf-accel-ops.h
20
+++ b/target/arm/cpu.h
19
+++ b/accel/hvf/hvf-accel-ops.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
@@ -XXX,XX +XXX,XX @@
22
* ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
21
#include "sysemu/cpus.h"
23
* is used for reset values of non-constant registers; no reset_
22
24
* prefix means a constant register.
23
int hvf_vcpu_exec(CPUState *);
25
+ * Some of these registers are split out into a substructure that
24
-void hvf_cpu_synchronize_post_reset(CPUState *);
26
+ * is shared with the translators to control the ISA.
25
-void hvf_cpu_synchronize_post_init(CPUState *);
27
*/
26
-void hvf_cpu_synchronize_pre_loadvm(CPUState *);
28
+ struct ARMISARegisters {
27
29
+ uint32_t id_isar0;
28
#endif /* HVF_CPUS_H */
30
+ uint32_t id_isar1;
29
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
31
+ uint32_t id_isar2;
32
+ uint32_t id_isar3;
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
30
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/intc/armv7m_nvic.c
31
--- a/accel/hvf/hvf-accel-ops.c
78
+++ b/hw/intc/armv7m_nvic.c
32
+++ b/accel/hvf/hvf-accel-ops.c
79
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
33
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
80
case 0xd5c: /* MMFR3. */
34
cpu->vcpu_dirty = false;
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
}
127
128
if (!cpu->has_el2) {
129
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
130
* registers if we don't have EL2. These are id_pfr1[15:12] and
131
* id_aa64pfr0_el1[11:8].
132
*/
133
- cpu->id_aa64pfr0 &= ~0xf00;
134
+ cpu->isar.id_aa64pfr0 &= ~0xf00;
135
cpu->id_pfr1 &= ~0xf000;
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
139
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
140
cpu->midr = 0x4107b362;
141
cpu->reset_fpsid = 0x410120b4;
142
- cpu->mvfr0 = 0x11111111;
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
}
35
}
165
36
166
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
37
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
167
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
38
+static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
168
cpu->midr = 0x4117b363;
39
{
169
cpu->reset_fpsid = 0x410120b4;
40
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
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
}
41
}
193
42
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
194
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
43
cpu->vcpu_dirty = false;
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
}
44
}
221
45
222
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
46
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
223
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
47
+static void hvf_cpu_synchronize_post_init(CPUState *cpu)
224
cpu->midr = 0x410fb022;
48
{
225
cpu->reset_fpsid = 0x410120b4;
49
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
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
}
50
}
249
51
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
250
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
52
cpu->vcpu_dirty = true;
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
}
53
}
269
54
270
static void cortex_m4_initfn(Object *obj)
55
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
271
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
56
+static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
272
cpu->id_mmfr1 = 0x00000000;
57
{
273
cpu->id_mmfr2 = 0x00000000;
58
run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
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
}
59
}
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
--
60
--
668
2.19.1
61
2.20.1
669
62
670
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
We can move the definition of hvf_vcpu_exec() into our internal
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
hvf header, obsoleting the need for hvf-accel-ops.h.
5
Message-id: 20181011205206.3552-6-richard.henderson@linaro.org
5
6
[PMM: drop change to now-deleted cpu_mode_names array]
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-11-agraf@csgraf.de
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/translate.c | 4 ++--
12
accel/hvf/hvf-accel-ops.h | 17 -----------------
11
1 file changed, 2 insertions(+), 2 deletions(-)
13
include/sysemu/hvf_int.h | 1 +
14
accel/hvf/hvf-accel-ops.c | 2 --
15
target/i386/hvf/hvf.c | 2 --
16
4 files changed, 1 insertion(+), 21 deletions(-)
17
delete mode 100644 accel/hvf/hvf-accel-ops.h
12
18
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
20
deleted file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- a/accel/hvf/hvf-accel-ops.h
23
+++ /dev/null
24
@@ -XXX,XX +XXX,XX @@
25
-/*
26
- * Accelerator CPUS Interface
27
- *
28
- * Copyright 2020 SUSE LLC
29
- *
30
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
31
- * See the COPYING file in the top-level directory.
32
- */
33
-
34
-#ifndef HVF_CPUS_H
35
-#define HVF_CPUS_H
36
-
37
-#include "sysemu/cpus.h"
38
-
39
-int hvf_vcpu_exec(CPUState *);
40
-
41
-#endif /* HVF_CPUS_H */
42
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
14
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
44
--- a/include/sysemu/hvf_int.h
16
+++ b/target/arm/translate.c
45
+++ b/include/sysemu/hvf_int.h
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 cpu_F0d, cpu_F1d;
46
@@ -XXX,XX +XXX,XX @@ extern HVFState *hvf_state;
18
47
void assert_hvf_ok(hv_return_t ret);
19
#include "exec/gen-icount.h"
48
int hvf_arch_init_vcpu(CPUState *cpu);
20
49
void hvf_arch_vcpu_destroy(CPUState *cpu);
21
-static const char *regnames[] =
50
+int hvf_vcpu_exec(CPUState *);
22
+static const char * const regnames[] =
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
23
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
52
int hvf_put_registers(CPUState *);
24
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
53
int hvf_get_registers(CPUState *);
25
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
26
@@ -XXX,XX +XXX,XX @@ static struct {
55
index XXXXXXX..XXXXXXX 100644
27
int nregs;
56
--- a/accel/hvf/hvf-accel-ops.c
28
int interleave;
57
+++ b/accel/hvf/hvf-accel-ops.c
29
int spacing;
58
@@ -XXX,XX +XXX,XX @@
30
-} neon_ls_element_type[11] = {
59
#include "sysemu/runstate.h"
31
+} const neon_ls_element_type[11] = {
60
#include "qemu/guest-random.h"
32
{4, 4, 1},
61
33
{4, 4, 2},
62
-#include "hvf-accel-ops.h"
34
{4, 1, 1},
63
-
64
HVFState *hvf_state;
65
66
/* Memory slots */
67
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/i386/hvf/hvf.c
70
+++ b/target/i386/hvf/hvf.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "qemu/accel.h"
73
#include "target/i386/cpu.h"
74
75
-#include "hvf-accel-ops.h"
76
-
77
void vmx_update_tpr(CPUState *cpu)
78
{
79
/* TODO: need integrate APIC handling */
35
--
80
--
36
2.19.1
81
2.20.1
37
82
38
83
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
We will need more than a single field for hvf going forward. To keep
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
the global vcpu struct uncluttered, let's allocate a special hvf vcpu
5
Message-id: 20181016223115.24100-9-richard.henderson@linaro.org
5
struct, similar to how hax does it.
6
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-12-agraf@csgraf.de
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
15
---
9
target/arm/cpu.h | 17 +++++++++++++++-
16
include/hw/core/cpu.h | 3 +-
10
linux-user/elfload.c | 6 +-----
17
include/sysemu/hvf_int.h | 4 +
11
target/arm/cpu64.c | 16 ++++++++-------
18
target/i386/hvf/vmx.h | 24 +++--
12
target/arm/helper.c | 2 +-
19
accel/hvf/hvf-accel-ops.c | 8 +-
13
target/arm/translate-a64.c | 40 +++++++++++++++++++-------------------
20
target/i386/hvf/hvf.c | 104 +++++++++---------
14
target/arm/translate.c | 6 +++---
21
target/i386/hvf/x86.c | 28 ++---
15
6 files changed, 50 insertions(+), 37 deletions(-)
22
target/i386/hvf/x86_descr.c | 26 ++---
23
target/i386/hvf/x86_emu.c | 62 +++++------
24
target/i386/hvf/x86_mmu.c | 4 +-
25
target/i386/hvf/x86_task.c | 12 +--
26
target/i386/hvf/x86hvf.c | 210 ++++++++++++++++++------------------
27
11 files changed, 248 insertions(+), 237 deletions(-)
16
28
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
31
--- a/include/hw/core/cpu.h
20
+++ b/target/arm/cpu.h
32
+++ b/include/hw/core/cpu.h
21
@@ -XXX,XX +XXX,XX @@ enum arm_features {
33
@@ -XXX,XX +XXX,XX @@ struct KVMState;
22
ARM_FEATURE_PMU, /* has PMU support */
34
struct kvm_run;
23
ARM_FEATURE_VBAR, /* has cp15 VBAR */
35
24
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
36
struct hax_vcpu_state;
25
- ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
37
+struct hvf_vcpu_state;
26
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
38
39
#define TB_JMP_CACHE_BITS 12
40
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
41
@@ -XXX,XX +XXX,XX @@ struct CPUState {
42
43
struct hax_vcpu_state *hax_vcpu;
44
45
- int hvf_fd;
46
+ struct hvf_vcpu_state *hvf;
47
48
/* track IOMMUs whose translations we've cached in the TCG TLB */
49
GArray *iommu_notifiers;
50
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/sysemu/hvf_int.h
53
+++ b/include/sysemu/hvf_int.h
54
@@ -XXX,XX +XXX,XX @@ struct HVFState {
27
};
55
};
28
56
extern HVFState *hvf_state;
29
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
57
30
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
58
+struct hvf_vcpu_state {
31
}
59
+ int fd;
32
60
+};
33
+static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
34
+{
35
+ /*
36
+ * This is a placeholder for use by VCMA until the rest of
37
+ * the ARMv8.2-FP16 extension is implemented for aa32 mode.
38
+ * At which point we can properly set and check MVFR1.FPHP.
39
+ */
40
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
41
+}
42
+
61
+
43
/*
62
void assert_hvf_ok(hv_return_t ret);
44
* 64-bit feature tests via id registers.
63
int hvf_arch_init_vcpu(CPUState *cpu);
45
*/
64
void hvf_arch_vcpu_destroy(CPUState *cpu);
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
65
diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
47
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
66
index XXXXXXX..XXXXXXX 100644
48
}
67
--- a/target/i386/hvf/vmx.h
49
68
+++ b/target/i386/hvf/vmx.h
50
+static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
69
@@ -XXX,XX +XXX,XX @@
51
+{
70
#include "vmcs.h"
52
+ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
71
#include "cpu.h"
53
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
72
#include "x86.h"
54
+}
73
+#include "sysemu/hvf.h"
74
+#include "sysemu/hvf_int.h"
75
76
#include "exec/address-spaces.h"
77
78
@@ -XXX,XX +XXX,XX @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
79
uint64_t val;
80
81
/* BUG, should take considering overlap.. */
82
- wreg(cpu->hvf_fd, HV_X86_RIP, rip);
83
+ wreg(cpu->hvf->fd, HV_X86_RIP, rip);
84
env->eip = rip;
85
86
/* after moving forward in rip, we need to clean INTERRUPTABILITY */
87
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
88
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
89
if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
90
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
91
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
92
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY,
93
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY,
94
val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
95
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
96
}
97
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_blocking(CPUState *cpu)
98
CPUX86State *env = &x86_cpu->env;
99
100
env->hflags2 &= ~HF2_NMI_MASK;
101
- uint32_t gi = (uint32_t) rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
102
+ uint32_t gi = (uint32_t) rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
103
gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
104
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
105
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
106
}
107
108
static inline void vmx_set_nmi_blocking(CPUState *cpu)
109
@@ -XXX,XX +XXX,XX @@ static inline void vmx_set_nmi_blocking(CPUState *cpu)
110
CPUX86State *env = &x86_cpu->env;
111
112
env->hflags2 |= HF2_NMI_MASK;
113
- uint32_t gi = (uint32_t)rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
114
+ uint32_t gi = (uint32_t)rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
115
gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
116
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
117
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
118
}
119
120
static inline void vmx_set_nmi_window_exiting(CPUState *cpu)
121
{
122
uint64_t val;
123
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
124
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
125
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
126
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
127
VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
128
129
}
130
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_window_exiting(CPUState *cpu)
131
{
132
133
uint64_t val;
134
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
135
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
136
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
137
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
138
~VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
139
}
140
141
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/accel/hvf/hvf-accel-ops.c
144
+++ b/accel/hvf/hvf-accel-ops.c
145
@@ -XXX,XX +XXX,XX @@ type_init(hvf_type_init);
146
147
static void hvf_vcpu_destroy(CPUState *cpu)
148
{
149
- hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
150
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf->fd);
151
assert_hvf_ok(ret);
152
153
hvf_arch_vcpu_destroy(cpu);
154
+ g_free(cpu->hvf);
155
+ cpu->hvf = NULL;
156
}
157
158
static int hvf_init_vcpu(CPUState *cpu)
159
{
160
int r;
161
162
+ cpu->hvf = g_malloc0(sizeof(*cpu->hvf));
55
+
163
+
56
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
164
/* init cpu signals */
57
{
165
sigset_t set;
58
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
166
struct sigaction sigact;
59
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
167
@@ -XXX,XX +XXX,XX @@ static int hvf_init_vcpu(CPUState *cpu)
168
pthread_sigmask(SIG_BLOCK, NULL, &set);
169
sigdelset(&set, SIG_IPI);
170
171
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
172
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
173
cpu->vcpu_dirty = 1;
174
assert_hvf_ok(r);
175
176
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
60
index XXXXXXX..XXXXXXX 100644
177
index XXXXXXX..XXXXXXX 100644
61
--- a/linux-user/elfload.c
178
--- a/target/i386/hvf/hvf.c
62
+++ b/linux-user/elfload.c
179
+++ b/target/i386/hvf/hvf.c
63
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
180
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
64
hwcaps |= ARM_HWCAP_A64_ASIMD;
181
int tpr = cpu_get_apic_tpr(x86_cpu->apic_state) << 4;
65
182
int irr = apic_get_highest_priority_irr(x86_cpu->apic_state);
66
/* probe for the extra features */
183
67
-#define GET_FEATURE(feat, hwcap) \
184
- wreg(cpu->hvf_fd, HV_X86_TPR, tpr);
68
- do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
185
+ wreg(cpu->hvf->fd, HV_X86_TPR, tpr);
69
#define GET_FEATURE_ID(feat, hwcap) \
186
if (irr == -1) {
70
do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
187
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
71
188
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
72
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
189
} else {
73
GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
190
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
74
GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
191
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
75
GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
192
irr >> 4);
76
- GET_FEATURE(ARM_FEATURE_V8_FP16,
193
}
77
- ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
194
}
78
+ GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
195
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
79
GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
196
static void update_apic_tpr(CPUState *cpu)
80
GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
197
{
81
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
198
X86CPU *x86_cpu = X86_CPU(cpu);
82
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
199
- int tpr = rreg(cpu->hvf_fd, HV_X86_TPR) >> 4;
83
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
200
+ int tpr = rreg(cpu->hvf->fd, HV_X86_TPR) >> 4;
84
201
cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
85
-#undef GET_FEATURE
202
}
86
#undef GET_FEATURE_ID
203
87
204
@@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu)
88
return hwcaps;
205
}
89
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
206
90
index XXXXXXX..XXXXXXX 100644
207
/* set VMCS control fields */
91
--- a/target/arm/cpu64.c
208
- wvmcs(cpu->hvf_fd, VMCS_PIN_BASED_CTLS,
92
+++ b/target/arm/cpu64.c
209
+ wvmcs(cpu->hvf->fd, VMCS_PIN_BASED_CTLS,
93
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
210
cap2ctrl(hvf_state->hvf_caps->vmx_cap_pinbased,
94
211
VMCS_PIN_BASED_CTLS_EXTINT |
95
t = cpu->isar.id_aa64pfr0;
212
VMCS_PIN_BASED_CTLS_NMI |
96
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
213
VMCS_PIN_BASED_CTLS_VNMI));
97
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
214
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS,
98
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
215
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS,
99
cpu->isar.id_aa64pfr0 = t;
216
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased,
100
217
VMCS_PRI_PROC_BASED_CTLS_HLT |
101
/* Replicate the same data to the 32-bit id registers. */
218
VMCS_PRI_PROC_BASED_CTLS_MWAIT |
102
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
219
VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
103
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
220
VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
104
cpu->isar.id_isar6 = u;
221
VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
105
222
- wvmcs(cpu->hvf_fd, VMCS_SEC_PROC_BASED_CTLS,
106
-#ifdef CONFIG_USER_ONLY
223
+ wvmcs(cpu->hvf->fd, VMCS_SEC_PROC_BASED_CTLS,
107
- /* We don't set these in system emulation mode for the moment,
224
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2,
108
- * since we don't correctly set the ID registers to advertise them,
225
VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
109
- * and in some cases they're only available in AArch64 and not AArch32,
226
110
- * whereas the architecture requires them to be present in both if
227
- wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
111
- * present in either.
228
+ wvmcs(cpu->hvf->fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
112
+ /*
229
0));
113
+ * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
230
- wvmcs(cpu->hvf_fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
114
+ * so do not set MVFR1.FPHP. Strictly speaking this is not legal,
231
+ wvmcs(cpu->hvf->fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
115
+ * but it is also not legal to enable SVE without support for FP16,
232
116
+ * and enabling SVE in system mode is more useful in the short term.
233
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
117
*/
234
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
118
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
235
119
+
236
x86cpu = X86_CPU(cpu);
120
+#ifdef CONFIG_USER_ONLY
237
x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
121
/* For usermode -cpu max we can use a larger and more efficient DCZ
238
122
* blocksize since we don't have to follow what the hardware does.
239
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_STAR, 1);
123
*/
240
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_LSTAR, 1);
124
diff --git a/target/arm/helper.c b/target/arm/helper.c
241
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_CSTAR, 1);
125
index XXXXXXX..XXXXXXX 100644
242
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FMASK, 1);
126
--- a/target/arm/helper.c
243
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FSBASE, 1);
127
+++ b/target/arm/helper.c
244
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_GSBASE, 1);
128
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
245
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_KERNELGSBASE, 1);
129
uint32_t changed;
246
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_TSC_AUX, 1);
130
247
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_TSC, 1);
131
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
248
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_CS, 1);
132
- if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
249
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_EIP, 1);
133
+ if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
250
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_ESP, 1);
134
val &= ~FPCR_FZ16;
251
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_STAR, 1);
135
}
252
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
136
253
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_CSTAR, 1);
137
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
254
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FMASK, 1);
138
index XXXXXXX..XXXXXXX 100644
255
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FSBASE, 1);
139
--- a/target/arm/translate-a64.c
256
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_GSBASE, 1);
140
+++ b/target/arm/translate-a64.c
257
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_KERNELGSBASE, 1);
141
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
258
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_TSC_AUX, 1);
142
break;
259
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_TSC, 1);
143
case 3:
260
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_CS, 1);
144
size = MO_16;
261
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_EIP, 1);
145
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
262
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_ESP, 1);
146
+ if (dc_isar_feature(aa64_fp16, s)) {
263
264
return 0;
265
}
266
@@ -XXX,XX +XXX,XX @@ static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_in
267
}
268
if (idtvec_info & VMCS_IDT_VEC_ERRCODE_VALID) {
269
env->has_error_code = true;
270
- env->error_code = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_ERROR);
271
+ env->error_code = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_ERROR);
272
}
273
}
274
- if ((rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
275
+ if ((rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
276
VMCS_INTERRUPTIBILITY_NMI_BLOCKING)) {
277
env->hflags2 |= HF2_NMI_MASK;
278
} else {
279
env->hflags2 &= ~HF2_NMI_MASK;
280
}
281
- if (rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
282
+ if (rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
283
(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
284
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
285
env->hflags |= HF_INHIBIT_IRQ_MASK;
286
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
287
return EXCP_HLT;
288
}
289
290
- hv_return_t r = hv_vcpu_run(cpu->hvf_fd);
291
+ hv_return_t r = hv_vcpu_run(cpu->hvf->fd);
292
assert_hvf_ok(r);
293
294
/* handle VMEXIT */
295
- uint64_t exit_reason = rvmcs(cpu->hvf_fd, VMCS_EXIT_REASON);
296
- uint64_t exit_qual = rvmcs(cpu->hvf_fd, VMCS_EXIT_QUALIFICATION);
297
- uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd,
298
+ uint64_t exit_reason = rvmcs(cpu->hvf->fd, VMCS_EXIT_REASON);
299
+ uint64_t exit_qual = rvmcs(cpu->hvf->fd, VMCS_EXIT_QUALIFICATION);
300
+ uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf->fd,
301
VMCS_EXIT_INSTRUCTION_LENGTH);
302
303
- uint64_t idtvec_info = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
304
+ uint64_t idtvec_info = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
305
306
hvf_store_events(cpu, ins_len, idtvec_info);
307
- rip = rreg(cpu->hvf_fd, HV_X86_RIP);
308
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
309
+ rip = rreg(cpu->hvf->fd, HV_X86_RIP);
310
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
311
312
qemu_mutex_lock_iothread();
313
314
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
315
case EXIT_REASON_EPT_FAULT:
316
{
317
hvf_slot *slot;
318
- uint64_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
319
+ uint64_t gpa = rvmcs(cpu->hvf->fd, VMCS_GUEST_PHYSICAL_ADDRESS);
320
321
if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&
322
((exit_qual & EXIT_QUAL_NMIUDTI) != 0)) {
323
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
324
store_regs(cpu);
325
break;
326
} else if (!string && !in) {
327
- RAX(env) = rreg(cpu->hvf_fd, HV_X86_RAX);
328
+ RAX(env) = rreg(cpu->hvf->fd, HV_X86_RAX);
329
hvf_handle_io(env, port, &RAX(env), 1, size, 1);
330
macvm_set_rip(cpu, rip + ins_len);
331
break;
332
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
147
break;
333
break;
148
}
334
}
149
/* fallthru */
335
case EXIT_REASON_CPUID: {
150
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
336
- uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
151
break;
337
- uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);
152
case 3:
338
- uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
153
size = MO_16;
339
- uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
154
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
340
+ uint32_t rax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
155
+ if (dc_isar_feature(aa64_fp16, s)) {
341
+ uint32_t rbx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RBX);
342
+ uint32_t rcx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
343
+ uint32_t rdx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
344
345
if (rax == 1) {
346
/* CPUID1.ecx.OSXSAVE needs to know CR4 */
347
- env->cr[4] = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
348
+ env->cr[4] = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
349
}
350
hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);
351
352
- wreg(cpu->hvf_fd, HV_X86_RAX, rax);
353
- wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
354
- wreg(cpu->hvf_fd, HV_X86_RCX, rcx);
355
- wreg(cpu->hvf_fd, HV_X86_RDX, rdx);
356
+ wreg(cpu->hvf->fd, HV_X86_RAX, rax);
357
+ wreg(cpu->hvf->fd, HV_X86_RBX, rbx);
358
+ wreg(cpu->hvf->fd, HV_X86_RCX, rcx);
359
+ wreg(cpu->hvf->fd, HV_X86_RDX, rdx);
360
361
macvm_set_rip(cpu, rip + ins_len);
362
break;
363
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
364
case EXIT_REASON_XSETBV: {
365
X86CPU *x86_cpu = X86_CPU(cpu);
366
CPUX86State *env = &x86_cpu->env;
367
- uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
368
- uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
369
- uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
370
+ uint32_t eax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
371
+ uint32_t ecx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
372
+ uint32_t edx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
373
374
if (ecx) {
375
macvm_set_rip(cpu, rip + ins_len);
376
break;
377
}
378
env->xcr0 = ((uint64_t)edx << 32) | eax;
379
- wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);
380
+ wreg(cpu->hvf->fd, HV_X86_XCR0, env->xcr0 | 1);
381
macvm_set_rip(cpu, rip + ins_len);
156
break;
382
break;
157
}
383
}
158
/* fallthru */
384
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
159
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
385
160
break;
386
switch (cr) {
161
case 3:
387
case 0x0: {
162
sz = MO_16;
388
- macvm_set_cr0(cpu->hvf_fd, RRX(env, reg));
163
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
389
+ macvm_set_cr0(cpu->hvf->fd, RRX(env, reg));
164
+ if (dc_isar_feature(aa64_fp16, s)) {
390
break;
391
}
392
case 4: {
393
- macvm_set_cr4(cpu->hvf_fd, RRX(env, reg));
394
+ macvm_set_cr4(cpu->hvf->fd, RRX(env, reg));
395
break;
396
}
397
case 8: {
398
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
165
break;
399
break;
166
}
400
}
167
/* fallthru */
401
case EXIT_REASON_TASK_SWITCH: {
168
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
402
- uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
169
handle_fp_1src_double(s, opcode, rd, rn);
403
+ uint64_t vinfo = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
170
break;
404
x68_segment_selector sel = {.sel = exit_qual & 0xffff};
171
case 3:
405
vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,
172
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
406
vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo
173
+ if (!dc_isar_feature(aa64_fp16, s)) {
407
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
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;
408
break;
202
}
409
}
203
/* fallthru */
410
case EXIT_REASON_RDPMC:
204
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
411
- wreg(cpu->hvf_fd, HV_X86_RAX, 0);
205
case 1: /* float64 */
412
- wreg(cpu->hvf_fd, HV_X86_RDX, 0);
413
+ wreg(cpu->hvf->fd, HV_X86_RAX, 0);
414
+ wreg(cpu->hvf->fd, HV_X86_RDX, 0);
415
macvm_set_rip(cpu, rip + ins_len);
416
break;
417
case VMX_REASON_VMCALL:
418
diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c
419
index XXXXXXX..XXXXXXX 100644
420
--- a/target/i386/hvf/x86.c
421
+++ b/target/i386/hvf/x86.c
422
@@ -XXX,XX +XXX,XX @@ bool x86_read_segment_descriptor(struct CPUState *cpu,
423
}
424
425
if (GDT_SEL == sel.ti) {
426
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
427
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
428
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
429
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
430
} else {
431
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
432
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
433
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
434
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
435
}
436
437
if (sel.index * 8 >= limit) {
438
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
439
uint32_t limit;
440
441
if (GDT_SEL == sel.ti) {
442
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
443
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
444
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
445
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
446
} else {
447
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
448
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
449
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
450
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
451
}
452
453
if (sel.index * 8 >= limit) {
454
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
455
bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
456
int gate)
457
{
458
- target_ulong base = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE);
459
- uint32_t limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
460
+ target_ulong base = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_BASE);
461
+ uint32_t limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
462
463
memset(idt_desc, 0, sizeof(*idt_desc));
464
if (gate * 8 >= limit) {
465
@@ -XXX,XX +XXX,XX @@ bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
466
467
bool x86_is_protected(struct CPUState *cpu)
468
{
469
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
470
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
471
return cr0 & CR0_PE;
472
}
473
474
@@ -XXX,XX +XXX,XX @@ bool x86_is_v8086(struct CPUState *cpu)
475
476
bool x86_is_long_mode(struct CPUState *cpu)
477
{
478
- return rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
479
+ return rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
480
}
481
482
bool x86_is_long64_mode(struct CPUState *cpu)
483
@@ -XXX,XX +XXX,XX @@ bool x86_is_long64_mode(struct CPUState *cpu)
484
485
bool x86_is_paging_mode(struct CPUState *cpu)
486
{
487
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
488
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
489
return cr0 & CR0_PG;
490
}
491
492
bool x86_is_pae_enabled(struct CPUState *cpu)
493
{
494
- uint64_t cr4 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
495
+ uint64_t cr4 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
496
return cr4 & CR4_PAE;
497
}
498
499
diff --git a/target/i386/hvf/x86_descr.c b/target/i386/hvf/x86_descr.c
500
index XXXXXXX..XXXXXXX 100644
501
--- a/target/i386/hvf/x86_descr.c
502
+++ b/target/i386/hvf/x86_descr.c
503
@@ -XXX,XX +XXX,XX @@ static const struct vmx_segment_field {
504
505
uint32_t vmx_read_segment_limit(CPUState *cpu, X86Seg seg)
506
{
507
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
508
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
509
}
510
511
uint32_t vmx_read_segment_ar(CPUState *cpu, X86Seg seg)
512
{
513
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
514
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
515
}
516
517
uint64_t vmx_read_segment_base(CPUState *cpu, X86Seg seg)
518
{
519
- return rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
520
+ return rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
521
}
522
523
x68_segment_selector vmx_read_segment_selector(CPUState *cpu, X86Seg seg)
524
{
525
x68_segment_selector sel;
526
- sel.sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
527
+ sel.sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
528
return sel;
529
}
530
531
void vmx_write_segment_selector(struct CPUState *cpu, x68_segment_selector selector, X86Seg seg)
532
{
533
- wvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector, selector.sel);
534
+ wvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector, selector.sel);
535
}
536
537
void vmx_read_segment_descriptor(struct CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
538
{
539
- desc->sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
540
- desc->base = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
541
- desc->limit = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
542
- desc->ar = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
543
+ desc->sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
544
+ desc->base = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
545
+ desc->limit = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
546
+ desc->ar = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
547
}
548
549
void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
550
{
551
const struct vmx_segment_field *sf = &vmx_segment_fields[seg];
552
553
- wvmcs(cpu->hvf_fd, sf->base, desc->base);
554
- wvmcs(cpu->hvf_fd, sf->limit, desc->limit);
555
- wvmcs(cpu->hvf_fd, sf->selector, desc->sel);
556
- wvmcs(cpu->hvf_fd, sf->ar_bytes, desc->ar);
557
+ wvmcs(cpu->hvf->fd, sf->base, desc->base);
558
+ wvmcs(cpu->hvf->fd, sf->limit, desc->limit);
559
+ wvmcs(cpu->hvf->fd, sf->selector, desc->sel);
560
+ wvmcs(cpu->hvf->fd, sf->ar_bytes, desc->ar);
561
}
562
563
void x86_segment_descriptor_to_vmx(struct CPUState *cpu, x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc)
564
diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c
565
index XXXXXXX..XXXXXXX 100644
566
--- a/target/i386/hvf/x86_emu.c
567
+++ b/target/i386/hvf/x86_emu.c
568
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
569
570
switch (msr) {
571
case MSR_IA32_TSC:
572
- val = rdtscp() + rvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET);
573
+ val = rdtscp() + rvmcs(cpu->hvf->fd, VMCS_TSC_OFFSET);
206
break;
574
break;
207
case 3: /* float16 */
575
case MSR_IA32_APICBASE:
208
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
576
val = cpu_get_apic_base(X86_CPU(cpu)->apic_state);
209
+ if (dc_isar_feature(aa64_fp16, s)) {
577
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
210
break;
578
val = x86_cpu->ucode_rev;
211
}
579
break;
212
/* fallthru */
580
case MSR_EFER:
213
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
581
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER);
214
break;
582
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER);
215
case 0x6: /* 16-bit float, 32-bit int */
583
break;
216
case 0xe: /* 16-bit float, 64-bit int */
584
case MSR_FSBASE:
217
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
585
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE);
218
+ if (dc_isar_feature(aa64_fp16, s)) {
586
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE);
219
break;
587
break;
220
}
588
case MSR_GSBASE:
221
/* fallthru */
589
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE);
222
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
590
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE);
223
case 1: /* float64 */
591
break;
224
break;
592
case MSR_KERNELGSBASE:
225
case 3: /* float16 */
593
- val = rvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE);
226
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
594
+ val = rvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE);
227
+ if (dc_isar_feature(aa64_fp16, s)) {
595
break;
228
break;
596
case MSR_STAR:
229
}
597
abort();
230
/* fallthru */
598
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
231
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
599
cpu_set_apic_base(X86_CPU(cpu)->apic_state, data);
232
*/
600
break;
233
is_min = extract32(size, 1, 1);
601
case MSR_FSBASE:
234
is_fp = true;
602
- wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, data);
235
- if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
603
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE, data);
236
+ if (!is_u && dc_isar_feature(aa64_fp16, s)) {
604
break;
237
size = 1;
605
case MSR_GSBASE:
238
} else if (!is_u || !is_q || extract32(size, 0, 1)) {
606
- wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, data);
239
unallocated_encoding(s);
607
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE, data);
240
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
608
break;
241
609
case MSR_KERNELGSBASE:
242
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
610
- wvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE, data);
243
/* Check for FMOV (vector, immediate) - half-precision */
611
+ wvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE, data);
244
- if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
612
break;
245
+ if (!(dc_isar_feature(aa64_fp16, s) && o2 && cmode == 0xf)) {
613
case MSR_STAR:
246
unallocated_encoding(s);
614
abort();
247
return;
615
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
248
}
616
break;
249
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
617
case MSR_EFER:
250
case 0x2f: /* FMINP */
618
/*printf("new efer %llx\n", EFER(cpu));*/
251
/* FP op, size[0] is 32 or 64 bit*/
619
- wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, data);
252
if (!u) {
620
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER, data);
253
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
621
if (data & MSR_EFER_NXE) {
254
+ if (!dc_isar_feature(aa64_fp16, s)) {
622
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
255
unallocated_encoding(s);
623
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
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
}
624
}
314
break;
625
break;
315
}
626
case MSR_MTRRphysBase(0):
316
- if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
627
@@ -XXX,XX +XXX,XX @@ void load_regs(struct CPUState *cpu)
317
+ if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
628
CPUX86State *env = &x86_cpu->env;
318
unallocated_encoding(s);
629
630
int i = 0;
631
- RRX(env, R_EAX) = rreg(cpu->hvf_fd, HV_X86_RAX);
632
- RRX(env, R_EBX) = rreg(cpu->hvf_fd, HV_X86_RBX);
633
- RRX(env, R_ECX) = rreg(cpu->hvf_fd, HV_X86_RCX);
634
- RRX(env, R_EDX) = rreg(cpu->hvf_fd, HV_X86_RDX);
635
- RRX(env, R_ESI) = rreg(cpu->hvf_fd, HV_X86_RSI);
636
- RRX(env, R_EDI) = rreg(cpu->hvf_fd, HV_X86_RDI);
637
- RRX(env, R_ESP) = rreg(cpu->hvf_fd, HV_X86_RSP);
638
- RRX(env, R_EBP) = rreg(cpu->hvf_fd, HV_X86_RBP);
639
+ RRX(env, R_EAX) = rreg(cpu->hvf->fd, HV_X86_RAX);
640
+ RRX(env, R_EBX) = rreg(cpu->hvf->fd, HV_X86_RBX);
641
+ RRX(env, R_ECX) = rreg(cpu->hvf->fd, HV_X86_RCX);
642
+ RRX(env, R_EDX) = rreg(cpu->hvf->fd, HV_X86_RDX);
643
+ RRX(env, R_ESI) = rreg(cpu->hvf->fd, HV_X86_RSI);
644
+ RRX(env, R_EDI) = rreg(cpu->hvf->fd, HV_X86_RDI);
645
+ RRX(env, R_ESP) = rreg(cpu->hvf->fd, HV_X86_RSP);
646
+ RRX(env, R_EBP) = rreg(cpu->hvf->fd, HV_X86_RBP);
647
for (i = 8; i < 16; i++) {
648
- RRX(env, i) = rreg(cpu->hvf_fd, HV_X86_RAX + i);
649
+ RRX(env, i) = rreg(cpu->hvf->fd, HV_X86_RAX + i);
650
}
651
652
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
653
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
654
rflags_to_lflags(env);
655
- env->eip = rreg(cpu->hvf_fd, HV_X86_RIP);
656
+ env->eip = rreg(cpu->hvf->fd, HV_X86_RIP);
657
}
658
659
void store_regs(struct CPUState *cpu)
660
@@ -XXX,XX +XXX,XX @@ void store_regs(struct CPUState *cpu)
661
CPUX86State *env = &x86_cpu->env;
662
663
int i = 0;
664
- wreg(cpu->hvf_fd, HV_X86_RAX, RAX(env));
665
- wreg(cpu->hvf_fd, HV_X86_RBX, RBX(env));
666
- wreg(cpu->hvf_fd, HV_X86_RCX, RCX(env));
667
- wreg(cpu->hvf_fd, HV_X86_RDX, RDX(env));
668
- wreg(cpu->hvf_fd, HV_X86_RSI, RSI(env));
669
- wreg(cpu->hvf_fd, HV_X86_RDI, RDI(env));
670
- wreg(cpu->hvf_fd, HV_X86_RBP, RBP(env));
671
- wreg(cpu->hvf_fd, HV_X86_RSP, RSP(env));
672
+ wreg(cpu->hvf->fd, HV_X86_RAX, RAX(env));
673
+ wreg(cpu->hvf->fd, HV_X86_RBX, RBX(env));
674
+ wreg(cpu->hvf->fd, HV_X86_RCX, RCX(env));
675
+ wreg(cpu->hvf->fd, HV_X86_RDX, RDX(env));
676
+ wreg(cpu->hvf->fd, HV_X86_RSI, RSI(env));
677
+ wreg(cpu->hvf->fd, HV_X86_RDI, RDI(env));
678
+ wreg(cpu->hvf->fd, HV_X86_RBP, RBP(env));
679
+ wreg(cpu->hvf->fd, HV_X86_RSP, RSP(env));
680
for (i = 8; i < 16; i++) {
681
- wreg(cpu->hvf_fd, HV_X86_RAX + i, RRX(env, i));
682
+ wreg(cpu->hvf->fd, HV_X86_RAX + i, RRX(env, i));
683
}
684
685
lflags_to_rflags(env);
686
- wreg(cpu->hvf_fd, HV_X86_RFLAGS, env->eflags);
687
+ wreg(cpu->hvf->fd, HV_X86_RFLAGS, env->eflags);
688
macvm_set_rip(cpu, env->eip);
689
}
690
691
diff --git a/target/i386/hvf/x86_mmu.c b/target/i386/hvf/x86_mmu.c
692
index XXXXXXX..XXXXXXX 100644
693
--- a/target/i386/hvf/x86_mmu.c
694
+++ b/target/i386/hvf/x86_mmu.c
695
@@ -XXX,XX +XXX,XX @@ static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
696
pt->err_code |= MMU_PAGE_PT;
697
}
698
699
- uint32_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
700
+ uint32_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
701
/* check protection */
702
if (cr0 & CR0_WP) {
703
if (pt->write_access && !pte_write_access(pte)) {
704
@@ -XXX,XX +XXX,XX @@ static bool walk_gpt(struct CPUState *cpu, target_ulong addr, int err_code,
705
{
706
int top_level, level;
707
bool is_large = false;
708
- target_ulong cr3 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR3);
709
+ target_ulong cr3 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR3);
710
uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
711
712
memset(pt, 0, sizeof(*pt));
713
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
714
index XXXXXXX..XXXXXXX 100644
715
--- a/target/i386/hvf/x86_task.c
716
+++ b/target/i386/hvf/x86_task.c
717
@@ -XXX,XX +XXX,XX @@ static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
718
X86CPU *x86_cpu = X86_CPU(cpu);
719
CPUX86State *env = &x86_cpu->env;
720
721
- wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, tss->cr3);
722
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_CR3, tss->cr3);
723
724
env->eip = tss->eip;
725
env->eflags = tss->eflags | 2;
726
@@ -XXX,XX +XXX,XX @@ static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segme
727
728
void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
729
{
730
- uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
731
+ uint64_t rip = rreg(cpu->hvf->fd, HV_X86_RIP);
732
if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
733
gate_type != VMCS_INTR_T_HWINTR &&
734
gate_type != VMCS_INTR_T_NMI)) {
735
- int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
736
+ int ins_len = rvmcs(cpu->hvf->fd, VMCS_EXIT_INSTRUCTION_LENGTH);
737
macvm_set_rip(cpu, rip + ins_len);
319
return;
738
return;
320
}
739
}
321
diff --git a/target/arm/translate.c b/target/arm/translate.c
740
@@ -XXX,XX +XXX,XX @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea
741
//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
742
VM_PANIC("task_switch_16");
743
744
- macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
745
+ macvm_set_cr0(cpu->hvf->fd, rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0) | CR0_TS);
746
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
747
vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);
748
749
store_regs(cpu);
750
751
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
752
- hv_vcpu_flush(cpu->hvf_fd);
753
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
754
+ hv_vcpu_flush(cpu->hvf->fd);
755
}
756
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
322
index XXXXXXX..XXXXXXX 100644
757
index XXXXXXX..XXXXXXX 100644
323
--- a/target/arm/translate.c
758
--- a/target/i386/hvf/x86hvf.c
324
+++ b/target/arm/translate.c
759
+++ b/target/i386/hvf/x86hvf.c
325
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
760
@@ -XXX,XX +XXX,XX @@ void hvf_put_xsave(CPUState *cpu_state)
326
int size = extract32(insn, 20, 1);
761
327
data = extract32(insn, 23, 2); /* rot */
762
x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
328
if (!dc_isar_feature(aa32_vcma, s)
763
329
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
764
- if (hv_vcpu_write_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
330
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
765
+ if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
331
return 1;
766
abort();
767
}
768
}
769
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
770
CPUX86State *env = &X86_CPU(cpu_state)->env;
771
struct vmx_segment seg;
772
773
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
774
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
775
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
776
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
777
778
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
779
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
780
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
781
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
782
783
- /* wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR2, env->cr[2]); */
784
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3, env->cr[3]);
785
+ /* wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR2, env->cr[2]); */
786
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3, env->cr[3]);
787
vmx_update_tpr(cpu_state);
788
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER, env->efer);
789
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER, env->efer);
790
791
- macvm_set_cr4(cpu_state->hvf_fd, env->cr[4]);
792
- macvm_set_cr0(cpu_state->hvf_fd, env->cr[0]);
793
+ macvm_set_cr4(cpu_state->hvf->fd, env->cr[4]);
794
+ macvm_set_cr0(cpu_state->hvf->fd, env->cr[0]);
795
796
hvf_set_segment(cpu_state, &seg, &env->segs[R_CS], false);
797
vmx_write_segment_descriptor(cpu_state, &seg, R_CS);
798
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
799
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
800
vmx_write_segment_descriptor(cpu_state, &seg, R_LDTR);
801
802
- hv_vcpu_flush(cpu_state->hvf_fd);
803
+ hv_vcpu_flush(cpu_state->hvf->fd);
804
}
805
806
void hvf_put_msrs(CPUState *cpu_state)
807
{
808
CPUX86State *env = &X86_CPU(cpu_state)->env;
809
810
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS,
811
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS,
812
env->sysenter_cs);
813
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP,
814
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP,
815
env->sysenter_esp);
816
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP,
817
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP,
818
env->sysenter_eip);
819
820
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_STAR, env->star);
821
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_STAR, env->star);
822
823
#ifdef TARGET_X86_64
824
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_CSTAR, env->cstar);
825
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, env->kernelgsbase);
826
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FMASK, env->fmask);
827
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_LSTAR, env->lstar);
828
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_CSTAR, env->cstar);
829
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, env->kernelgsbase);
830
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FMASK, env->fmask);
831
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_LSTAR, env->lstar);
832
#endif
833
834
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_GSBASE, env->segs[R_GS].base);
835
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FSBASE, env->segs[R_FS].base);
836
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_GSBASE, env->segs[R_GS].base);
837
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FSBASE, env->segs[R_FS].base);
838
}
839
840
841
@@ -XXX,XX +XXX,XX @@ void hvf_get_xsave(CPUState *cpu_state)
842
843
xsave = X86_CPU(cpu_state)->env.xsave_buf;
844
845
- if (hv_vcpu_read_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
846
+ if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
847
abort();
848
}
849
850
@@ -XXX,XX +XXX,XX @@ void hvf_get_segments(CPUState *cpu_state)
851
vmx_read_segment_descriptor(cpu_state, &seg, R_LDTR);
852
hvf_get_segment(&env->ldt, &seg);
853
854
- env->idt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
855
- env->idt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE);
856
- env->gdt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
857
- env->gdt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE);
858
+ env->idt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
859
+ env->idt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE);
860
+ env->gdt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
861
+ env->gdt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE);
862
863
- env->cr[0] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR0);
864
+ env->cr[0] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR0);
865
env->cr[2] = 0;
866
- env->cr[3] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3);
867
- env->cr[4] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR4);
868
+ env->cr[3] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3);
869
+ env->cr[4] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR4);
870
871
- env->efer = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER);
872
+ env->efer = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER);
873
}
874
875
void hvf_get_msrs(CPUState *cpu_state)
876
@@ -XXX,XX +XXX,XX @@ void hvf_get_msrs(CPUState *cpu_state)
877
CPUX86State *env = &X86_CPU(cpu_state)->env;
878
uint64_t tmp;
879
880
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS, &tmp);
881
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS, &tmp);
882
env->sysenter_cs = tmp;
883
884
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP, &tmp);
885
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP, &tmp);
886
env->sysenter_esp = tmp;
887
888
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP, &tmp);
889
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP, &tmp);
890
env->sysenter_eip = tmp;
891
892
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_STAR, &env->star);
893
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_STAR, &env->star);
894
895
#ifdef TARGET_X86_64
896
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_CSTAR, &env->cstar);
897
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, &env->kernelgsbase);
898
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_FMASK, &env->fmask);
899
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_LSTAR, &env->lstar);
900
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_CSTAR, &env->cstar);
901
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, &env->kernelgsbase);
902
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_FMASK, &env->fmask);
903
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_LSTAR, &env->lstar);
904
#endif
905
906
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_APICBASE, &tmp);
907
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_APICBASE, &tmp);
908
909
- env->tsc = rdtscp() + rvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET);
910
+ env->tsc = rdtscp() + rvmcs(cpu_state->hvf->fd, VMCS_TSC_OFFSET);
911
}
912
913
int hvf_put_registers(CPUState *cpu_state)
914
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
915
X86CPU *x86cpu = X86_CPU(cpu_state);
916
CPUX86State *env = &x86cpu->env;
917
918
- wreg(cpu_state->hvf_fd, HV_X86_RAX, env->regs[R_EAX]);
919
- wreg(cpu_state->hvf_fd, HV_X86_RBX, env->regs[R_EBX]);
920
- wreg(cpu_state->hvf_fd, HV_X86_RCX, env->regs[R_ECX]);
921
- wreg(cpu_state->hvf_fd, HV_X86_RDX, env->regs[R_EDX]);
922
- wreg(cpu_state->hvf_fd, HV_X86_RBP, env->regs[R_EBP]);
923
- wreg(cpu_state->hvf_fd, HV_X86_RSP, env->regs[R_ESP]);
924
- wreg(cpu_state->hvf_fd, HV_X86_RSI, env->regs[R_ESI]);
925
- wreg(cpu_state->hvf_fd, HV_X86_RDI, env->regs[R_EDI]);
926
- wreg(cpu_state->hvf_fd, HV_X86_R8, env->regs[8]);
927
- wreg(cpu_state->hvf_fd, HV_X86_R9, env->regs[9]);
928
- wreg(cpu_state->hvf_fd, HV_X86_R10, env->regs[10]);
929
- wreg(cpu_state->hvf_fd, HV_X86_R11, env->regs[11]);
930
- wreg(cpu_state->hvf_fd, HV_X86_R12, env->regs[12]);
931
- wreg(cpu_state->hvf_fd, HV_X86_R13, env->regs[13]);
932
- wreg(cpu_state->hvf_fd, HV_X86_R14, env->regs[14]);
933
- wreg(cpu_state->hvf_fd, HV_X86_R15, env->regs[15]);
934
- wreg(cpu_state->hvf_fd, HV_X86_RFLAGS, env->eflags);
935
- wreg(cpu_state->hvf_fd, HV_X86_RIP, env->eip);
936
+ wreg(cpu_state->hvf->fd, HV_X86_RAX, env->regs[R_EAX]);
937
+ wreg(cpu_state->hvf->fd, HV_X86_RBX, env->regs[R_EBX]);
938
+ wreg(cpu_state->hvf->fd, HV_X86_RCX, env->regs[R_ECX]);
939
+ wreg(cpu_state->hvf->fd, HV_X86_RDX, env->regs[R_EDX]);
940
+ wreg(cpu_state->hvf->fd, HV_X86_RBP, env->regs[R_EBP]);
941
+ wreg(cpu_state->hvf->fd, HV_X86_RSP, env->regs[R_ESP]);
942
+ wreg(cpu_state->hvf->fd, HV_X86_RSI, env->regs[R_ESI]);
943
+ wreg(cpu_state->hvf->fd, HV_X86_RDI, env->regs[R_EDI]);
944
+ wreg(cpu_state->hvf->fd, HV_X86_R8, env->regs[8]);
945
+ wreg(cpu_state->hvf->fd, HV_X86_R9, env->regs[9]);
946
+ wreg(cpu_state->hvf->fd, HV_X86_R10, env->regs[10]);
947
+ wreg(cpu_state->hvf->fd, HV_X86_R11, env->regs[11]);
948
+ wreg(cpu_state->hvf->fd, HV_X86_R12, env->regs[12]);
949
+ wreg(cpu_state->hvf->fd, HV_X86_R13, env->regs[13]);
950
+ wreg(cpu_state->hvf->fd, HV_X86_R14, env->regs[14]);
951
+ wreg(cpu_state->hvf->fd, HV_X86_R15, env->regs[15]);
952
+ wreg(cpu_state->hvf->fd, HV_X86_RFLAGS, env->eflags);
953
+ wreg(cpu_state->hvf->fd, HV_X86_RIP, env->eip);
954
955
- wreg(cpu_state->hvf_fd, HV_X86_XCR0, env->xcr0);
956
+ wreg(cpu_state->hvf->fd, HV_X86_XCR0, env->xcr0);
957
958
hvf_put_xsave(cpu_state);
959
960
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
961
962
hvf_put_msrs(cpu_state);
963
964
- wreg(cpu_state->hvf_fd, HV_X86_DR0, env->dr[0]);
965
- wreg(cpu_state->hvf_fd, HV_X86_DR1, env->dr[1]);
966
- wreg(cpu_state->hvf_fd, HV_X86_DR2, env->dr[2]);
967
- wreg(cpu_state->hvf_fd, HV_X86_DR3, env->dr[3]);
968
- wreg(cpu_state->hvf_fd, HV_X86_DR4, env->dr[4]);
969
- wreg(cpu_state->hvf_fd, HV_X86_DR5, env->dr[5]);
970
- wreg(cpu_state->hvf_fd, HV_X86_DR6, env->dr[6]);
971
- wreg(cpu_state->hvf_fd, HV_X86_DR7, env->dr[7]);
972
+ wreg(cpu_state->hvf->fd, HV_X86_DR0, env->dr[0]);
973
+ wreg(cpu_state->hvf->fd, HV_X86_DR1, env->dr[1]);
974
+ wreg(cpu_state->hvf->fd, HV_X86_DR2, env->dr[2]);
975
+ wreg(cpu_state->hvf->fd, HV_X86_DR3, env->dr[3]);
976
+ wreg(cpu_state->hvf->fd, HV_X86_DR4, env->dr[4]);
977
+ wreg(cpu_state->hvf->fd, HV_X86_DR5, env->dr[5]);
978
+ wreg(cpu_state->hvf->fd, HV_X86_DR6, env->dr[6]);
979
+ wreg(cpu_state->hvf->fd, HV_X86_DR7, env->dr[7]);
980
981
return 0;
982
}
983
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
984
X86CPU *x86cpu = X86_CPU(cpu_state);
985
CPUX86State *env = &x86cpu->env;
986
987
- env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
988
- env->regs[R_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
989
- env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
990
- env->regs[R_EDX] = rreg(cpu_state->hvf_fd, HV_X86_RDX);
991
- env->regs[R_EBP] = rreg(cpu_state->hvf_fd, HV_X86_RBP);
992
- env->regs[R_ESP] = rreg(cpu_state->hvf_fd, HV_X86_RSP);
993
- env->regs[R_ESI] = rreg(cpu_state->hvf_fd, HV_X86_RSI);
994
- env->regs[R_EDI] = rreg(cpu_state->hvf_fd, HV_X86_RDI);
995
- env->regs[8] = rreg(cpu_state->hvf_fd, HV_X86_R8);
996
- env->regs[9] = rreg(cpu_state->hvf_fd, HV_X86_R9);
997
- env->regs[10] = rreg(cpu_state->hvf_fd, HV_X86_R10);
998
- env->regs[11] = rreg(cpu_state->hvf_fd, HV_X86_R11);
999
- env->regs[12] = rreg(cpu_state->hvf_fd, HV_X86_R12);
1000
- env->regs[13] = rreg(cpu_state->hvf_fd, HV_X86_R13);
1001
- env->regs[14] = rreg(cpu_state->hvf_fd, HV_X86_R14);
1002
- env->regs[15] = rreg(cpu_state->hvf_fd, HV_X86_R15);
1003
+ env->regs[R_EAX] = rreg(cpu_state->hvf->fd, HV_X86_RAX);
1004
+ env->regs[R_EBX] = rreg(cpu_state->hvf->fd, HV_X86_RBX);
1005
+ env->regs[R_ECX] = rreg(cpu_state->hvf->fd, HV_X86_RCX);
1006
+ env->regs[R_EDX] = rreg(cpu_state->hvf->fd, HV_X86_RDX);
1007
+ env->regs[R_EBP] = rreg(cpu_state->hvf->fd, HV_X86_RBP);
1008
+ env->regs[R_ESP] = rreg(cpu_state->hvf->fd, HV_X86_RSP);
1009
+ env->regs[R_ESI] = rreg(cpu_state->hvf->fd, HV_X86_RSI);
1010
+ env->regs[R_EDI] = rreg(cpu_state->hvf->fd, HV_X86_RDI);
1011
+ env->regs[8] = rreg(cpu_state->hvf->fd, HV_X86_R8);
1012
+ env->regs[9] = rreg(cpu_state->hvf->fd, HV_X86_R9);
1013
+ env->regs[10] = rreg(cpu_state->hvf->fd, HV_X86_R10);
1014
+ env->regs[11] = rreg(cpu_state->hvf->fd, HV_X86_R11);
1015
+ env->regs[12] = rreg(cpu_state->hvf->fd, HV_X86_R12);
1016
+ env->regs[13] = rreg(cpu_state->hvf->fd, HV_X86_R13);
1017
+ env->regs[14] = rreg(cpu_state->hvf->fd, HV_X86_R14);
1018
+ env->regs[15] = rreg(cpu_state->hvf->fd, HV_X86_R15);
1019
1020
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1021
- env->eip = rreg(cpu_state->hvf_fd, HV_X86_RIP);
1022
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1023
+ env->eip = rreg(cpu_state->hvf->fd, HV_X86_RIP);
1024
1025
hvf_get_xsave(cpu_state);
1026
- env->xcr0 = rreg(cpu_state->hvf_fd, HV_X86_XCR0);
1027
+ env->xcr0 = rreg(cpu_state->hvf->fd, HV_X86_XCR0);
1028
1029
hvf_get_segments(cpu_state);
1030
hvf_get_msrs(cpu_state);
1031
1032
- env->dr[0] = rreg(cpu_state->hvf_fd, HV_X86_DR0);
1033
- env->dr[1] = rreg(cpu_state->hvf_fd, HV_X86_DR1);
1034
- env->dr[2] = rreg(cpu_state->hvf_fd, HV_X86_DR2);
1035
- env->dr[3] = rreg(cpu_state->hvf_fd, HV_X86_DR3);
1036
- env->dr[4] = rreg(cpu_state->hvf_fd, HV_X86_DR4);
1037
- env->dr[5] = rreg(cpu_state->hvf_fd, HV_X86_DR5);
1038
- env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
1039
- env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
1040
+ env->dr[0] = rreg(cpu_state->hvf->fd, HV_X86_DR0);
1041
+ env->dr[1] = rreg(cpu_state->hvf->fd, HV_X86_DR1);
1042
+ env->dr[2] = rreg(cpu_state->hvf->fd, HV_X86_DR2);
1043
+ env->dr[3] = rreg(cpu_state->hvf->fd, HV_X86_DR3);
1044
+ env->dr[4] = rreg(cpu_state->hvf->fd, HV_X86_DR4);
1045
+ env->dr[5] = rreg(cpu_state->hvf->fd, HV_X86_DR5);
1046
+ env->dr[6] = rreg(cpu_state->hvf->fd, HV_X86_DR6);
1047
+ env->dr[7] = rreg(cpu_state->hvf->fd, HV_X86_DR7);
1048
1049
x86_update_hflags(env);
1050
return 0;
1051
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
1052
static void vmx_set_int_window_exiting(CPUState *cpu)
1053
{
1054
uint64_t val;
1055
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1056
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
1057
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1058
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
1059
VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1060
}
1061
1062
void vmx_clear_int_window_exiting(CPUState *cpu)
1063
{
1064
uint64_t val;
1065
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1066
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
1067
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1068
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
1069
~VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1070
}
1071
1072
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1073
uint64_t info = 0;
1074
if (have_event) {
1075
info = vector | intr_type | VMCS_INTR_VALID;
1076
- uint64_t reason = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_REASON);
1077
+ uint64_t reason = rvmcs(cpu_state->hvf->fd, VMCS_EXIT_REASON);
1078
if (env->nmi_injected && reason != EXIT_REASON_TASK_SWITCH) {
1079
vmx_clear_nmi_blocking(cpu_state);
332
}
1080
}
333
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
1081
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
334
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
1082
info &= ~(1 << 12); /* clear undefined bit */
335
int size = extract32(insn, 20, 1);
1083
if (intr_type == VMCS_INTR_T_SWINTR ||
336
data = extract32(insn, 24, 1); /* rot */
1084
intr_type == VMCS_INTR_T_SWEXCEPTION) {
337
if (!dc_isar_feature(aa32_vcma, s)
1085
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
338
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
1086
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
339
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
1087
}
340
return 1;
1088
1089
if (env->has_error_code) {
1090
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_EXCEPTION_ERROR,
1091
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_EXCEPTION_ERROR,
1092
env->error_code);
1093
/* Indicate that VMCS_ENTRY_EXCEPTION_ERROR is valid */
1094
info |= VMCS_INTR_DEL_ERRCODE;
1095
}
1096
/*printf("reinject %lx err %d\n", info, err);*/
1097
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1098
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1099
};
1100
}
1101
1102
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1103
if (!(env->hflags2 & HF2_NMI_MASK) && !(info & VMCS_INTR_VALID)) {
1104
cpu_state->interrupt_request &= ~CPU_INTERRUPT_NMI;
1105
info = VMCS_INTR_VALID | VMCS_INTR_T_NMI | EXCP02_NMI;
1106
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1107
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1108
} else {
1109
vmx_set_nmi_window_exiting(cpu_state);
341
}
1110
}
342
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
1111
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
343
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
1112
int line = cpu_get_pic_interrupt(&x86cpu->env);
344
return 1;
1113
cpu_state->interrupt_request &= ~CPU_INTERRUPT_HARD;
1114
if (line >= 0) {
1115
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line |
1116
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, line |
1117
VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
345
}
1118
}
346
if (size == 0) {
1119
}
347
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
1120
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
348
+ if (!dc_isar_feature(aa32_fp16_arith, s)) {
1121
X86CPU *cpu = X86_CPU(cpu_state);
349
return 1;
1122
CPUX86State *env = &cpu->env;
350
}
1123
351
/* For fp16, rm is just Vm, and index is M. */
1124
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1125
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1126
1127
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
1128
cpu_synchronize_state(cpu_state);
352
--
1129
--
353
2.19.1
1130
2.20.1
354
1131
355
1132
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Move shi_op and sli_op expanders from translate-a64.c.
3
The hooks we have that call us after reset, init and loadvm really all
4
just want to say "The reference of all register state is in the QEMU
5
vcpu struct, please push it".
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
We already have a working pushing mechanism though called cpu->vcpu_dirty,
6
Message-id: 20181011205206.3552-15-richard.henderson@linaro.org
8
so we can just reuse that for all of the above, syncing state properly the
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
next time we actually execute a vCPU.
10
11
This fixes PSCI resets on ARM, as they modify CPU state even after the
12
post init call has completed, but before we execute the vCPU again.
13
14
To also make the scheme work for x86, we have to make sure we don't
15
move stale eflags into our env when the vcpu state is dirty.
16
17
Signed-off-by: Alexander Graf <agraf@csgraf.de>
18
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
19
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
20
Reviewed-by: Sergio Lopez <slp@redhat.com>
21
Message-id: 20210519202253.76782-13-agraf@csgraf.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
23
---
10
target/arm/translate.h | 2 +
24
accel/hvf/hvf-accel-ops.c | 27 +++++++--------------------
11
target/arm/translate-a64.c | 152 +----------------------
25
target/i386/hvf/x86hvf.c | 5 ++++-
12
target/arm/translate.c | 244 ++++++++++++++++++++++++++-----------
26
2 files changed, 11 insertions(+), 21 deletions(-)
13
3 files changed, 179 insertions(+), 219 deletions(-)
14
27
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
30
--- a/accel/hvf/hvf-accel-ops.c
18
+++ b/target/arm/translate.h
31
+++ b/accel/hvf/hvf-accel-ops.c
19
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 bit_op;
32
@@ -XXX,XX +XXX,XX @@ static void hvf_cpu_synchronize_state(CPUState *cpu)
20
extern const GVecGen3 bif_op;
21
extern const GVecGen2i ssra_op[4];
22
extern const GVecGen2i usra_op[4];
23
+extern const GVecGen2i sri_op[4];
24
+extern const GVecGen2i sli_op[4];
25
26
/*
27
* Forward to the isar_feature_* tests given a DisasContext pointer.
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
33
}
33
}
34
}
34
}
35
35
36
-static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
36
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
37
-{
37
- run_on_cpu_data arg)
38
- uint64_t mask = dup_const(MO_8, 0xff >> shift);
38
+static void do_hvf_cpu_synchronize_set_dirty(CPUState *cpu,
39
- TCGv_i64 t = tcg_temp_new_i64();
39
+ run_on_cpu_data arg)
40
-
40
{
41
- tcg_gen_shri_i64(t, a, shift);
41
- hvf_put_registers(cpu);
42
- tcg_gen_andi_i64(t, t, mask);
42
- cpu->vcpu_dirty = false;
43
- tcg_gen_andi_i64(d, d, ~mask);
43
+ /* QEMU state is the reference, push it to HVF now and on next entry */
44
- tcg_gen_or_i64(d, d, t);
44
+ cpu->vcpu_dirty = true;
45
- tcg_temp_free_i64(t);
45
}
46
47
static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
48
{
49
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
46
-}
50
-}
47
-
51
-
48
-static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
52
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
53
- run_on_cpu_data arg)
49
-{
54
-{
50
- uint64_t mask = dup_const(MO_16, 0xffff >> shift);
55
- hvf_put_registers(cpu);
51
- TCGv_i64 t = tcg_temp_new_i64();
56
- cpu->vcpu_dirty = false;
52
-
57
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
53
- tcg_gen_shri_i64(t, a, shift);
58
}
54
- tcg_gen_andi_i64(t, t, mask);
59
55
- tcg_gen_andi_i64(d, d, ~mask);
60
static void hvf_cpu_synchronize_post_init(CPUState *cpu)
56
- tcg_gen_or_i64(d, d, t);
61
{
57
- tcg_temp_free_i64(t);
62
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
58
-}
63
-}
59
-
64
-
60
-static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
65
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
66
- run_on_cpu_data arg)
61
-{
67
-{
62
- tcg_gen_shri_i32(a, a, shift);
68
- cpu->vcpu_dirty = true;
63
- tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
69
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
64
-}
70
}
65
-
71
66
-static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
72
static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
67
-{
68
- tcg_gen_shri_i64(a, a, shift);
69
- tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
70
-}
71
-
72
-static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
73
-{
74
- uint64_t mask = (2ull << ((8 << vece) - 1)) - 1;
75
- TCGv_vec t = tcg_temp_new_vec_matching(d);
76
- TCGv_vec m = tcg_temp_new_vec_matching(d);
77
-
78
- tcg_gen_dupi_vec(vece, m, mask ^ (mask >> sh));
79
- tcg_gen_shri_vec(vece, t, a, sh);
80
- tcg_gen_and_vec(vece, d, d, m);
81
- tcg_gen_or_vec(vece, d, d, t);
82
-
83
- tcg_temp_free_vec(t);
84
- tcg_temp_free_vec(m);
85
-}
86
-
87
/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
88
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
89
int immh, int immb, int opcode, int rn, int rd)
90
{
73
{
91
- static const GVecGen2i sri_op[4] = {
74
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
92
- { .fni8 = gen_shr8_ins_i64,
75
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
93
- .fniv = gen_shr_ins_vec,
94
- .load_dest = true,
95
- .opc = INDEX_op_shri_vec,
96
- .vece = MO_8 },
97
- { .fni8 = gen_shr16_ins_i64,
98
- .fniv = gen_shr_ins_vec,
99
- .load_dest = true,
100
- .opc = INDEX_op_shri_vec,
101
- .vece = MO_16 },
102
- { .fni4 = gen_shr32_ins_i32,
103
- .fniv = gen_shr_ins_vec,
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
}
76
}
121
77
122
-static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
78
static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
123
-{
79
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
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
214
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
215
--- a/target/arm/translate.c
81
--- a/target/i386/hvf/x86hvf.c
216
+++ b/target/arm/translate.c
82
+++ b/target/i386/hvf/x86hvf.c
217
@@ -XXX,XX +XXX,XX @@ const GVecGen2i usra_op[4] = {
83
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
218
.vece = MO_64, },
84
X86CPU *cpu = X86_CPU(cpu_state);
219
};
85
CPUX86State *env = &cpu->env;
220
86
221
+static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
87
- env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
222
+{
88
+ if (!cpu_state->vcpu_dirty) {
223
+ uint64_t mask = dup_const(MO_8, 0xff >> shift);
89
+ /* light weight sync for CPU_INTERRUPT_HARD and IF_MASK */
224
+ TCGv_i64 t = tcg_temp_new_i64();
90
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
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
+ }
91
+ }
273
+}
92
274
+
93
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
275
+const GVecGen2i sri_op[4] = {
94
cpu_synchronize_state(cpu_state);
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)
379
int pairwise;
380
int u;
381
int vec_size;
382
- uint32_t imm, mask;
383
+ uint32_t imm;
384
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
385
TCGv_ptr ptr1, ptr2, ptr3;
386
TCGv_i64 tmp64;
387
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
388
}
389
return 0;
390
391
+ case 4: /* VSRI */
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) {
467
- case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
468
- case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
469
- case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
470
- default: abort();
471
- }
472
- break;
473
case 6: /* VQSHLU */
474
switch (size) {
475
case 0:
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
--
95
--
520
2.19.1
96
2.20.1
521
97
522
98
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Coverity notes that we don't check for dup2() failing. Add some
2
assertions so that if it does ever happen we get some indication.
3
(This is similar to how we handle other "don't expect this syscall to
4
fail" checks in this test code.)
2
5
3
Since QEMU does not implement ASIDs, changes to the ASID must flush the
6
Fixes: Coverity CID 1432346
4
tlb. However, if the ASID does not change there is no reason to flush.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
9
Message-id: 20210525134458.6675-2-peter.maydell@linaro.org
10
---
11
tests/qtest/bios-tables-test.c | 8 ++++++--
12
1 file changed, 6 insertions(+), 2 deletions(-)
5
13
6
In testing a boot of the Ubuntu installer to the first menu, this reduces
14
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
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>
15
---
16
target/arm/helper.c | 8 +++-----
17
1 file changed, 3 insertions(+), 5 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
16
--- a/tests/qtest/bios-tables-test.c
22
+++ b/target/arm/helper.c
17
+++ b/tests/qtest/bios-tables-test.c
23
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ static void test_acpi_asl(test_data *data)
24
static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
exp_sdt->asl_file, sdt->asl_file);
25
uint64_t value)
20
int out = dup(STDOUT_FILENO);
26
{
21
int ret G_GNUC_UNUSED;
27
- /* 64 bit accesses to the TTBRs can change the ASID and so we
22
+ int dupret;
28
- * must flush the TLB.
23
29
- */
24
- dup2(STDERR_FILENO, STDOUT_FILENO);
30
- if (cpreg_field_is_64bit(ri)) {
25
+ g_assert(out >= 0);
31
+ /* If the ASID changes (with a 64-bit write), we must flush the TLB. */
26
+ dupret = dup2(STDERR_FILENO, STDOUT_FILENO);
32
+ if (cpreg_field_is_64bit(ri) &&
27
+ g_assert(dupret >= 0);
33
+ extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
28
ret = system(diff) ;
34
ARMCPU *cpu = arm_env_get_cpu(env);
29
- dup2(out, STDOUT_FILENO);
35
-
30
+ dupret = dup2(out, STDOUT_FILENO);
36
tlb_flush(CPU(cpu));
31
+ g_assert(dupret >= 0);
37
}
32
close(out);
38
raw_write(env, ri, value);
33
g_free(diff);
34
}
39
--
35
--
40
2.19.1
36
2.20.1
41
37
42
38
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
The e1000e_send_verify() test calls qemu_recv() but doesn't
2
check that the call succeeded, which annoys Coverity. Add
3
an explicit test check for the length of the data.
2
4
3
Announce 64bit addressing support.
5
(This is a test check, not a "we assume this syscall always
6
succeeds", so we use g_assert_cmpint() rather than g_assert().)
4
7
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Fixes: Coverity CID 1432324
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
11
Message-id: 20210525134458.6675-3-peter.maydell@linaro.org
10
---
12
---
11
hw/net/cadence_gem.c | 3 ++-
13
tests/qtest/e1000e-test.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 1 deletion(-)
13
15
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
16
diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/cadence_gem.c
18
--- a/tests/qtest/e1000e-test.c
17
+++ b/hw/net/cadence_gem.c
19
+++ b/tests/qtest/e1000e-test.c
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
19
#define GEM_DESCONF4 (0x0000028C/4)
21
/* Check data sent to the backend */
20
#define GEM_DESCONF5 (0x00000290/4)
22
ret = qemu_recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
21
#define GEM_DESCONF6 (0x00000294/4)
23
g_assert_cmpint(ret, == , sizeof(recv_len));
22
+#define GEM_DESCONF6_64B_MASK (1U << 23)
24
- qemu_recv(test_sockets[0], buffer, 64, 0);
23
#define GEM_DESCONF7 (0x00000298/4)
25
+ ret = qemu_recv(test_sockets[0], buffer, 64, 0);
24
26
+ g_assert_cmpint(ret, >=, 5);
25
#define GEM_INT_Q1_STATUS (0x00000400 / 4)
27
g_assert_cmpstr(buffer, == , "TEST");
26
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
28
27
s->regs[GEM_DESCONF] = 0x02500111;
29
/* Free test data buffer */
28
s->regs[GEM_DESCONF2] = 0x2ab13fff;
29
s->regs[GEM_DESCONF5] = 0x002f2045;
30
- s->regs[GEM_DESCONF6] = 0x0;
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
--
30
--
36
2.19.1
31
2.20.1
37
32
38
33
diff view generated by jsdifflib
1
For traps of FP/SIMD instructions to AArch32 Hyp mode, the syndrome
1
Coverity notices that the checks against mkstemp() failing in
2
provided in HSR has more information than is reported to AArch64.
2
create_qcow2_with_mbr() are wrong: mkstemp returns -1 on failure but
3
Specifically, there are extra fields TA and coproc which indicate
3
the check is just "g_assert(fd)". Fix to use "g_assert(fd >= 0)",
4
whether the trapped instruction was FP or SIMD. Add this extra
4
matching the correct check in create_test_img().
5
information to the syndromes we construct, and mask it out when
6
taking the exception to AArch64.
7
5
6
Fixes: Coverity CID 1432274
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20181012144235.19646-11-peter.maydell@linaro.org
9
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
10
Message-id: 20210525134458.6675-4-peter.maydell@linaro.org
11
---
11
---
12
target/arm/internals.h | 14 +++++++++++++-
12
tests/qtest/hd-geo-test.c | 4 ++--
13
target/arm/helper.c | 9 +++++++++
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
target/arm/translate.c | 8 ++++----
15
3 files changed, 26 insertions(+), 5 deletions(-)
16
14
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/internals.h
17
--- a/tests/qtest/hd-geo-test.c
20
+++ b/target/arm/internals.h
18
+++ b/tests/qtest/hd-geo-test.c
21
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_get_ec(uint32_t syn)
19
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
22
* few cases the value in HSR for exceptions taken to AArch32 Hyp
23
* mode differs slightly, and we fix this up when populating HSR in
24
* arm_cpu_do_interrupt_aarch32_hyp().
25
+ * The exception is FP/SIMD access traps -- these report extra information
26
+ * when taking an exception to AArch32. For those we include the extra coproc
27
+ * and TA fields, and mask them out when taking the exception to AArch64.
28
*/
29
static inline uint32_t syn_uncategorized(void)
30
{
31
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
32
33
static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
34
{
35
+ /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
36
return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
37
| (is_16bit ? 0 : ARM_EL_IL)
38
- | (cv << 24) | (cond << 20);
39
+ | (cv << 24) | (cond << 20) | 0xa;
40
+}
41
+
42
+static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
43
+{
44
+ /* AArch32 SIMD trap: TA == 1 coproc == 0 */
45
+ return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
46
+ | (is_16bit ? 0 : ARM_EL_IL)
47
+ | (cv << 24) | (cond << 20) | (1 << 5);
48
}
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
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
74
+++ 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
}
20
}
83
21
84
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
22
fd = mkstemp(raw_path);
85
*/
23
- g_assert(fd);
86
if (s->fp_excp_el) {
24
+ g_assert(fd >= 0);
87
gen_exception_insn(s, 4, EXCP_UDEF,
25
close(fd);
88
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
26
89
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
27
fd = open(raw_path, O_WRONLY);
90
return 0;
28
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
91
}
29
close(fd);
92
30
93
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
31
fd = mkstemp(qcow2_path);
94
32
- g_assert(fd);
95
if (s->fp_excp_el) {
33
+ g_assert(fd >= 0);
96
gen_exception_insn(s, 4, EXCP_UDEF,
34
close(fd);
97
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
35
98
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
36
qemu_img_path = getenv("QTEST_QEMU_IMG");
99
return 0;
100
}
101
if (!s->vfp_enabled) {
102
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
103
104
if (s->fp_excp_el) {
105
gen_exception_insn(s, 4, EXCP_UDEF,
106
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
107
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
108
return 0;
109
}
110
if (!s->vfp_enabled) {
111
--
37
--
112
2.19.1
38
2.20.1
113
39
114
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Coverity points out that we calculate a 64-bit value using 32-bit
2
arithmetic; add the cast to force the multiply to be done as 64-bits.
3
(The overflow will never happen with the current test data.)
2
4
3
The EL3 version of this register does not include an ASID,
5
Fixes: Coverity CID 1432320
4
and so the tlb_flush performed by vmsa_ttbr_write is not needed.
5
6
Reviewed-by: Aaron Lindsay <aaron@os.amperecomputing.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
9
Message-id: 20210525134458.6675-5-peter.maydell@linaro.org
11
---
10
---
12
target/arm/helper.c | 2 +-
11
tests/qtest/pflash-cfi02-test.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/tests/qtest/pflash-cfi02-test.c b/tests/qtest/pflash-cfi02-test.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/tests/qtest/pflash-cfi02-test.c
18
+++ b/target/arm/helper.c
17
+++ b/tests/qtest/pflash-cfi02-test.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
18
@@ -XXX,XX +XXX,XX @@ static void test_geometry(const void *opaque)
20
.fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
19
21
{ .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
20
for (int region = 0; region < nb_erase_regions; ++region) {
22
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
21
for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) {
23
- .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
22
- uint64_t byte_addr = i * c->sector_len[region];
24
+ .access = PL3_RW, .resetvalue = 0,
23
+ uint64_t byte_addr = (uint64_t)i * c->sector_len[region];
25
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
24
g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
26
{ .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
25
}
27
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
26
}
28
--
27
--
29
2.19.1
28
2.20.1
30
29
31
30
diff view generated by jsdifflib
1
The A/I/F bits in ISR_EL1 should track the virtual interrupt
1
Coverity points out that in tpm_test_swtpm_migration_test() we
2
status, not the physical interrupt status, if the associated
2
assume that src_tpm_addr and dst_tpm_addr are non-NULL (we
3
HCR_EL2.AMO/IMO/FMO bit is set. Implement this, rather than
3
pass them to tpm_util_migration_start_qemu() which will
4
always showing the physical interrupt status.
4
unconditionally dereference them) but then later explicitly
5
check them for NULL. Remove the pointless checks.
5
6
6
We don't currently implement anything to do with external
7
Fixes: Coverity CID 1432367, 1432359
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
8
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20181012144235.19646-6-peter.maydell@linaro.org
11
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
12
Message-id: 20210525134458.6675-6-peter.maydell@linaro.org
16
---
13
---
17
target/arm/helper.c | 22 ++++++++++++++++++----
14
tests/qtest/tpm-tests.c | 12 ++++--------
18
1 file changed, 18 insertions(+), 4 deletions(-)
15
1 file changed, 4 insertions(+), 8 deletions(-)
19
16
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
19
--- a/tests/qtest/tpm-tests.c
23
+++ b/target/arm/helper.c
20
+++ b/tests/qtest/tpm-tests.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
21
@@ -XXX,XX +XXX,XX @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
25
CPUState *cs = ENV_GET_CPU(env);
22
qtest_quit(src_qemu);
26
uint64_t ret = 0;
23
27
24
tpm_util_swtpm_kill(dst_tpm_pid);
28
- if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
25
- if (dst_tpm_addr) {
29
- ret |= CPSR_I;
26
- g_unlink(dst_tpm_addr->u.q_unix.path);
30
+ if (arm_hcr_el2_imo(env)) {
27
- qapi_free_SocketAddress(dst_tpm_addr);
31
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
28
- }
32
+ ret |= CPSR_I;
29
+ g_unlink(dst_tpm_addr->u.q_unix.path);
33
+ }
30
+ qapi_free_SocketAddress(dst_tpm_addr);
34
+ } else {
31
35
+ if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
32
tpm_util_swtpm_kill(src_tpm_pid);
36
+ ret |= CPSR_I;
33
- if (src_tpm_addr) {
37
+ }
34
- g_unlink(src_tpm_addr->u.q_unix.path);
38
}
35
- qapi_free_SocketAddress(src_tpm_addr);
39
- if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
36
- }
40
- ret |= CPSR_F;
37
+ g_unlink(src_tpm_addr->u.q_unix.path);
41
+
38
+ qapi_free_SocketAddress(src_tpm_addr);
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
}
39
}
55
--
40
--
56
2.19.1
41
2.20.1
57
42
58
43
diff view generated by jsdifflib
1
From: Stewart Hildebrand <Stewart.Hildebrand@dornerworks.com>
1
Coverity complains that we don't check for failures from dup()
2
and mkstemp(); add asserts that these syscalls succeeded.
2
3
3
"The Image must be placed text_offset bytes from a 2MB aligned base
4
Fixes: Coverity CID 1432516, 1432574
4
address anywhere in usable system RAM and called there."
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20210525134458.6675-7-peter.maydell@linaro.org
9
---
10
tests/unit/test-vmstate.c | 5 ++++-
11
1 file changed, 4 insertions(+), 1 deletion(-)
5
12
6
For the virt board, we write our startup bootloader at the very
13
diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
7
bottom of RAM, so that bit can't be used for the image. To avoid
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>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/arm/boot.c | 18 ++++++++++++++++++
22
1 file changed, 18 insertions(+)
23
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/boot.c
15
--- a/tests/unit/test-vmstate.c
27
+++ b/hw/arm/boot.c
16
+++ b/tests/unit/test-vmstate.c
28
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static int temp_fd;
29
#include "qemu/config-file.h"
18
/* Duplicate temp_fd and seek to the beginning of the file */
30
#include "qemu/option.h"
19
static QEMUFile *open_test_file(bool write)
31
#include "exec/address-spaces.h"
32
+#include "qemu/units.h"
33
34
/* Kernel boot protocol is specified in the kernel docs
35
* Documentation/arm/Booting and Documentation/arm64/booting.txt
36
@@ -XXX,XX +XXX,XX @@
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
{
20
{
45
@@ -XXX,XX +XXX,XX @@ static void write_bootloader(const char *name, hwaddr addr,
21
- int fd = dup(temp_fd);
46
code[i] = tswap32(insn);
22
+ int fd;
47
}
23
QIOChannel *ioc;
48
24
QEMUFile *f;
49
+ assert((len * sizeof(uint32_t)) < BOOTLOADER_MAX_SIZE);
25
50
+
26
+ fd = dup(temp_fd);
51
rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as);
27
+ g_assert(fd >= 0);
52
28
lseek(fd, 0, SEEK_SET);
53
g_free(code);
29
if (write) {
54
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
30
g_assert_cmpint(ftruncate(fd, 0), ==, 0);
55
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
31
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
56
if (hdrvals[1] != 0) {
32
g_autofree char *temp_file = g_strdup_printf("%s/vmst.test.XXXXXX",
57
kernel_load_offset = le64_to_cpu(hdrvals[0]);
33
g_get_tmp_dir());
58
+
34
temp_fd = mkstemp(temp_file);
59
+ /*
35
+ g_assert(temp_fd >= 0);
60
+ * We write our startup "bootloader" at the very bottom of RAM,
36
61
+ * so that bit can't be used for the image. Luckily the Image
37
module_call_init(MODULE_INIT_QOM);
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
}
72
}
73
38
74
--
39
--
75
2.19.1
40
2.20.1
76
41
77
42
diff view generated by jsdifflib