1
Latest arm queue, half minor code cleanups and half minor
1
The following changes since commit 3214bec13d8d4c40f707d21d8350d04e4123ae97:
2
bug fixes.
3
2
4
-- PMM
3
Merge tag 'migration-20250110-pull-request' of https://gitlab.com/farosas/qemu into staging (2025-01-10 13:39:19 -0500)
5
6
The following changes since commit 5d0e5694470d2952b4f257bc985cac8c89b4fd92:
7
8
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-06-17 11:55:14 +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-20190617
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250113
13
8
14
for you to fetch changes up to 1120827fa182f0e76226df7ffe7a86598d1df54f:
9
for you to fetch changes up to 435d260e7ec5ff9c79e3e62f1d66ec82d2d691ae:
15
10
16
target/arm: Only implement doubles if the FPU supports them (2019-06-17 15:15:06 +0100)
11
docs/system/arm/virt: mention specific migration information (2025-01-13 12:35:35 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* support large kernel images in bootloader (by avoiding
15
* hw/arm_sysctl: fix extracting 31th bit of val
21
putting the initrd over the top of them)
16
* hw/misc: cast rpm to uint64_t
22
* correctly disable FPU/DSP in the CPU for the mps2-an521, musca-a boards
17
* tests/qtest/boot-serial-test: Improve ASM
23
* arm_gicv3: Fix decoding of ID register range
18
* target/arm: Move minor arithmetic helpers out of helper.c
24
* arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
19
* target/arm: change default pauth algorithm to impdef
25
* some code cleanups following on from the VFP decodetree conversion
26
* Only implement doubles if the FPU supports them
27
(so we now correctly model Cortex-M4, -M33 as single precision only)
28
20
29
----------------------------------------------------------------
21
----------------------------------------------------------------
30
Peter Maydell (24):
22
Anastasia Belova (1):
31
hw/arm/boot: Don't assume RAM starts at address zero
23
hw/arm_sysctl: fix extracting 31th bit of val
32
hw/arm/boot: Diagnose layouts that put initrd or DTB off the end of RAM
33
hw/arm/boot: Avoid placing the initrd on top of the kernel
34
hw/arm/boot: Honour image size field in AArch64 Image format kernels
35
target/arm: Allow VFP and Neon to be disabled via a CPU property
36
target/arm: Allow M-profile CPUs to disable the DSP extension via CPU property
37
hw/arm/armv7m: Forward "vfp" and "dsp" properties to CPU
38
hw/arm: Correctly disable FPU/DSP for some ARMSSE-based boards
39
hw/intc/arm_gicv3: Fix decoding of ID register range
40
hw/intc/arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
41
target/arm: Move vfp_expand_imm() to translate.[ch]
42
target/arm: Use vfp_expand_imm() for AArch32 VFP VMOV_imm
43
target/arm: Stop using cpu_F0s for NEON_2RM_VABS_F
44
target/arm: Stop using cpu_F0s for NEON_2RM_VNEG_F
45
target/arm: Stop using cpu_F0s for NEON_2RM_VRINT*
46
target/arm: Stop using cpu_F0s for NEON_2RM_VCVT[ANPM][US]
47
target/arm: Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F
48
target/arm: Stop using cpu_F0s for Neon f32/s32 VCVT
49
target/arm: Stop using cpu_F0s in Neon VCVT fixed-point ops
50
target/arm: stop using deprecated functions in NEON_2RM_VCVT_F16_F32
51
target/arm: Stop using deprecated functions in NEON_2RM_VCVT_F32_F16
52
target/arm: Remove unused cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d
53
target/arm: Fix typos in trans function prototypes
54
target/arm: Only implement doubles if the FPU supports them
55
24
56
include/hw/arm/armsse.h | 7 ++
25
Peter Maydell (2):
57
include/hw/arm/armv7m.h | 4 +
26
target/arm: Move minor arithmetic helpers out of helper.c
58
target/arm/cpu.h | 12 +++
27
tests/tcg/aarch64: force qarma5 for pauth-3 test
59
target/arm/translate-a64.h | 1 -
60
target/arm/translate.h | 7 ++
61
hw/arm/armsse.c | 58 +++++++---
62
hw/arm/armv7m.c | 18 ++++
63
hw/arm/boot.c | 83 ++++++++++----
64
hw/arm/musca.c | 8 ++
65
hw/intc/arm_gicv3_dist.c | 12 ++-
66
hw/intc/arm_gicv3_redist.c | 4 +-
67
target/arm/cpu.c | 179 ++++++++++++++++++++++++++++--
68
target/arm/translate-a64.c | 32 ------
69
target/arm/translate-vfp.inc.c | 173 ++++++++++++++++++++++-------
70
target/arm/translate.c | 240 ++++++++++++++---------------------------
71
target/arm/vfp.decode | 10 +-
72
16 files changed, 572 insertions(+), 276 deletions(-)
73
28
29
Philippe Mathieu-Daudé (4):
30
tests/qtest/boot-serial-test: Improve ASM comments of PL011 tests
31
tests/qtest/boot-serial-test: Reduce for() loop in PL011 tests
32
tests/qtest/boot-serial-test: Reorder pair of instructions in PL011 test
33
tests/qtest/boot-serial-test: Initialize PL011 Control register
34
35
Pierrick Bouvier (3):
36
target/arm: add new property to select pauth-qarma5
37
target/arm: change default pauth algorithm to impdef
38
docs/system/arm/virt: mention specific migration information
39
40
Tigran Sogomonian (1):
41
hw/misc: cast rpm to uint64_t
42
43
docs/system/arm/cpu-features.rst | 7 +-
44
docs/system/arm/virt.rst | 4 +
45
docs/system/introduction.rst | 2 +-
46
target/arm/cpu.h | 4 +
47
hw/core/machine.c | 4 +-
48
hw/misc/arm_sysctl.c | 2 +-
49
hw/misc/npcm7xx_mft.c | 5 +-
50
target/arm/arm-qmp-cmds.c | 2 +-
51
target/arm/cpu.c | 2 +
52
target/arm/cpu64.c | 38 ++-
53
target/arm/helper.c | 285 -----------------------
54
target/arm/tcg/arith_helper.c | 296 ++++++++++++++++++++++++
55
tests/qtest/arm-cpu-features.c | 15 +-
56
tests/qtest/boot-serial-test.c | 23 +-
57
target/arm/{op_addsub.h => tcg/op_addsub.c.inc} | 0
58
target/arm/tcg/meson.build | 1 +
59
tests/tcg/aarch64/Makefile.softmmu-target | 3 +
60
17 files changed, 377 insertions(+), 316 deletions(-)
61
create mode 100644 target/arm/tcg/arith_helper.c
62
rename target/arm/{op_addsub.h => tcg/op_addsub.c.inc} (100%)
63
diff view generated by jsdifflib
Deleted patch
1
In the Arm kernel/initrd loading code, in some places we make the
2
incorrect assumption that info->ram_size can be treated as the
3
address of the end of RAM, as for instance when we calculate the
4
available space for the initrd using "info->ram_size - info->initrd_start".
5
This is wrong, because many Arm boards (including "virt") specify
6
a non-zero info->loader_start to indicate that their RAM area
7
starts at a non-zero physical address.
8
1
9
Correct the places which make this incorrect assumption.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Tested-by: Mark Rutland <mark.rutland@arm.com>
14
Message-id: 20190516144733.32399-2-peter.maydell@linaro.org
15
---
16
hw/arm/boot.c | 9 ++++-----
17
1 file changed, 4 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
22
+++ b/hw/arm/boot.c
23
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
24
int elf_machine;
25
hwaddr entry;
26
static const ARMInsnFixup *primary_loader;
27
+ uint64_t ram_end = info->loader_start + info->ram_size;
28
29
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
30
primary_loader = bootloader_aarch64;
31
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
32
/* 32-bit ARM */
33
entry = info->loader_start + KERNEL_LOAD_ADDR;
34
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
35
- info->ram_size - KERNEL_LOAD_ADDR,
36
- as);
37
+ ram_end - KERNEL_LOAD_ADDR, as);
38
is_linux = 1;
39
}
40
if (kernel_size < 0) {
41
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
42
if (info->initrd_filename) {
43
initrd_size = load_ramdisk_as(info->initrd_filename,
44
info->initrd_start,
45
- info->ram_size - info->initrd_start,
46
- as);
47
+ ram_end - info->initrd_start, as);
48
if (initrd_size < 0) {
49
initrd_size = load_image_targphys_as(info->initrd_filename,
50
info->initrd_start,
51
- info->ram_size -
52
+ ram_end -
53
info->initrd_start,
54
as);
55
}
56
--
57
2.20.1
58
59
diff view generated by jsdifflib
Deleted patch
1
We calculate the locations in memory where we want to put the
2
initrd and the DTB based on the size of the kernel, since they
3
come after it. Add some explicit checks that these aren't off the
4
end of RAM entirely.
5
1
6
(At the moment the way we calculate the initrd_start means that
7
it can't ever be off the end of RAM, but that will change with
8
the next commit.)
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Tested-by: Mark Rutland <mark.rutland@arm.com>
13
Message-id: 20190516144733.32399-3-peter.maydell@linaro.org
14
---
15
hw/arm/boot.c | 23 +++++++++++++++++++++++
16
1 file changed, 23 insertions(+)
17
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/boot.c
21
+++ b/hw/arm/boot.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
23
error_report("could not load kernel '%s'", info->kernel_filename);
24
exit(1);
25
}
26
+
27
+ if (kernel_size > info->ram_size) {
28
+ error_report("kernel '%s' is too large to fit in RAM "
29
+ "(kernel size %d, RAM size %" PRId64 ")",
30
+ info->kernel_filename, kernel_size, info->ram_size);
31
+ exit(1);
32
+ }
33
+
34
info->entry = entry;
35
if (is_linux) {
36
uint32_t fixupcontext[FIXUP_MAX];
37
38
if (info->initrd_filename) {
39
+
40
+ if (info->initrd_start >= ram_end) {
41
+ error_report("not enough space after kernel to load initrd");
42
+ exit(1);
43
+ }
44
+
45
initrd_size = load_ramdisk_as(info->initrd_filename,
46
info->initrd_start,
47
ram_end - info->initrd_start, as);
48
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
49
info->initrd_filename);
50
exit(1);
51
}
52
+ if (info->initrd_start + initrd_size > info->ram_size) {
53
+ error_report("could not load initrd '%s': "
54
+ "too big to fit into RAM after the kernel",
55
+ info->initrd_filename);
56
+ }
57
} else {
58
initrd_size = 0;
59
}
60
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
61
/* Place the DTB after the initrd in memory with alignment. */
62
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
63
align);
64
+ if (info->dtb_start >= ram_end) {
65
+ error_report("Not enough space for DTB after kernel/initrd");
66
+ exit(1);
67
+ }
68
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
69
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
70
} else {
71
--
72
2.20.1
73
74
diff view generated by jsdifflib
Deleted patch
1
We currently put the initrd at the smaller of:
2
* 128MB into RAM
3
* halfway into the RAM
4
(with the dtb following it).
5
1
6
However for large kernels this might mean that the kernel
7
overlaps the initrd. For some kinds of kernel (self-decompressing
8
32-bit kernels, and ELF images with a BSS section at the end)
9
we don't know the exact size, but even there we have a
10
minimum size. Put the initrd at least further into RAM than
11
that. For image formats that can give us an exact kernel size, this
12
will mean that we definitely avoid overlaying kernel and initrd.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Tested-by: Mark Rutland <mark.rutland@arm.com>
17
Message-id: 20190516144733.32399-4-peter.maydell@linaro.org
18
---
19
hw/arm/boot.c | 34 ++++++++++++++++++++--------------
20
1 file changed, 20 insertions(+), 14 deletions(-)
21
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
25
+++ b/hw/arm/boot.c
26
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
27
if (info->nb_cpus == 0)
28
info->nb_cpus = 1;
29
30
- /*
31
- * We want to put the initrd far enough into RAM that when the
32
- * kernel is uncompressed it will not clobber the initrd. However
33
- * on boards without much RAM we must ensure that we still leave
34
- * enough room for a decent sized initrd, and on boards with large
35
- * amounts of RAM we must avoid the initrd being so far up in RAM
36
- * that it is outside lowmem and inaccessible to the kernel.
37
- * So for boards with less than 256MB of RAM we put the initrd
38
- * halfway into RAM, and for boards with 256MB of RAM or more we put
39
- * the initrd at 128MB.
40
- */
41
- info->initrd_start = info->loader_start +
42
- MIN(info->ram_size / 2, 128 * 1024 * 1024);
43
-
44
/* Assume that raw images are linux kernels, and ELF images are not. */
45
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
46
&elf_high_addr, elf_machine, as);
47
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
48
}
49
50
info->entry = entry;
51
+
52
+ /*
53
+ * We want to put the initrd far enough into RAM that when the
54
+ * kernel is uncompressed it will not clobber the initrd. However
55
+ * on boards without much RAM we must ensure that we still leave
56
+ * enough room for a decent sized initrd, and on boards with large
57
+ * amounts of RAM we must avoid the initrd being so far up in RAM
58
+ * that it is outside lowmem and inaccessible to the kernel.
59
+ * So for boards with less than 256MB of RAM we put the initrd
60
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
61
+ * the initrd at 128MB.
62
+ * We also refuse to put the initrd somewhere that will definitely
63
+ * overlay the kernel we just loaded, though for kernel formats which
64
+ * don't tell us their exact size (eg self-decompressing 32-bit kernels)
65
+ * we might still make a bad choice here.
66
+ */
67
+ info->initrd_start = info->loader_start +
68
+ MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
69
+ info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
70
+
71
if (is_linux) {
72
uint32_t fixupcontext[FIXUP_MAX];
73
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
Since Linux v3.17, the kernel's Image header includes a field image_size,
2
which gives the total size of the kernel including unpopulated data
3
sections such as the BSS). If this is present, then return it from
4
load_aarch64_image() as the true size of the kernel rather than
5
just using the size of the Image file itself. This allows the code
6
which calculates where to put the initrd to avoid putting it in
7
the kernel's BSS area.
8
1
9
This means that we should be able to reliably load kernel images
10
which are larger than 128MB without accidentally putting the
11
initrd or dtb in locations that clash with the kernel itself.
12
13
Fixes: https://bugs.launchpad.net/qemu/+bug/1823998
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Tested-by: Mark Rutland <mark.rutland@arm.com>
18
Message-id: 20190516144733.32399-5-peter.maydell@linaro.org
19
---
20
hw/arm/boot.c | 17 +++++++++++++++--
21
1 file changed, 15 insertions(+), 2 deletions(-)
22
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
26
+++ b/hw/arm/boot.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
28
hwaddr *entry, AddressSpace *as)
29
{
30
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
31
+ uint64_t kernel_size = 0;
32
uint8_t *buffer;
33
int size;
34
35
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
36
* is only valid if the image_size is non-zero.
37
*/
38
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
39
- if (hdrvals[1] != 0) {
40
+
41
+ kernel_size = le64_to_cpu(hdrvals[1]);
42
+
43
+ if (kernel_size != 0) {
44
kernel_load_offset = le64_to_cpu(hdrvals[0]);
45
46
/*
47
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
48
}
49
}
50
51
+ /*
52
+ * Kernels before v3.17 don't populate the image_size field, and
53
+ * raw images have no header. For those our best guess at the size
54
+ * is the size of the Image file itself.
55
+ */
56
+ if (kernel_size == 0) {
57
+ kernel_size = size;
58
+ }
59
+
60
*entry = mem_base + kernel_load_offset;
61
rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
62
63
g_free(buffer);
64
65
- return size;
66
+ return kernel_size;
67
}
68
69
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
1
The architecture permits FPUs which have only single-precision
1
From: Anastasia Belova <abelova@astralinux.ru>
2
support, not double-precision; Cortex-M4 and Cortex-M33 are
3
both like that. Add the necessary checks on the MVFR0 FPDP
4
field so that we UNDEF any double-precision instructions on
5
CPUs like this.
6
2
7
Note that even if FPDP==0 the insns like VMOV-to/from-gpreg,
3
1 << 31 is casted to uint64_t while bitwise and with val.
8
VLDM/VSTM, VLDR/VSTR which take double precision registers
4
So this value may become 0xffffffff80000000 but only
9
still exist.
5
31th "start" bit is required.
10
6
7
This is not possible in practice because the MemoryRegionOps
8
uses the default max access size of 4 bytes and so none
9
of the upper bytes of val will be set, but the bitfield
10
extract API is clearer anyway.
11
12
Use the bitfield extract() API instead.
13
14
Found by Linux Verification Center (linuxtesting.org) with SVACE.
15
16
Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
17
Message-id: 20241220125429.7552-1-abelova@astralinux.ru
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: add clarification to commit message]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190614104457.24703-3-peter.maydell@linaro.org
14
---
21
---
15
target/arm/cpu.h | 6 +++
22
hw/misc/arm_sysctl.c | 2 +-
16
target/arm/translate-vfp.inc.c | 84 ++++++++++++++++++++++++++++++++++
23
1 file changed, 1 insertion(+), 1 deletion(-)
17
2 files changed, 90 insertions(+)
18
24
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
20
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
27
--- a/hw/misc/arm_sysctl.c
22
+++ b/target/arm/cpu.h
28
+++ b/hw/misc/arm_sysctl.c
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
29
@@ -XXX,XX +XXX,XX @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
24
return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
30
* as zero.
25
}
31
*/
26
32
s->sys_cfgctrl = val & ~((3 << 18) | (1 << 31));
27
+static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
33
- if (val & (1 << 31)) {
28
+{
34
+ if (extract64(val, 31, 1)) {
29
+ /* Return true if CPU supports double precision floating point */
35
/* Start bit set -- actually do something */
30
+ return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
36
unsigned int dcc = extract32(s->sys_cfgctrl, 26, 4);
31
+}
37
unsigned int function = extract32(s->sys_cfgctrl, 20, 6);
32
+
33
/*
34
* We always set the FP and SIMD FP16 fields to indicate identical
35
* levels of support (assuming SIMD is implemented at all), so
36
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-vfp.inc.c
39
+++ b/target/arm/translate-vfp.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
41
((a->vm | a->vn | a->vd) & 0x10)) {
42
return false;
43
}
44
+
45
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
46
+ return false;
47
+ }
48
+
49
rd = a->vd;
50
rn = a->vn;
51
rm = a->vm;
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
53
((a->vm | a->vn | a->vd) & 0x10)) {
54
return false;
55
}
56
+
57
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
58
+ return false;
59
+ }
60
+
61
rd = a->vd;
62
rn = a->vn;
63
rm = a->vm;
64
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
65
((a->vm | a->vd) & 0x10)) {
66
return false;
67
}
68
+
69
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
70
+ return false;
71
+ }
72
+
73
rd = a->vd;
74
rm = a->vm;
75
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
77
if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
78
return false;
79
}
80
+
81
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
82
+ return false;
83
+ }
84
+
85
rd = a->vd;
86
rm = a->vm;
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
return false;
90
}
91
92
+ if (!dc_isar_feature(aa32_fpdp, s)) {
93
+ return false;
94
+ }
95
+
96
if (!dc_isar_feature(aa32_fpshvec, s) &&
97
(veclen != 0 || s->vec_stride != 0)) {
98
return false;
99
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
100
return false;
101
}
102
103
+ if (!dc_isar_feature(aa32_fpdp, s)) {
104
+ return false;
105
+ }
106
+
107
if (!dc_isar_feature(aa32_fpshvec, s) &&
108
(veclen != 0 || s->vec_stride != 0)) {
109
return false;
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
111
return false;
112
}
113
114
+ if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ return false;
116
+ }
117
+
118
if (!vfp_access_check(s)) {
119
return true;
120
}
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
122
return false;
123
}
124
125
+ if (!dc_isar_feature(aa32_fpdp, s)) {
126
+ return false;
127
+ }
128
+
129
if (!dc_isar_feature(aa32_fpshvec, s) &&
130
(veclen != 0 || s->vec_stride != 0)) {
131
return false;
132
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
133
return false;
134
}
135
136
+ if (!dc_isar_feature(aa32_fpdp, s)) {
137
+ return false;
138
+ }
139
+
140
if (!vfp_access_check(s)) {
141
return true;
142
}
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
144
return false;
145
}
146
147
+ if (!dc_isar_feature(aa32_fpdp, s)) {
148
+ return false;
149
+ }
150
+
151
if (!vfp_access_check(s)) {
152
return true;
153
}
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
155
return false;
156
}
157
158
+ if (!dc_isar_feature(aa32_fpdp, s)) {
159
+ return false;
160
+ }
161
+
162
if (!vfp_access_check(s)) {
163
return true;
164
}
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
166
return false;
167
}
168
169
+ if (!dc_isar_feature(aa32_fpdp, s)) {
170
+ return false;
171
+ }
172
+
173
if (!vfp_access_check(s)) {
174
return true;
175
}
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
177
return false;
178
}
179
180
+ if (!dc_isar_feature(aa32_fpdp, s)) {
181
+ return false;
182
+ }
183
+
184
if (!vfp_access_check(s)) {
185
return true;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
188
return false;
189
}
190
191
+ if (!dc_isar_feature(aa32_fpdp, s)) {
192
+ return false;
193
+ }
194
+
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
199
return false;
200
}
201
202
+ if (!dc_isar_feature(aa32_fpdp, s)) {
203
+ return false;
204
+ }
205
+
206
if (!vfp_access_check(s)) {
207
return true;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
210
return false;
211
}
212
213
+ if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ return false;
215
+ }
216
+
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
221
return false;
222
}
223
224
+ if (!dc_isar_feature(aa32_fpdp, s)) {
225
+ return false;
226
+ }
227
+
228
if (!vfp_access_check(s)) {
229
return true;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
232
return false;
233
}
234
235
+ if (!dc_isar_feature(aa32_fpdp, s)) {
236
+ return false;
237
+ }
238
+
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
243
return false;
244
}
245
246
+ if (!dc_isar_feature(aa32_fpdp, s)) {
247
+ return false;
248
+ }
249
+
250
if (!vfp_access_check(s)) {
251
return true;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
254
return false;
255
}
256
257
+ if (!dc_isar_feature(aa32_fpdp, s)) {
258
+ return false;
259
+ }
260
+
261
if (!vfp_access_check(s)) {
262
return true;
263
}
264
--
38
--
265
2.20.1
39
2.34.1
266
267
diff view generated by jsdifflib
1
Remove the now unused TCG globals cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d.
1
From: Tigran Sogomonian <tsogomonian@astralinux.ru>
2
2
3
cpu_M0 is still used by the iwmmxt code, and cpu_V0 and
3
The value of an arithmetic expression
4
cpu_V1 are used by both iwmmxt and Neon.
4
'rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION' is a subject
5
to overflow because its operands are not cast to
6
a larger data type before performing arithmetic. Thus, need
7
to cast rpm to uint64_t.
5
8
9
Found by Linux Verification Center (linuxtesting.org) with SVACE.
10
11
Signed-off-by: Tigran Sogomonian <tsogomonian@astralinux.ru>
12
Reviewed-by: Patrick Leis <venture@google.com>
13
Reviewed-by: Hao Wu <wuhaotsh@google.com>
14
Message-id: 20241226130311.1349-1-tsogomonian@astralinux.ru
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-13-peter.maydell@linaro.org
10
---
16
---
11
target/arm/translate.c | 12 ++----------
17
hw/misc/npcm7xx_mft.c | 5 +++--
12
1 file changed, 2 insertions(+), 10 deletions(-)
18
1 file changed, 3 insertions(+), 2 deletions(-)
13
19
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
22
--- a/hw/misc/npcm7xx_mft.c
17
+++ b/target/arm/translate.c
23
+++ b/hw/misc/npcm7xx_mft.c
18
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
24
@@ -XXX,XX +XXX,XX @@ static NPCM7xxMFTCaptureState npcm7xx_mft_compute_cnt(
19
TCGv_i64 cpu_exclusive_addr;
25
* RPM = revolution/min. The time for one revlution (in ns) is
20
TCGv_i64 cpu_exclusive_val;
26
* MINUTE_TO_NANOSECOND / RPM.
21
27
*/
22
-/* FIXME: These should be removed. */
28
- count = clock_ns_to_ticks(clock, (60 * NANOSECONDS_PER_SECOND) /
23
-static TCGv_i32 cpu_F0s, cpu_F1s;
29
- (rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
24
-static TCGv_i64 cpu_F0d, cpu_F1d;
30
+ count = clock_ns_to_ticks(clock,
25
-
31
+ (uint64_t)(60 * NANOSECONDS_PER_SECOND) /
26
#include "exec/gen-icount.h"
32
+ ((uint64_t)rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
27
28
static const char * const regnames[] =
29
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
30
dc->base.max_insns = MIN(dc->base.max_insns, bound);
31
}
33
}
32
34
33
- cpu_F0s = tcg_temp_new_i32();
35
if (count > NPCM7XX_MFT_MAX_CNT) {
34
- cpu_F1s = tcg_temp_new_i32();
35
- cpu_F0d = tcg_temp_new_i64();
36
- cpu_F1d = tcg_temp_new_i64();
37
- cpu_V0 = cpu_F0d;
38
- cpu_V1 = cpu_F1d;
39
+ cpu_V0 = tcg_temp_new_i64();
40
+ cpu_V1 = tcg_temp_new_i64();
41
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
42
cpu_M0 = tcg_temp_new_i64();
43
}
44
--
36
--
45
2.20.1
37
2.34.1
46
47
diff view generated by jsdifflib
1
In several places cut and paste errors meant we were using the wrong
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
type for the 'arg' struct in trans_ functions called by the
3
decodetree decoder, because we were using the _sp version of the
4
struct in the _dp function. These were harmless, because the two
5
structs were identical and so decodetree made them typedefs of the
6
same underlying structure (and we'd have had a compile error if they
7
were not harmless), but we should clean them up anyway.
8
2
3
Re-indent ASM comments adding the 'loop:' label.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Fabiano Rosas <farosas@suse.de>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20190614104457.24703-2-peter.maydell@linaro.org
12
---
9
---
13
target/arm/translate-vfp.inc.c | 28 ++++++++++++++--------------
10
tests/qtest/boot-serial-test.c | 18 +++++++++---------
14
1 file changed, 14 insertions(+), 14 deletions(-)
11
1 file changed, 9 insertions(+), 9 deletions(-)
15
12
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
13
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.inc.c
15
--- a/tests/qtest/boot-serial-test.c
19
+++ b/target/arm/translate-vfp.inc.c
16
+++ b/tests/qtest/boot-serial-test.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
17
@@ -XXX,XX +XXX,XX @@ static const uint8_t kernel_plml605[] = {
21
return true;
18
};
22
}
19
23
20
static const uint8_t bios_raspi2[] = {
24
-static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_sp *a)
21
- 0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */
25
+static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
22
- 0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */
26
{
23
- 0x00, 0x20, 0xc3, 0xe5, /* strb r2,[r3] */
27
TCGv_i32 tmp;
24
- 0xfb, 0xff, 0xff, 0xea, /* b loop */
28
25
- 0x00, 0x10, 0x20, 0x3f, /* 0x3f201000 = UART0 base addr */
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
26
+ 0x08, 0x30, 0x9f, 0xe5, /* loop: ldr r3, [pc, #8] Get &UART0 */
30
return true;
27
+ 0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
31
}
28
+ 0x00, 0x20, 0xc3, 0xe5, /* strb r2, [r3] *TXDAT = 'T' */
32
29
+ 0xfb, 0xff, 0xff, 0xea, /* b -12 (loop) */
33
-static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a)
30
+ 0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
34
+static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
31
};
35
{
32
36
uint32_t offset;
33
static const uint8_t kernel_aarch64[] = {
37
TCGv_i32 addr;
34
- 0x81, 0x0a, 0x80, 0x52, /* mov w1, #0x54 */
38
@@ -XXX,XX +XXX,XX @@ static void gen_VMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
35
- 0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 */
39
tcg_temp_free_i64(tmp);
36
- 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] */
40
}
37
- 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
41
38
+ 0x81, 0x0a, 0x80, 0x52, /* loop: mov w1, #'T' */
42
-static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_sp *a)
39
+ 0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
43
+static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_dp *a)
40
+ 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] *TXDAT = 'T' */
44
{
41
+ 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
45
return do_vfp_3op_dp(s, gen_VMLA_dp, a->vd, a->vn, a->vm, true);
42
};
46
}
43
47
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
44
static const uint8_t kernel_nrf51[] = {
48
tcg_temp_free_i64(tmp);
49
}
50
51
-static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_sp *a)
52
+static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_dp *a)
53
{
54
return do_vfp_3op_dp(s, gen_VMLS_dp, a->vd, a->vn, a->vm, true);
55
}
56
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
57
tcg_temp_free_i64(tmp);
58
}
59
60
-static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_sp *a)
61
+static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_dp *a)
62
{
63
return do_vfp_3op_dp(s, gen_VNMLS_dp, a->vd, a->vn, a->vm, true);
64
}
65
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
66
tcg_temp_free_i64(tmp);
67
}
68
69
-static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_sp *a)
70
+static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_dp *a)
71
{
72
return do_vfp_3op_dp(s, gen_VNMLA_dp, a->vd, a->vn, a->vm, true);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_sp(DisasContext *s, arg_VMUL_sp *a)
75
return do_vfp_3op_sp(s, gen_helper_vfp_muls, a->vd, a->vn, a->vm, false);
76
}
77
78
-static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_sp *a)
79
+static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_dp *a)
80
{
81
return do_vfp_3op_dp(s, gen_helper_vfp_muld, a->vd, a->vn, a->vm, false);
82
}
83
@@ -XXX,XX +XXX,XX @@ static void gen_VNMUL_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
84
gen_helper_vfp_negd(vd, vd);
85
}
86
87
-static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_sp *a)
88
+static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
89
{
90
return do_vfp_3op_dp(s, gen_VNMUL_dp, a->vd, a->vn, a->vm, false);
91
}
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VADD_sp(DisasContext *s, arg_VADD_sp *a)
93
return do_vfp_3op_sp(s, gen_helper_vfp_adds, a->vd, a->vn, a->vm, false);
94
}
95
96
-static bool trans_VADD_dp(DisasContext *s, arg_VADD_sp *a)
97
+static bool trans_VADD_dp(DisasContext *s, arg_VADD_dp *a)
98
{
99
return do_vfp_3op_dp(s, gen_helper_vfp_addd, a->vd, a->vn, a->vm, false);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUB_sp(DisasContext *s, arg_VSUB_sp *a)
102
return do_vfp_3op_sp(s, gen_helper_vfp_subs, a->vd, a->vn, a->vm, false);
103
}
104
105
-static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_sp *a)
106
+static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_dp *a)
107
{
108
return do_vfp_3op_dp(s, gen_helper_vfp_subd, a->vd, a->vn, a->vm, false);
109
}
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_sp(DisasContext *s, arg_VDIV_sp *a)
111
return do_vfp_3op_sp(s, gen_helper_vfp_divs, a->vd, a->vn, a->vm, false);
112
}
113
114
-static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_sp *a)
115
+static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
116
{
117
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
118
}
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
120
return true;
121
}
122
123
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_sp *a)
124
+static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
125
{
126
/*
127
* VFNMA : fd = muladd(-fd, fn, fm)
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
129
return true;
130
}
131
132
-static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_sp *a)
133
+static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
134
{
135
TCGv_ptr fpst;
136
TCGv_i64 tmp;
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
138
return true;
139
}
140
141
-static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_sp *a)
142
+static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
143
{
144
TCGv_ptr fpst;
145
TCGv_i64 tmp;
146
--
45
--
147
2.20.1
46
2.34.1
148
47
149
48
diff view generated by jsdifflib
1
The SSE-200 hardware has configurable integration settings which
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
determine whether its two CPUs have the FPU and DSP:
3
* CPU0_FPU (default 0)
4
* CPU0_DSP (default 0)
5
* CPU1_FPU (default 1)
6
* CPU1_DSP (default 1)
7
2
8
Similarly, the IoTKit has settings for its single CPU:
3
Since registers are not modified, we don't need
9
* CPU0_FPU (default 1)
4
to refill their values. Directly jump to the previous
10
* CPU0_DSP (default 1)
5
store instruction to keep filling the TXDAT register.
11
6
12
Of our four boards that use either the IoTKit or the SSE-200:
7
The equivalent C code remains:
13
* mps2-an505, mps2-an521 and musca-a use the default settings
14
* musca-b1 enables FPU and DSP on both CPUs
15
8
16
Currently QEMU models all these boards using CPUs with
9
while (true) {
17
both FPU and DSP enabled. This means that we are incorrect
10
*UART_DATA = 'T';
18
for mps2-an521 and musca-a, which should not have FPU or DSP
11
}
19
on CPU0.
20
12
21
Create QOM properties on the ARMSSE devices corresponding to the
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
default h/w integration settings, and make the Musca-B1 board
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
enable FPU and DSP on both CPUs. This fixes the mps2-an521
15
Reviewed-by: Fabiano Rosas <farosas@suse.de>
24
and musca-a behaviour, and leaves the musca-b1 and mps2-an505
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
behaviour unchanged.
17
---
18
tests/qtest/boot-serial-test.c | 12 ++++++------
19
1 file changed, 6 insertions(+), 6 deletions(-)
26
20
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
29
Message-id: 20190517174046.11146-5-peter.maydell@linaro.org
30
---
31
include/hw/arm/armsse.h | 7 +++++
32
hw/arm/armsse.c | 58 ++++++++++++++++++++++++++++++++---------
33
hw/arm/musca.c | 8 ++++++
34
3 files changed, 61 insertions(+), 12 deletions(-)
35
36
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
37
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/arm/armsse.h
23
--- a/tests/qtest/boot-serial-test.c
39
+++ b/include/hw/arm/armsse.h
24
+++ b/tests/qtest/boot-serial-test.c
40
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static const uint8_t kernel_plml605[] = {
41
* address of each SRAM bank (and thus the total amount of internal SRAM)
42
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
43
* (where it expects to load the PC and SP from the vector table on reset)
44
+ * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
45
+ * set whether the CPUs have the FPU and DSP features present. The default
46
+ * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
47
+ * SSE-200 both are present; CPU0 in an SSE-200 has neither.
48
+ * Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
49
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
50
* which are wired to its NVIC lines 32 .. n+32
51
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
52
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
53
uint32_t mainclk_frq;
54
uint32_t sram_addr_width;
55
uint32_t init_svtor;
56
+ bool cpu_fpu[SSE_MAX_CPUS];
57
+ bool cpu_dsp[SSE_MAX_CPUS];
58
} ARMSSE;
59
60
typedef struct ARMSSEInfo ARMSSEInfo;
61
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/armsse.c
64
+++ b/hw/arm/armsse.c
65
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
66
bool has_cachectrl;
67
bool has_cpusecctrl;
68
bool has_cpuid;
69
+ Property *props;
70
+};
71
+
72
+static Property iotkit_properties[] = {
73
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
74
+ MemoryRegion *),
75
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
76
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
77
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
78
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
79
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
80
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
81
+ DEFINE_PROP_END_OF_LIST()
82
+};
83
+
84
+static Property armsse_properties[] = {
85
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
86
+ MemoryRegion *),
87
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
88
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
89
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
90
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
91
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
92
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
93
+ DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94
+ DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95
+ DEFINE_PROP_END_OF_LIST()
96
};
26
};
97
27
98
static const ARMSSEInfo armsse_variants[] = {
28
static const uint8_t bios_raspi2[] = {
99
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
29
- 0x08, 0x30, 0x9f, 0xe5, /* loop: ldr r3, [pc, #8] Get &UART0 */
100
.has_cachectrl = false,
30
+ 0x08, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #8] Get &UART0 */
101
.has_cpusecctrl = false,
31
0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
102
.has_cpuid = false,
32
- 0x00, 0x20, 0xc3, 0xe5, /* strb r2, [r3] *TXDAT = 'T' */
103
+ .props = iotkit_properties,
33
- 0xfb, 0xff, 0xff, 0xea, /* b -12 (loop) */
104
},
34
+ 0x00, 0x20, 0xc3, 0xe5, /* loop: strb r2, [r3] *TXDAT = 'T' */
105
{
35
+ 0xff, 0xff, 0xff, 0xea, /* b -4 (loop) */
106
.name = TYPE_SSE200,
36
0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
107
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
108
.has_cachectrl = true,
109
.has_cpusecctrl = true,
110
.has_cpuid = true,
111
+ .props = armsse_properties,
112
},
113
};
37
};
114
38
115
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
39
static const uint8_t kernel_aarch64[] = {
116
return;
40
- 0x81, 0x0a, 0x80, 0x52, /* loop: mov w1, #'T' */
117
}
41
+ 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
118
}
42
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
119
+ if (!s->cpu_fpu[i]) {
43
- 0x41, 0x00, 0x00, 0x39, /* strb w1, [x2] *TXDAT = 'T' */
120
+ object_property_set_bool(cpuobj, false, "vfp", &err);
44
- 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */
121
+ if (err) {
45
+ 0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
122
+ error_propagate(errp, err);
46
+ 0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
123
+ return;
124
+ }
125
+ }
126
+ if (!s->cpu_dsp[i]) {
127
+ object_property_set_bool(cpuobj, false, "dsp", &err);
128
+ if (err) {
129
+ error_propagate(errp, err);
130
+ return;
131
+ }
132
+ }
133
134
if (i > 0) {
135
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
136
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription armsse_vmstate = {
137
}
138
};
47
};
139
48
140
-static Property armsse_properties[] = {
49
static const uint8_t kernel_nrf51[] = {
141
- DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
142
- MemoryRegion *),
143
- DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
144
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
145
- DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
146
- DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
147
- DEFINE_PROP_END_OF_LIST()
148
-};
149
-
150
static void armsse_reset(DeviceState *dev)
151
{
152
ARMSSE *s = ARMSSE(dev);
153
@@ -XXX,XX +XXX,XX @@ static void armsse_class_init(ObjectClass *klass, void *data)
154
DeviceClass *dc = DEVICE_CLASS(klass);
155
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
156
ARMSSEClass *asc = ARMSSE_CLASS(klass);
157
+ const ARMSSEInfo *info = data;
158
159
dc->realize = armsse_realize;
160
dc->vmsd = &armsse_vmstate;
161
- dc->props = armsse_properties;
162
+ dc->props = info->props;
163
dc->reset = armsse_reset;
164
iic->check = armsse_idau_check;
165
- asc->info = data;
166
+ asc->info = info;
167
}
168
169
static const TypeInfo armsse_info = {
170
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/arm/musca.c
173
+++ b/hw/arm/musca.c
174
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
175
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
176
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
177
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
178
+ /*
179
+ * Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
180
+ * CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
181
+ */
182
+ if (mmc->type == MUSCA_B1) {
183
+ qdev_prop_set_bit(ssedev, "CPU0_FPU", true);
184
+ qdev_prop_set_bit(ssedev, "CPU0_DSP", true);
185
+ }
186
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
187
&error_fatal);
188
189
--
50
--
190
2.20.1
51
2.34.1
191
52
192
53
diff view generated by jsdifflib
1
Remove some old constructns from NEON_2RM_VCVT_F16_F32 code:
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
* don't use CPU_F0s
3
* don't use tcg_gen_st_f32
4
2
3
In the next commit we are going to use a different value
4
for the $w1 register, maintaining the same $x2 value. In
5
order to keep the next commit trivial to review, set $x2
6
before $w1.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Fabiano Rosas <farosas@suse.de>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-12-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.c | 26 +++++++++++---------------
13
tests/qtest/boot-serial-test.c | 2 +-
11
1 file changed, 11 insertions(+), 15 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
12
15
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
18
--- a/tests/qtest/boot-serial-test.c
16
+++ b/target/arm/translate.c
19
+++ b/tests/qtest/boot-serial-test.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
20
@@ -XXX,XX +XXX,XX @@ static const uint8_t bios_raspi2[] = {
18
return ret;
21
};
19
}
22
20
23
static const uint8_t kernel_aarch64[] = {
21
-#define tcg_gen_st_f32 tcg_gen_st_i32
24
- 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
22
-
25
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
23
#define ARM_CP_RW_BIT (1 << 20)
26
+ 0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
24
27
0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
25
/* Include the VFP decoder */
28
0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
29
};
27
tmp = neon_load_reg(rm, 0);
28
tmp2 = neon_load_reg(rm, 1);
29
tcg_gen_ext16u_i32(tmp3, tmp);
30
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
31
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
32
- tcg_gen_shri_i32(tmp3, tmp, 16);
33
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
34
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
35
- tcg_temp_free_i32(tmp);
36
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
37
+ neon_store_reg(rd, 0, tmp3);
38
+ tcg_gen_shri_i32(tmp, tmp, 16);
39
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
40
+ neon_store_reg(rd, 1, tmp);
41
+ tmp3 = tcg_temp_new_i32();
42
tcg_gen_ext16u_i32(tmp3, tmp2);
43
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
44
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
45
- tcg_gen_shri_i32(tmp3, tmp2, 16);
46
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
47
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
48
- tcg_temp_free_i32(tmp2);
49
- tcg_temp_free_i32(tmp3);
50
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
51
+ neon_store_reg(rd, 2, tmp3);
52
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
53
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
54
+ neon_store_reg(rd, 3, tmp2);
55
tcg_temp_free_i32(ahp);
56
tcg_temp_free_ptr(fpst);
57
break;
58
--
30
--
59
2.20.1
31
2.34.1
60
32
61
33
diff view generated by jsdifflib
1
Create "vfp" and "dsp" properties on the armv7m container object
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
which will be forwarded to its CPU object, so that SoCs can
3
configure whether the CPU has these features.
4
2
3
The tests using the PL011 UART of the virt and raspi machines
4
weren't properly enabling the UART and its transmitter previous
5
to sending characters. Follow the PL011 manual initialization
6
recommendation by setting the proper bits of the control register.
7
8
Update the ASM code prefixing:
9
10
*UART_CTRL = UART_ENABLE | TX_ENABLE;
11
12
to:
13
14
while (true) {
15
*UART_DATA = 'T';
16
}
17
18
Note, since commit 51b61dd4d56 ("hw/char/pl011: Warn when using
19
disabled transmitter") incomplete PL011 initialization can be
20
logged using the '-d guest_errors' command line option.
21
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20190517174046.11146-4-peter.maydell@linaro.org
9
---
25
---
10
include/hw/arm/armv7m.h | 4 ++++
26
tests/qtest/boot-serial-test.c | 7 ++++++-
11
hw/arm/armv7m.c | 18 ++++++++++++++++++
27
1 file changed, 6 insertions(+), 1 deletion(-)
12
2 files changed, 22 insertions(+)
13
28
14
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
29
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/armv7m.h
31
--- a/tests/qtest/boot-serial-test.c
17
+++ b/include/hw/arm/armv7m.h
32
+++ b/tests/qtest/boot-serial-test.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
33
@@ -XXX,XX +XXX,XX @@ static const uint8_t kernel_plml605[] = {
19
* devices will be automatically layered on top of this view.)
20
* + Property "idau": IDAU interface (forwarded to CPU object)
21
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
22
+ * + Property "vfp": enable VFP (forwarded to CPU object)
23
+ * + Property "dsp": enable DSP (forwarded to CPU object)
24
* + Property "enable-bitband": expose bitbanded IO
25
*/
26
typedef struct ARMv7MState {
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
28
uint32_t init_svtor;
29
bool enable_bitband;
30
bool start_powered_off;
31
+ bool vfp;
32
+ bool dsp;
33
} ARMv7MState;
34
35
#endif
36
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/armv7m.c
39
+++ b/hw/arm/armv7m.c
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
41
return;
42
}
43
}
44
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
45
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
46
+ "vfp", &err);
47
+ if (err != NULL) {
48
+ error_propagate(errp, err);
49
+ return;
50
+ }
51
+ }
52
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
53
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
54
+ "dsp", &err);
55
+ if (err != NULL) {
56
+ error_propagate(errp, err);
57
+ return;
58
+ }
59
+ }
60
61
/*
62
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
63
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
64
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
65
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
66
false),
67
+ DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
68
+ DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
69
DEFINE_PROP_END_OF_LIST(),
70
};
34
};
71
35
36
static const uint8_t bios_raspi2[] = {
37
- 0x08, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #8] Get &UART0 */
38
+ 0x10, 0x30, 0x9f, 0xe5, /* ldr r3, [pc, #16] Get &UART0 */
39
+ 0x10, 0x20, 0x9f, 0xe5, /* ldr r2, [pc, #16] Get &CR */
40
+ 0xb0, 0x23, 0xc3, 0xe1, /* strh r2, [r3, #48] Set CR */
41
0x54, 0x20, 0xa0, 0xe3, /* mov r2, #'T' */
42
0x00, 0x20, 0xc3, 0xe5, /* loop: strb r2, [r3] *TXDAT = 'T' */
43
0xff, 0xff, 0xff, 0xea, /* b -4 (loop) */
44
0x00, 0x10, 0x20, 0x3f, /* UART0: 0x3f201000 */
45
+ 0x01, 0x01, 0x00, 0x00, /* CR: 0x101 = UARTEN|TXE */
46
};
47
48
static const uint8_t kernel_aarch64[] = {
49
0x02, 0x20, 0xa1, 0xd2, /* mov x2, #0x9000000 Load UART0 */
50
+ 0x21, 0x20, 0x80, 0x52, /* mov w1, 0x101 CR = UARTEN|TXE */
51
+ 0x41, 0x60, 0x00, 0x79, /* strh w1, [x2, #48] Set CR */
52
0x81, 0x0a, 0x80, 0x52, /* mov w1, #'T' */
53
0x41, 0x00, 0x00, 0x39, /* loop: strb w1, [x2] *TXDAT = 'T' */
54
0xff, 0xff, 0xff, 0x17, /* b -4 (loop) */
72
--
55
--
73
2.20.1
56
2.34.1
74
57
75
58
diff view generated by jsdifflib
1
Remove some old constructs from NEON_2RM_VCVT_F16_F32 code:
1
helper.c includes some small TCG helper functions used for mostly
2
* don't use cpu_F0s
2
arithmetic instructions. These are TCG only and there's no need for
3
* don't use tcg_gen_ld_f32
3
them to be in the large and unwieldy helper.c. Move them out to
4
their own source file in the tcg/ subdirectory, together with the
5
op_addsub.h multiply-included template header that they use.
6
7
Since we are moving op_addsub.h, we take the opportunity to
8
give it a name which matches our convention for files which
9
are not true header files but which are #included from other
10
C files: op_addsub.c.inc.
11
12
(Ironically, this means that helper.c no longer contains
13
any TCG helper function definitions at all.)
4
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20250110131211.2546314-1-peter.maydell@linaro.org
8
Message-id: 20190613163917.28589-11-peter.maydell@linaro.org
18
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
---
19
---
10
target/arm/translate.c | 27 ++++++++++++---------------
20
target/arm/helper.c | 285 -----------------
11
1 file changed, 12 insertions(+), 15 deletions(-)
21
target/arm/tcg/arith_helper.c | 296 ++++++++++++++++++
22
.../arm/{op_addsub.h => tcg/op_addsub.c.inc} | 0
23
target/arm/tcg/meson.build | 1 +
24
4 files changed, 297 insertions(+), 285 deletions(-)
25
create mode 100644 target/arm/tcg/arith_helper.c
26
rename target/arm/{op_addsub.h => tcg/op_addsub.c.inc} (100%)
12
27
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
30
--- a/target/arm/helper.c
16
+++ b/target/arm/translate.c
31
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
32
@@ -XXX,XX +XXX,XX @@
18
return ret;
33
#include "qemu/main-loop.h"
34
#include "qemu/timer.h"
35
#include "qemu/bitops.h"
36
-#include "qemu/crc32c.h"
37
#include "qemu/qemu-print.h"
38
#include "exec/exec-all.h"
39
#include "exec/translation-block.h"
40
-#include <zlib.h> /* for crc32 */
41
#include "hw/irq.h"
42
#include "system/cpu-timers.h"
43
#include "system/kvm.h"
44
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
45
};
19
}
46
}
20
47
21
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
48
-/*
22
#define tcg_gen_st_f32 tcg_gen_st_i32
49
- * Note that signed overflow is undefined in C. The following routines are
23
50
- * careful to use unsigned types where modulo arithmetic is required.
24
#define ARM_CP_RW_BIT (1 << 20)
51
- * Failure to do so _will_ break on newer gcc.
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
52
- */
26
q || (rm & 1)) {
53
-
27
return 1;
54
-/* Signed saturating arithmetic. */
28
}
55
-
29
- tmp = tcg_temp_new_i32();
56
-/* Perform 16-bit signed saturating addition. */
30
- tmp2 = tcg_temp_new_i32();
57
-static inline uint16_t add16_sat(uint16_t a, uint16_t b)
31
fpst = get_fpstatus_ptr(true);
58
-{
32
ahp = get_ahp_flag();
59
- uint16_t res;
33
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
60
-
34
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
61
- res = a + b;
35
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
62
- if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
36
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
63
- if (a & 0x8000) {
37
+ tmp = neon_load_reg(rm, 0);
64
- res = 0x8000;
38
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
65
- } else {
39
+ tmp2 = neon_load_reg(rm, 1);
66
- res = 0x7fff;
40
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
67
- }
41
tcg_gen_shli_i32(tmp2, tmp2, 16);
68
- }
42
tcg_gen_or_i32(tmp2, tmp2, tmp);
69
- return res;
43
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
70
-}
44
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
71
-
45
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
72
-/* Perform 8-bit signed saturating addition. */
46
+ tcg_temp_free_i32(tmp);
73
-static inline uint8_t add8_sat(uint8_t a, uint8_t b)
47
+ tmp = neon_load_reg(rm, 2);
74
-{
48
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
75
- uint8_t res;
49
+ tmp3 = neon_load_reg(rm, 3);
76
-
50
neon_store_reg(rd, 0, tmp2);
77
- res = a + b;
51
- tmp2 = tcg_temp_new_i32();
78
- if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
52
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
79
- if (a & 0x80) {
53
- tcg_gen_shli_i32(tmp2, tmp2, 16);
80
- res = 0x80;
54
- tcg_gen_or_i32(tmp2, tmp2, tmp);
81
- } else {
55
- neon_store_reg(rd, 1, tmp2);
82
- res = 0x7f;
56
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
83
- }
57
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
84
- }
58
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
85
- return res;
59
+ neon_store_reg(rd, 1, tmp3);
86
-}
60
tcg_temp_free_i32(tmp);
87
-
61
tcg_temp_free_i32(ahp);
88
-/* Perform 16-bit signed saturating subtraction. */
62
tcg_temp_free_ptr(fpst);
89
-static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
90
-{
91
- uint16_t res;
92
-
93
- res = a - b;
94
- if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
95
- if (a & 0x8000) {
96
- res = 0x8000;
97
- } else {
98
- res = 0x7fff;
99
- }
100
- }
101
- return res;
102
-}
103
-
104
-/* Perform 8-bit signed saturating subtraction. */
105
-static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
106
-{
107
- uint8_t res;
108
-
109
- res = a - b;
110
- if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
111
- if (a & 0x80) {
112
- res = 0x80;
113
- } else {
114
- res = 0x7f;
115
- }
116
- }
117
- return res;
118
-}
119
-
120
-#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
121
-#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
122
-#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
123
-#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
124
-#define PFX q
125
-
126
-#include "op_addsub.h"
127
-
128
-/* Unsigned saturating arithmetic. */
129
-static inline uint16_t add16_usat(uint16_t a, uint16_t b)
130
-{
131
- uint16_t res;
132
- res = a + b;
133
- if (res < a) {
134
- res = 0xffff;
135
- }
136
- return res;
137
-}
138
-
139
-static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
140
-{
141
- if (a > b) {
142
- return a - b;
143
- } else {
144
- return 0;
145
- }
146
-}
147
-
148
-static inline uint8_t add8_usat(uint8_t a, uint8_t b)
149
-{
150
- uint8_t res;
151
- res = a + b;
152
- if (res < a) {
153
- res = 0xff;
154
- }
155
- return res;
156
-}
157
-
158
-static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
159
-{
160
- if (a > b) {
161
- return a - b;
162
- } else {
163
- return 0;
164
- }
165
-}
166
-
167
-#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
168
-#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
169
-#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
170
-#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
171
-#define PFX uq
172
-
173
-#include "op_addsub.h"
174
-
175
-/* Signed modulo arithmetic. */
176
-#define SARITH16(a, b, n, op) do { \
177
- int32_t sum; \
178
- sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
179
- RESULT(sum, n, 16); \
180
- if (sum >= 0) \
181
- ge |= 3 << (n * 2); \
182
- } while (0)
183
-
184
-#define SARITH8(a, b, n, op) do { \
185
- int32_t sum; \
186
- sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
187
- RESULT(sum, n, 8); \
188
- if (sum >= 0) \
189
- ge |= 1 << n; \
190
- } while (0)
191
-
192
-
193
-#define ADD16(a, b, n) SARITH16(a, b, n, +)
194
-#define SUB16(a, b, n) SARITH16(a, b, n, -)
195
-#define ADD8(a, b, n) SARITH8(a, b, n, +)
196
-#define SUB8(a, b, n) SARITH8(a, b, n, -)
197
-#define PFX s
198
-#define ARITH_GE
199
-
200
-#include "op_addsub.h"
201
-
202
-/* Unsigned modulo arithmetic. */
203
-#define ADD16(a, b, n) do { \
204
- uint32_t sum; \
205
- sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
206
- RESULT(sum, n, 16); \
207
- if ((sum >> 16) == 1) \
208
- ge |= 3 << (n * 2); \
209
- } while (0)
210
-
211
-#define ADD8(a, b, n) do { \
212
- uint32_t sum; \
213
- sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
214
- RESULT(sum, n, 8); \
215
- if ((sum >> 8) == 1) \
216
- ge |= 1 << n; \
217
- } while (0)
218
-
219
-#define SUB16(a, b, n) do { \
220
- uint32_t sum; \
221
- sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
222
- RESULT(sum, n, 16); \
223
- if ((sum >> 16) == 0) \
224
- ge |= 3 << (n * 2); \
225
- } while (0)
226
-
227
-#define SUB8(a, b, n) do { \
228
- uint32_t sum; \
229
- sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
230
- RESULT(sum, n, 8); \
231
- if ((sum >> 8) == 0) \
232
- ge |= 1 << n; \
233
- } while (0)
234
-
235
-#define PFX u
236
-#define ARITH_GE
237
-
238
-#include "op_addsub.h"
239
-
240
-/* Halved signed arithmetic. */
241
-#define ADD16(a, b, n) \
242
- RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
243
-#define SUB16(a, b, n) \
244
- RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
245
-#define ADD8(a, b, n) \
246
- RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
247
-#define SUB8(a, b, n) \
248
- RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
249
-#define PFX sh
250
-
251
-#include "op_addsub.h"
252
-
253
-/* Halved unsigned arithmetic. */
254
-#define ADD16(a, b, n) \
255
- RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
256
-#define SUB16(a, b, n) \
257
- RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
258
-#define ADD8(a, b, n) \
259
- RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
260
-#define SUB8(a, b, n) \
261
- RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
262
-#define PFX uh
263
-
264
-#include "op_addsub.h"
265
-
266
-static inline uint8_t do_usad(uint8_t a, uint8_t b)
267
-{
268
- if (a > b) {
269
- return a - b;
270
- } else {
271
- return b - a;
272
- }
273
-}
274
-
275
-/* Unsigned sum of absolute byte differences. */
276
-uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
277
-{
278
- uint32_t sum;
279
- sum = do_usad(a, b);
280
- sum += do_usad(a >> 8, b >> 8);
281
- sum += do_usad(a >> 16, b >> 16);
282
- sum += do_usad(a >> 24, b >> 24);
283
- return sum;
284
-}
285
-
286
-/* For ARMv6 SEL instruction. */
287
-uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
288
-{
289
- uint32_t mask;
290
-
291
- mask = 0;
292
- if (flags & 1) {
293
- mask |= 0xff;
294
- }
295
- if (flags & 2) {
296
- mask |= 0xff00;
297
- }
298
- if (flags & 4) {
299
- mask |= 0xff0000;
300
- }
301
- if (flags & 8) {
302
- mask |= 0xff000000;
303
- }
304
- return (a & mask) | (b & ~mask);
305
-}
306
-
307
-/*
308
- * CRC helpers.
309
- * The upper bytes of val (above the number specified by 'bytes') must have
310
- * been zeroed out by the caller.
311
- */
312
-uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
313
-{
314
- uint8_t buf[4];
315
-
316
- stl_le_p(buf, val);
317
-
318
- /* zlib crc32 converts the accumulator and output to one's complement. */
319
- return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
320
-}
321
-
322
-uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
323
-{
324
- uint8_t buf[4];
325
-
326
- stl_le_p(buf, val);
327
-
328
- /* Linux crc32c converts the output to one's complement. */
329
- return crc32c(acc, buf, bytes) ^ 0xffffffff;
330
-}
331
332
/*
333
* Return the exception level to which FP-disabled exceptions should
334
diff --git a/target/arm/tcg/arith_helper.c b/target/arm/tcg/arith_helper.c
335
new file mode 100644
336
index XXXXXXX..XXXXXXX
337
--- /dev/null
338
+++ b/target/arm/tcg/arith_helper.c
339
@@ -XXX,XX +XXX,XX @@
340
+/*
341
+ * ARM generic helpers for various arithmetical operations.
342
+ *
343
+ * This code is licensed under the GNU GPL v2 or later.
344
+ *
345
+ * SPDX-License-Identifier: GPL-2.0-or-later
346
+ */
347
+#include "qemu/osdep.h"
348
+#include "cpu.h"
349
+#include "exec/helper-proto.h"
350
+#include "qemu/crc32c.h"
351
+#include <zlib.h> /* for crc32 */
352
+
353
+/*
354
+ * Note that signed overflow is undefined in C. The following routines are
355
+ * careful to use unsigned types where modulo arithmetic is required.
356
+ * Failure to do so _will_ break on newer gcc.
357
+ */
358
+
359
+/* Signed saturating arithmetic. */
360
+
361
+/* Perform 16-bit signed saturating addition. */
362
+static inline uint16_t add16_sat(uint16_t a, uint16_t b)
363
+{
364
+ uint16_t res;
365
+
366
+ res = a + b;
367
+ if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
368
+ if (a & 0x8000) {
369
+ res = 0x8000;
370
+ } else {
371
+ res = 0x7fff;
372
+ }
373
+ }
374
+ return res;
375
+}
376
+
377
+/* Perform 8-bit signed saturating addition. */
378
+static inline uint8_t add8_sat(uint8_t a, uint8_t b)
379
+{
380
+ uint8_t res;
381
+
382
+ res = a + b;
383
+ if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
384
+ if (a & 0x80) {
385
+ res = 0x80;
386
+ } else {
387
+ res = 0x7f;
388
+ }
389
+ }
390
+ return res;
391
+}
392
+
393
+/* Perform 16-bit signed saturating subtraction. */
394
+static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
395
+{
396
+ uint16_t res;
397
+
398
+ res = a - b;
399
+ if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
400
+ if (a & 0x8000) {
401
+ res = 0x8000;
402
+ } else {
403
+ res = 0x7fff;
404
+ }
405
+ }
406
+ return res;
407
+}
408
+
409
+/* Perform 8-bit signed saturating subtraction. */
410
+static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
411
+{
412
+ uint8_t res;
413
+
414
+ res = a - b;
415
+ if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
416
+ if (a & 0x80) {
417
+ res = 0x80;
418
+ } else {
419
+ res = 0x7f;
420
+ }
421
+ }
422
+ return res;
423
+}
424
+
425
+#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
426
+#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
427
+#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
428
+#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
429
+#define PFX q
430
+
431
+#include "op_addsub.c.inc"
432
+
433
+/* Unsigned saturating arithmetic. */
434
+static inline uint16_t add16_usat(uint16_t a, uint16_t b)
435
+{
436
+ uint16_t res;
437
+ res = a + b;
438
+ if (res < a) {
439
+ res = 0xffff;
440
+ }
441
+ return res;
442
+}
443
+
444
+static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
445
+{
446
+ if (a > b) {
447
+ return a - b;
448
+ } else {
449
+ return 0;
450
+ }
451
+}
452
+
453
+static inline uint8_t add8_usat(uint8_t a, uint8_t b)
454
+{
455
+ uint8_t res;
456
+ res = a + b;
457
+ if (res < a) {
458
+ res = 0xff;
459
+ }
460
+ return res;
461
+}
462
+
463
+static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
464
+{
465
+ if (a > b) {
466
+ return a - b;
467
+ } else {
468
+ return 0;
469
+ }
470
+}
471
+
472
+#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
473
+#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
474
+#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
475
+#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
476
+#define PFX uq
477
+
478
+#include "op_addsub.c.inc"
479
+
480
+/* Signed modulo arithmetic. */
481
+#define SARITH16(a, b, n, op) do { \
482
+ int32_t sum; \
483
+ sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
484
+ RESULT(sum, n, 16); \
485
+ if (sum >= 0) \
486
+ ge |= 3 << (n * 2); \
487
+ } while (0)
488
+
489
+#define SARITH8(a, b, n, op) do { \
490
+ int32_t sum; \
491
+ sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
492
+ RESULT(sum, n, 8); \
493
+ if (sum >= 0) \
494
+ ge |= 1 << n; \
495
+ } while (0)
496
+
497
+
498
+#define ADD16(a, b, n) SARITH16(a, b, n, +)
499
+#define SUB16(a, b, n) SARITH16(a, b, n, -)
500
+#define ADD8(a, b, n) SARITH8(a, b, n, +)
501
+#define SUB8(a, b, n) SARITH8(a, b, n, -)
502
+#define PFX s
503
+#define ARITH_GE
504
+
505
+#include "op_addsub.c.inc"
506
+
507
+/* Unsigned modulo arithmetic. */
508
+#define ADD16(a, b, n) do { \
509
+ uint32_t sum; \
510
+ sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
511
+ RESULT(sum, n, 16); \
512
+ if ((sum >> 16) == 1) \
513
+ ge |= 3 << (n * 2); \
514
+ } while (0)
515
+
516
+#define ADD8(a, b, n) do { \
517
+ uint32_t sum; \
518
+ sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
519
+ RESULT(sum, n, 8); \
520
+ if ((sum >> 8) == 1) \
521
+ ge |= 1 << n; \
522
+ } while (0)
523
+
524
+#define SUB16(a, b, n) do { \
525
+ uint32_t sum; \
526
+ sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
527
+ RESULT(sum, n, 16); \
528
+ if ((sum >> 16) == 0) \
529
+ ge |= 3 << (n * 2); \
530
+ } while (0)
531
+
532
+#define SUB8(a, b, n) do { \
533
+ uint32_t sum; \
534
+ sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
535
+ RESULT(sum, n, 8); \
536
+ if ((sum >> 8) == 0) \
537
+ ge |= 1 << n; \
538
+ } while (0)
539
+
540
+#define PFX u
541
+#define ARITH_GE
542
+
543
+#include "op_addsub.c.inc"
544
+
545
+/* Halved signed arithmetic. */
546
+#define ADD16(a, b, n) \
547
+ RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
548
+#define SUB16(a, b, n) \
549
+ RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
550
+#define ADD8(a, b, n) \
551
+ RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
552
+#define SUB8(a, b, n) \
553
+ RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
554
+#define PFX sh
555
+
556
+#include "op_addsub.c.inc"
557
+
558
+/* Halved unsigned arithmetic. */
559
+#define ADD16(a, b, n) \
560
+ RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
561
+#define SUB16(a, b, n) \
562
+ RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
563
+#define ADD8(a, b, n) \
564
+ RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
565
+#define SUB8(a, b, n) \
566
+ RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
567
+#define PFX uh
568
+
569
+#include "op_addsub.c.inc"
570
+
571
+static inline uint8_t do_usad(uint8_t a, uint8_t b)
572
+{
573
+ if (a > b) {
574
+ return a - b;
575
+ } else {
576
+ return b - a;
577
+ }
578
+}
579
+
580
+/* Unsigned sum of absolute byte differences. */
581
+uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
582
+{
583
+ uint32_t sum;
584
+ sum = do_usad(a, b);
585
+ sum += do_usad(a >> 8, b >> 8);
586
+ sum += do_usad(a >> 16, b >> 16);
587
+ sum += do_usad(a >> 24, b >> 24);
588
+ return sum;
589
+}
590
+
591
+/* For ARMv6 SEL instruction. */
592
+uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
593
+{
594
+ uint32_t mask;
595
+
596
+ mask = 0;
597
+ if (flags & 1) {
598
+ mask |= 0xff;
599
+ }
600
+ if (flags & 2) {
601
+ mask |= 0xff00;
602
+ }
603
+ if (flags & 4) {
604
+ mask |= 0xff0000;
605
+ }
606
+ if (flags & 8) {
607
+ mask |= 0xff000000;
608
+ }
609
+ return (a & mask) | (b & ~mask);
610
+}
611
+
612
+/*
613
+ * CRC helpers.
614
+ * The upper bytes of val (above the number specified by 'bytes') must have
615
+ * been zeroed out by the caller.
616
+ */
617
+uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
618
+{
619
+ uint8_t buf[4];
620
+
621
+ stl_le_p(buf, val);
622
+
623
+ /* zlib crc32 converts the accumulator and output to one's complement. */
624
+ return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
625
+}
626
+
627
+uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
628
+{
629
+ uint8_t buf[4];
630
+
631
+ stl_le_p(buf, val);
632
+
633
+ /* Linux crc32c converts the output to one's complement. */
634
+ return crc32c(acc, buf, bytes) ^ 0xffffffff;
635
+}
636
diff --git a/target/arm/op_addsub.h b/target/arm/tcg/op_addsub.c.inc
637
similarity index 100%
638
rename from target/arm/op_addsub.h
639
rename to target/arm/tcg/op_addsub.c.inc
640
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
641
index XXXXXXX..XXXXXXX 100644
642
--- a/target/arm/tcg/meson.build
643
+++ b/target/arm/tcg/meson.build
644
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
645
'tlb_helper.c',
646
'vec_helper.c',
647
'tlb-insns.c',
648
+ 'arith_helper.c',
649
))
650
651
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
63
--
652
--
64
2.20.1
653
2.34.1
65
654
66
655
diff view generated by jsdifflib
1
Allow the DSP extension to be disabled via a CPU property for
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
M-profile CPUs. (A and R-profile CPUs don't have this extension
3
as a defined separate optional architecture extension, so
4
they don't need the property.)
5
2
3
Before changing default pauth algorithm, we need to make sure current
4
default one (QARMA5) can still be selected.
5
6
$ qemu-system-aarch64 -cpu max,pauth-qarma5=on ...
7
8
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241219183211.3493974-2-pierrick.bouvier@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20190517174046.11146-3-peter.maydell@linaro.org
10
---
12
---
11
target/arm/cpu.h | 2 ++
13
docs/system/arm/cpu-features.rst | 5 ++++-
12
target/arm/cpu.c | 29 +++++++++++++++++++++++++++++
14
target/arm/cpu.h | 1 +
13
2 files changed, 31 insertions(+)
15
target/arm/arm-qmp-cmds.c | 2 +-
16
target/arm/cpu64.c | 20 ++++++++++++++------
17
tests/qtest/arm-cpu-features.c | 15 +++++++++++----
18
5 files changed, 31 insertions(+), 12 deletions(-)
14
19
20
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
21
index XXXXXXX..XXXXXXX 100644
22
--- a/docs/system/arm/cpu-features.rst
23
+++ b/docs/system/arm/cpu-features.rst
24
@@ -XXX,XX +XXX,XX @@ Below is the list of TCG VCPU features and their descriptions.
25
``pauth-qarma3``
26
When ``pauth`` is enabled, select the architected QARMA3 algorithm.
27
28
-Without either ``pauth-impdef`` or ``pauth-qarma3`` enabled,
29
+``pauth-qarma5``
30
+ When ``pauth`` is enabled, select the architected QARMA5 algorithm.
31
+
32
+Without ``pauth-impdef``, ``pauth-qarma3`` or ``pauth-qarma5`` enabled,
33
the architected QARMA5 algorithm is used. The architected QARMA5
34
and QARMA3 algorithms have good cryptographic properties, but can
35
be quite slow to emulate. The impdef algorithm used by QEMU is
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
38
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
20
bool has_vfp;
41
bool prop_pauth;
21
/* CPU has Neon */
42
bool prop_pauth_impdef;
22
bool has_neon;
43
bool prop_pauth_qarma3;
23
+ /* CPU has M-profile DSP extension */
44
+ bool prop_pauth_qarma5;
24
+ bool has_dsp;
45
bool prop_lpa2;
25
46
26
/* CPU has memory protection unit */
47
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
27
bool has_mpu;
48
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
50
--- a/target/arm/arm-qmp-cmds.c
31
+++ b/target/arm/cpu.c
51
+++ b/target/arm/arm-qmp-cmds.c
32
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_vfp_property =
52
@@ -XXX,XX +XXX,XX @@ static const char *cpu_model_advertised_features[] = {
33
static Property arm_cpu_has_neon_property =
53
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
34
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
54
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
35
55
"kvm-no-adjvtime", "kvm-steal-time",
36
+static Property arm_cpu_has_dsp_property =
56
- "pauth", "pauth-impdef", "pauth-qarma3",
37
+ DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
57
+ "pauth", "pauth-impdef", "pauth-qarma3", "pauth-qarma5",
38
+
58
NULL
39
static Property arm_cpu_has_mpu_property =
59
};
40
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
60
41
61
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/cpu64.c
64
+++ b/target/arm/cpu64.c
65
@@ -XXX,XX +XXX,XX @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
66
}
67
68
if (cpu->prop_pauth) {
69
- if (cpu->prop_pauth_impdef && cpu->prop_pauth_qarma3) {
70
+ if ((cpu->prop_pauth_impdef && cpu->prop_pauth_qarma3) ||
71
+ (cpu->prop_pauth_impdef && cpu->prop_pauth_qarma5) ||
72
+ (cpu->prop_pauth_qarma3 && cpu->prop_pauth_qarma5)) {
73
error_setg(errp,
74
- "cannot enable both pauth-impdef and pauth-qarma3");
75
+ "cannot enable pauth-impdef, pauth-qarma3 and "
76
+ "pauth-qarma5 at the same time");
77
return;
78
}
79
80
@@ -XXX,XX +XXX,XX @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
81
} else if (cpu->prop_pauth_qarma3) {
82
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, features);
83
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 1);
84
- } else {
85
+ } else { /* default is pauth-qarma5 */
86
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
87
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
88
}
89
- } else if (cpu->prop_pauth_impdef || cpu->prop_pauth_qarma3) {
90
- error_setg(errp, "cannot enable pauth-impdef or "
91
- "pauth-qarma3 without pauth");
92
+ } else if (cpu->prop_pauth_impdef ||
93
+ cpu->prop_pauth_qarma3 ||
94
+ cpu->prop_pauth_qarma5) {
95
+ error_setg(errp, "cannot enable pauth-impdef, pauth-qarma3 or "
96
+ "pauth-qarma5 without pauth");
97
error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
43
}
98
}
44
}
99
}
45
100
@@ -XXX,XX +XXX,XX @@ static const Property arm_cpu_pauth_impdef_property =
46
+ if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
101
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
47
+ arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
102
static const Property arm_cpu_pauth_qarma3_property =
48
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property,
103
DEFINE_PROP_BOOL("pauth-qarma3", ARMCPU, prop_pauth_qarma3, false);
49
+ &error_abort);
104
+static Property arm_cpu_pauth_qarma5_property =
50
+ }
105
+ DEFINE_PROP_BOOL("pauth-qarma5", ARMCPU, prop_pauth_qarma5, false);
51
+
106
52
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
107
void aarch64_add_pauth_properties(Object *obj)
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
108
{
54
&error_abort);
109
@@ -XXX,XX +XXX,XX @@ void aarch64_add_pauth_properties(Object *obj)
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
110
} else {
56
cpu->isar.mvfr0 = u;
111
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
112
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_qarma3_property);
113
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_qarma5_property);
57
}
114
}
58
115
}
59
+ if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
116
60
+ uint32_t u;
117
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
61
+
118
index XXXXXXX..XXXXXXX 100644
62
+ unset_feature(env, ARM_FEATURE_THUMB_DSP);
119
--- a/tests/qtest/arm-cpu-features.c
63
+
120
+++ b/tests/qtest/arm-cpu-features.c
64
+ u = cpu->isar.id_isar1;
121
@@ -XXX,XX +XXX,XX @@ static void pauth_tests_default(QTestState *qts, const char *cpu_type)
65
+ u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
122
assert_has_feature_enabled(qts, cpu_type, "pauth");
66
+ cpu->isar.id_isar1 = u;
123
assert_has_feature_disabled(qts, cpu_type, "pauth-impdef");
67
+
124
assert_has_feature_disabled(qts, cpu_type, "pauth-qarma3");
68
+ u = cpu->isar.id_isar2;
125
+ assert_has_feature_disabled(qts, cpu_type, "pauth-qarma5");
69
+ u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
126
assert_set_feature(qts, cpu_type, "pauth", false);
70
+ u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
127
assert_set_feature(qts, cpu_type, "pauth", true);
71
+ cpu->isar.id_isar2 = u;
128
assert_set_feature(qts, cpu_type, "pauth-impdef", true);
72
+
129
assert_set_feature(qts, cpu_type, "pauth-impdef", false);
73
+ u = cpu->isar.id_isar3;
130
assert_set_feature(qts, cpu_type, "pauth-qarma3", true);
74
+ u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
131
assert_set_feature(qts, cpu_type, "pauth-qarma3", false);
75
+ u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
132
+ assert_set_feature(qts, cpu_type, "pauth-qarma5", true);
76
+ cpu->isar.id_isar3 = u;
133
+ assert_set_feature(qts, cpu_type, "pauth-qarma5", false);
77
+ }
134
assert_error(qts, cpu_type,
78
+
135
- "cannot enable pauth-impdef or pauth-qarma3 without pauth",
79
/* Some features automatically imply others: */
136
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
80
if (arm_feature(env, ARM_FEATURE_V8)) {
137
"{ 'pauth': false, 'pauth-impdef': true }");
81
if (arm_feature(env, ARM_FEATURE_M)) {
138
assert_error(qts, cpu_type,
139
- "cannot enable pauth-impdef or pauth-qarma3 without pauth",
140
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
141
"{ 'pauth': false, 'pauth-qarma3': true }");
142
assert_error(qts, cpu_type,
143
- "cannot enable both pauth-impdef and pauth-qarma3",
144
- "{ 'pauth': true, 'pauth-impdef': true, 'pauth-qarma3': true }");
145
+ "cannot enable pauth-impdef, pauth-qarma3 or pauth-qarma5 without pauth",
146
+ "{ 'pauth': false, 'pauth-qarma5': true }");
147
+ assert_error(qts, cpu_type,
148
+ "cannot enable pauth-impdef, pauth-qarma3 and pauth-qarma5 at the same time",
149
+ "{ 'pauth': true, 'pauth-impdef': true, 'pauth-qarma3': true,"
150
+ " 'pauth-qarma5': true }");
151
}
152
153
static void test_query_cpu_model_expansion(const void *data)
82
--
154
--
83
2.20.1
155
2.34.1
84
85
diff view generated by jsdifflib
1
Stop using cpu_F0s in the Neon VCVT fixed-point operations.
1
The pauth-3 test explicitly tests that a computation of the
2
pointer-authentication produces the expected result. This means that
3
it must be run with the QARMA5 algorithm.
4
5
Explicitly set the pauth algorithm when running this test, so that it
6
doesn't break when we change the default algorithm the 'max' CPU
7
uses.
2
8
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-10-peter.maydell@linaro.org
7
---
10
---
8
target/arm/translate.c | 62 +++++++++++++++++++-----------------------
11
tests/tcg/aarch64/Makefile.softmmu-target | 3 +++
9
1 file changed, 28 insertions(+), 34 deletions(-)
12
1 file changed, 3 insertions(+)
10
13
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
16
--- a/tests/tcg/aarch64/Makefile.softmmu-target
14
+++ b/target/arm/translate.c
17
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
18
@@ -XXX,XX +XXX,XX @@ EXTRA_RUNS+=run-memory-replay
16
/* Function prototypes for gen_ functions calling Neon helpers. */
19
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
20
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
18
TCGv_i32, TCGv_i32);
21
pauth-3: CFLAGS += $(CROSS_CC_HAS_ARMV8_3)
19
+/* Function prototypes for gen_ functions for fix point conversions */
22
+# This test explicitly checks the output of the pauth operation so we
20
+typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
23
+# must force the use of the QARMA5 algorithm for it.
21
24
+run-pauth-3: QEMU_BASE_MACHINE=-M virt -cpu max,pauth-qarma5=on -display none
22
/* initialize TCG globals. */
25
else
23
void arm_translate_init(void)
26
pauth-3:
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
27
    $(call skip-test, "BUILD of $@", "missing compiler support")
25
return statusptr;
26
}
27
28
-#define VFP_GEN_FIX(name, round) \
29
-static inline void gen_vfp_##name(int dp, int shift, int neon) \
30
-{ \
31
- TCGv_i32 tmp_shift = tcg_const_i32(shift); \
32
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
33
- if (dp) { \
34
- gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
35
- statusptr); \
36
- } else { \
37
- gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
38
- statusptr); \
39
- } \
40
- tcg_temp_free_i32(tmp_shift); \
41
- tcg_temp_free_ptr(statusptr); \
42
-}
43
-VFP_GEN_FIX(tosl, _round_to_zero)
44
-VFP_GEN_FIX(toul, _round_to_zero)
45
-VFP_GEN_FIX(slto, )
46
-VFP_GEN_FIX(ulto, )
47
-#undef VFP_GEN_FIX
48
-
49
static inline long vfp_reg_offset(bool dp, unsigned reg)
50
{
51
if (dp) {
52
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
53
}
54
} else if (op >= 14) {
55
/* VCVT fixed-point. */
56
+ TCGv_ptr fpst;
57
+ TCGv_i32 shiftv;
58
+ VFPGenFixPointFn *fn;
59
+
60
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
61
return 1;
62
}
63
+
64
+ if (!(op & 1)) {
65
+ if (u) {
66
+ fn = gen_helper_vfp_ultos;
67
+ } else {
68
+ fn = gen_helper_vfp_sltos;
69
+ }
70
+ } else {
71
+ if (u) {
72
+ fn = gen_helper_vfp_touls_round_to_zero;
73
+ } else {
74
+ fn = gen_helper_vfp_tosls_round_to_zero;
75
+ }
76
+ }
77
+
78
/* We have already masked out the must-be-1 top bit of imm6,
79
* hence this 32-shift where the ARM ARM has 64-imm6.
80
*/
81
shift = 32 - shift;
82
+ fpst = get_fpstatus_ptr(1);
83
+ shiftv = tcg_const_i32(shift);
84
for (pass = 0; pass < (q ? 4 : 2); pass++) {
85
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
86
- if (!(op & 1)) {
87
- if (u)
88
- gen_vfp_ulto(0, shift, 1);
89
- else
90
- gen_vfp_slto(0, shift, 1);
91
- } else {
92
- if (u)
93
- gen_vfp_toul(0, shift, 1);
94
- else
95
- gen_vfp_tosl(0, shift, 1);
96
- }
97
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
98
+ TCGv_i32 tmpf = neon_load_reg(rm, pass);
99
+ fn(tmpf, tmpf, shiftv, fpst);
100
+ neon_store_reg(rd, pass, tmpf);
101
}
102
+ tcg_temp_free_ptr(fpst);
103
+ tcg_temp_free_i32(shiftv);
104
} else {
105
return 1;
106
}
107
--
28
--
108
2.20.1
29
2.34.1
109
110
diff view generated by jsdifflib
1
Allow VFP and neon to be disabled via a CPU property. As with
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
the "pmu" property, we only allow these features to be removed
3
from CPUs which have it by default, not added to CPUs which
4
don't have it.
5
2
6
The primary motivation here is to be able to optionally
3
Pointer authentication on aarch64 is pretty expensive (up to 50% of
7
create Cortex-M33 CPUs with no FPU, but we provide switches
4
execution time) when running a virtual machine with tcg and -cpu max
8
for both VFP and Neon because the two interact:
5
(which enables pauth=on).
9
* AArch64 can't have one without the other
10
* Some ID register fields only change if both are disabled
11
6
7
The advice is always: use pauth-impdef=on.
8
Our documentation even mentions it "by default" in
9
docs/system/introduction.rst.
10
11
Thus, we change the default to use impdef by default. This does not
12
affect kvm or hvf acceleration, since pauth algorithm used is the one
13
from host cpu.
14
15
This change is retro compatible, in terms of cli, with previous
16
versions, as the semantic of using -cpu max,pauth-impdef=on, and -cpu
17
max,pauth-qarma3=on is preserved.
18
The new option introduced in previous patch and matching old default is
19
-cpu max,pauth-qarma5=on.
20
It is retro compatible with migration as well, by defining a backcompat
21
property, that will use qarma5 by default for virt machine <= 9.2.
22
Tested by saving and restoring a vm from qemu 9.2.0 into qemu-master
23
(10.0) for cpus neoverse-n2 and max.
24
25
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20241219183211.3493974-3-pierrick.bouvier@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Message-id: 20190517174046.11146-2-peter.maydell@linaro.org
16
---
29
---
17
target/arm/cpu.h | 4 ++
30
docs/system/arm/cpu-features.rst | 2 +-
18
target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++--
31
docs/system/introduction.rst | 2 +-
19
2 files changed, 148 insertions(+), 6 deletions(-)
32
target/arm/cpu.h | 3 +++
33
hw/core/machine.c | 4 +++-
34
target/arm/cpu.c | 2 ++
35
target/arm/cpu64.c | 22 ++++++++++++++++------
36
6 files changed, 26 insertions(+), 9 deletions(-)
20
37
38
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
39
index XXXXXXX..XXXXXXX 100644
40
--- a/docs/system/arm/cpu-features.rst
41
+++ b/docs/system/arm/cpu-features.rst
42
@@ -XXX,XX +XXX,XX @@ Below is the list of TCG VCPU features and their descriptions.
43
When ``pauth`` is enabled, select the architected QARMA5 algorithm.
44
45
Without ``pauth-impdef``, ``pauth-qarma3`` or ``pauth-qarma5`` enabled,
46
-the architected QARMA5 algorithm is used. The architected QARMA5
47
+the QEMU impdef algorithm is used. The architected QARMA5
48
and QARMA3 algorithms have good cryptographic properties, but can
49
be quite slow to emulate. The impdef algorithm used by QEMU is
50
non-cryptographic but significantly faster.
51
diff --git a/docs/system/introduction.rst b/docs/system/introduction.rst
52
index XXXXXXX..XXXXXXX 100644
53
--- a/docs/system/introduction.rst
54
+++ b/docs/system/introduction.rst
55
@@ -XXX,XX +XXX,XX @@ would default to it anyway.
56
57
.. code::
58
59
- -cpu max,pauth-impdef=on \
60
+ -cpu max \
61
-smp 4 \
62
-accel tcg \
63
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
64
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
66
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
67
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
68
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
26
bool has_el3;
69
/* QOM property to indicate we should use the back-compat CNTFRQ default */
27
/* CPU has PMU (Performance Monitor Unit) */
70
bool backcompat_cntfrq;
28
bool has_pmu;
71
29
+ /* CPU has VFP */
72
+ /* QOM property to indicate we should use the back-compat QARMA5 default */
30
+ bool has_vfp;
73
+ bool backcompat_pauth_default_use_qarma5;
31
+ /* CPU has Neon */
74
+
32
+ bool has_neon;
75
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
33
76
* register.
34
/* CPU has memory protection unit */
77
*/
35
bool has_mpu;
78
diff --git a/hw/core/machine.c b/hw/core/machine.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/core/machine.c
81
+++ b/hw/core/machine.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "hw/virtio/virtio-iommu.h"
84
#include "audio/audio.h"
85
86
-GlobalProperty hw_compat_9_2[] = {};
87
+GlobalProperty hw_compat_9_2[] = {
88
+ {"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"},
89
+};
90
const size_t hw_compat_9_2_len = G_N_ELEMENTS(hw_compat_9_2);
91
92
GlobalProperty hw_compat_9_1[] = {
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
93
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.c
95
--- a/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
96
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_cfgend_property =
97
@@ -XXX,XX +XXX,XX @@ static const Property arm_cpu_properties[] = {
41
static Property arm_cpu_has_pmu_property =
98
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
42
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
99
/* True to default to the backward-compat old CNTFRQ rather than 1Ghz */
43
100
DEFINE_PROP_BOOL("backcompat-cntfrq", ARMCPU, backcompat_cntfrq, false),
44
+static Property arm_cpu_has_vfp_property =
101
+ DEFINE_PROP_BOOL("backcompat-pauth-default-use-qarma5", ARMCPU,
45
+ DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
102
+ backcompat_pauth_default_use_qarma5, false),
103
};
104
105
static const gchar *arm_gdb_arch_name(CPUState *cs)
106
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/cpu64.c
109
+++ b/target/arm/cpu64.c
110
@@ -XXX,XX +XXX,XX @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
111
return;
112
}
113
114
- if (cpu->prop_pauth_impdef) {
115
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
116
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
117
+ bool use_default = !cpu->prop_pauth_qarma5 &&
118
+ !cpu->prop_pauth_qarma3 &&
119
+ !cpu->prop_pauth_impdef;
46
+
120
+
47
+static Property arm_cpu_has_neon_property =
121
+ if (cpu->prop_pauth_qarma5 ||
48
+ DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
122
+ (use_default &&
49
+
123
+ cpu->backcompat_pauth_default_use_qarma5)) {
50
static Property arm_cpu_has_mpu_property =
124
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
51
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
125
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
52
126
} else if (cpu->prop_pauth_qarma3) {
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
127
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, features);
54
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
128
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 1);
55
set_feature(&cpu->env, ARM_FEATURE_PMSA);
129
- } else { /* default is pauth-qarma5 */
56
}
130
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
57
+ /* Similarly for the VFP feature bits */
131
- isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
58
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
132
+ } else if (cpu->prop_pauth_impdef ||
59
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
133
+ (use_default &&
60
+ }
134
+ !cpu->backcompat_pauth_default_use_qarma5)) {
61
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
135
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
62
+ set_feature(&cpu->env, ARM_FEATURE_VFP);
136
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
63
+ }
137
+ } else {
64
138
+ g_assert_not_reached();
65
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
139
}
66
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
140
} else if (cpu->prop_pauth_impdef ||
67
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
141
cpu->prop_pauth_qarma3 ||
68
&error_abort);
69
}
70
71
+ /*
72
+ * Allow user to turn off VFP and Neon support, but only for TCG --
73
+ * KVM does not currently allow us to lie to the guest about its
74
+ * ID/feature registers, so the guest always sees what the host has.
75
+ */
76
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
77
+ cpu->has_vfp = true;
78
+ if (!kvm_enabled()) {
79
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property,
80
+ &error_abort);
81
+ }
82
+ }
83
+
84
+ if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
85
+ cpu->has_neon = true;
86
+ if (!kvm_enabled()) {
87
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property,
88
+ &error_abort);
89
+ }
90
+ }
91
+
92
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
93
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
94
&error_abort);
95
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
96
return;
97
}
98
99
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
100
+ cpu->has_vfp != cpu->has_neon) {
101
+ /*
102
+ * This is an architectural requirement for AArch64; AArch32 is
103
+ * more flexible and permits VFP-no-Neon and Neon-no-VFP.
104
+ */
105
+ error_setg(errp,
106
+ "AArch64 CPUs must have both VFP and Neon or neither");
107
+ return;
108
+ }
109
+
110
+ if (!cpu->has_vfp) {
111
+ uint64_t t;
112
+ uint32_t u;
113
+
114
+ unset_feature(env, ARM_FEATURE_VFP);
115
+ unset_feature(env, ARM_FEATURE_VFP3);
116
+ unset_feature(env, ARM_FEATURE_VFP4);
117
+
118
+ t = cpu->isar.id_aa64isar1;
119
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
120
+ cpu->isar.id_aa64isar1 = t;
121
+
122
+ t = cpu->isar.id_aa64pfr0;
123
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
124
+ cpu->isar.id_aa64pfr0 = t;
125
+
126
+ u = cpu->isar.id_isar6;
127
+ u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
128
+ cpu->isar.id_isar6 = u;
129
+
130
+ u = cpu->isar.mvfr0;
131
+ u = FIELD_DP32(u, MVFR0, FPSP, 0);
132
+ u = FIELD_DP32(u, MVFR0, FPDP, 0);
133
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
134
+ u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
135
+ u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
136
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
137
+ u = FIELD_DP32(u, MVFR0, FPROUND, 0);
138
+ cpu->isar.mvfr0 = u;
139
+
140
+ u = cpu->isar.mvfr1;
141
+ u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
142
+ u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
143
+ u = FIELD_DP32(u, MVFR1, FPHP, 0);
144
+ cpu->isar.mvfr1 = u;
145
+
146
+ u = cpu->isar.mvfr2;
147
+ u = FIELD_DP32(u, MVFR2, FPMISC, 0);
148
+ cpu->isar.mvfr2 = u;
149
+ }
150
+
151
+ if (!cpu->has_neon) {
152
+ uint64_t t;
153
+ uint32_t u;
154
+
155
+ unset_feature(env, ARM_FEATURE_NEON);
156
+
157
+ t = cpu->isar.id_aa64isar0;
158
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
159
+ cpu->isar.id_aa64isar0 = t;
160
+
161
+ t = cpu->isar.id_aa64isar1;
162
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
163
+ cpu->isar.id_aa64isar1 = t;
164
+
165
+ t = cpu->isar.id_aa64pfr0;
166
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
167
+ cpu->isar.id_aa64pfr0 = t;
168
+
169
+ u = cpu->isar.id_isar5;
170
+ u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
171
+ u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
172
+ cpu->isar.id_isar5 = u;
173
+
174
+ u = cpu->isar.id_isar6;
175
+ u = FIELD_DP32(u, ID_ISAR6, DP, 0);
176
+ u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
177
+ cpu->isar.id_isar6 = u;
178
+
179
+ u = cpu->isar.mvfr1;
180
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
181
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
182
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
183
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
184
+ u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
185
+ cpu->isar.mvfr1 = u;
186
+
187
+ u = cpu->isar.mvfr2;
188
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
189
+ cpu->isar.mvfr2 = u;
190
+ }
191
+
192
+ if (!cpu->has_neon && !cpu->has_vfp) {
193
+ uint64_t t;
194
+ uint32_t u;
195
+
196
+ t = cpu->isar.id_aa64isar0;
197
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
198
+ cpu->isar.id_aa64isar0 = t;
199
+
200
+ t = cpu->isar.id_aa64isar1;
201
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
202
+ cpu->isar.id_aa64isar1 = t;
203
+
204
+ u = cpu->isar.mvfr0;
205
+ u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
206
+ cpu->isar.mvfr0 = u;
207
+ }
208
+
209
/* Some features automatically imply others: */
210
if (arm_feature(env, ARM_FEATURE_V8)) {
211
if (arm_feature(env, ARM_FEATURE_M)) {
212
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
213
if (arm_feature(env, ARM_FEATURE_V5)) {
214
set_feature(env, ARM_FEATURE_V4T);
215
}
216
- if (arm_feature(env, ARM_FEATURE_VFP4)) {
217
- set_feature(env, ARM_FEATURE_VFP3);
218
- }
219
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
220
- set_feature(env, ARM_FEATURE_VFP);
221
- }
222
if (arm_feature(env, ARM_FEATURE_LPAE)) {
223
set_feature(env, ARM_FEATURE_V7MP);
224
set_feature(env, ARM_FEATURE_PXN);
225
--
142
--
226
2.20.1
143
2.34.1
227
228
diff view generated by jsdifflib
Deleted patch
1
The GIC ID registers cover an area 0x30 bytes in size
2
(12 registers, 4 bytes each). We were incorrectly decoding
3
only the first 0x20 bytes.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190524124248.28394-2-peter.maydell@linaro.org
8
---
9
hw/intc/arm_gicv3_dist.c | 4 ++--
10
hw/intc/arm_gicv3_redist.c | 4 ++--
11
2 files changed, 4 insertions(+), 4 deletions(-)
12
13
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/arm_gicv3_dist.c
16
+++ b/hw/intc/arm_gicv3_dist.c
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
18
}
19
return MEMTX_OK;
20
}
21
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
22
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
23
/* ID registers */
24
*data = gicv3_idreg(offset - GICD_IDREGS);
25
return MEMTX_OK;
26
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_writel(GICv3State *s, hwaddr offset,
27
gicd_write_irouter(s, attrs, irq, r);
28
return MEMTX_OK;
29
}
30
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
31
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
32
case GICD_TYPER:
33
case GICD_IIDR:
34
/* RO registers, ignore the write */
35
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/intc/arm_gicv3_redist.c
38
+++ b/hw/intc/arm_gicv3_redist.c
39
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
40
}
41
*data = cs->gicr_nsacr;
42
return MEMTX_OK;
43
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
44
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
45
*data = gicv3_idreg(offset - GICR_IDREGS);
46
return MEMTX_OK;
47
default:
48
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
49
return MEMTX_OK;
50
case GICR_IIDR:
51
case GICR_TYPER:
52
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
53
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
54
/* RO registers, ignore the write */
55
qemu_log_mask(LOG_GUEST_ERROR,
56
"%s: invalid guest write to RO register at offset "
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
The GICv3 specification says that the GICD_TYPER.SecurityExtn bit
2
is RAZ if GICD_CTLR.DS is 1. We were incorrectly making it RAZ
3
if the security extension is unsupported. "Security extension
4
unsupported" always implies GICD_CTLR.DS == 1, but the guest can
5
also set DS on a GIC which does support the security extension.
6
Fix the condition to correctly check the GICD_CTLR.DS bit.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190524124248.28394-3-peter.maydell@linaro.org
10
---
11
hw/intc/arm_gicv3_dist.c | 8 +++++++-
12
1 file changed, 7 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_dist.c
17
+++ b/hw/intc/arm_gicv3_dist.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
19
* ITLinesNumber == (num external irqs / 32) - 1
20
*/
21
int itlinesnumber = ((s->num_irq - GIC_INTERNAL) / 32) - 1;
22
+ /*
23
+ * SecurityExtn must be RAZ if GICD_CTLR.DS == 1, and
24
+ * "security extensions not supported" always implies DS == 1,
25
+ * so we only need to check the DS bit.
26
+ */
27
+ bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
28
29
- *data = (1 << 25) | (1 << 24) | (s->security_extn << 10) |
30
+ *data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
31
(0xf << 19) | itlinesnumber;
32
return MEMTX_OK;
33
}
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
We want to use vfp_expand_imm() in the AArch32 VFP decode;
2
move it from the a64-only header/source file to the
3
AArch32 one (which is always compiled even for AArch64).
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-a64.h | 1 -
11
target/arm/translate.h | 7 +++++++
12
target/arm/translate-a64.c | 32 --------------------------------
13
target/arm/translate-vfp.inc.c | 33 +++++++++++++++++++++++++++++++++
14
4 files changed, 40 insertions(+), 33 deletions(-)
15
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.h
19
+++ b/target/arm/translate-a64.h
20
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
21
TCGv_ptr get_fpstatus_ptr(bool);
22
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
23
unsigned int imms, unsigned int immr);
24
-uint64_t vfp_expand_imm(int size, uint8_t imm8);
25
bool sve_access_check(DisasContext *s);
26
27
/* We should have at some point before trying to access an FP register
28
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.h
31
+++ b/target/arm/translate.h
32
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
33
}
34
}
35
36
+/*
37
+ * Given a VFP floating point constant encoded into an 8 bit immediate in an
38
+ * instruction, expand it to the actual constant value of the specified
39
+ * size, as per the VFPExpandImm() pseudocode in the Arm ARM.
40
+ */
41
+uint64_t vfp_expand_imm(int size, uint8_t imm8);
42
+
43
/* Vector operations shared between ARM and AArch64. */
44
extern const GVecGen3 mla_op[4];
45
extern const GVecGen3 mls_op[4];
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
51
}
52
}
53
54
-/* The imm8 encodes the sign bit, enough bits to represent an exponent in
55
- * the range 01....1xx to 10....0xx, and the most significant 4 bits of
56
- * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
57
- */
58
-uint64_t vfp_expand_imm(int size, uint8_t imm8)
59
-{
60
- uint64_t imm;
61
-
62
- switch (size) {
63
- case MO_64:
64
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
65
- (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
66
- extract32(imm8, 0, 6);
67
- imm <<= 48;
68
- break;
69
- case MO_32:
70
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
71
- (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
72
- (extract32(imm8, 0, 6) << 3);
73
- imm <<= 16;
74
- break;
75
- case MO_16:
76
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
77
- (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
78
- (extract32(imm8, 0, 6) << 6);
79
- break;
80
- default:
81
- g_assert_not_reached();
82
- }
83
- return imm;
84
-}
85
-
86
/* Floating point immediate
87
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
88
* +---+---+---+-----------+------+---+------------+-------+------+------+
89
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-vfp.inc.c
92
+++ b/target/arm/translate-vfp.inc.c
93
@@ -XXX,XX +XXX,XX @@
94
#include "decode-vfp.inc.c"
95
#include "decode-vfp-uncond.inc.c"
96
97
+/*
98
+ * The imm8 encodes the sign bit, enough bits to represent an exponent in
99
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
100
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
101
+ */
102
+uint64_t vfp_expand_imm(int size, uint8_t imm8)
103
+{
104
+ uint64_t imm;
105
+
106
+ switch (size) {
107
+ case MO_64:
108
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
109
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
110
+ extract32(imm8, 0, 6);
111
+ imm <<= 48;
112
+ break;
113
+ case MO_32:
114
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
115
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
116
+ (extract32(imm8, 0, 6) << 3);
117
+ imm <<= 16;
118
+ break;
119
+ case MO_16:
120
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
121
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
122
+ (extract32(imm8, 0, 6) << 6);
123
+ break;
124
+ default:
125
+ g_assert_not_reached();
126
+ }
127
+ return imm;
128
+}
129
+
130
/*
131
* Return the offset of a 16-bit half of the specified VFP single-precision
132
* register. If top is true, returns the top 16 bits; otherwise the bottom
133
--
134
2.20.1
135
136
diff view generated by jsdifflib
Deleted patch
1
The AArch32 VMOV (immediate) instruction uses the same VFP encoded
2
immediate format we already handle in vfp_expand_imm(). Use that
3
function rather than hand-decoding it.
4
1
5
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-3-peter.maydell@linaro.org
10
---
11
target/arm/translate-vfp.inc.c | 28 ++++------------------------
12
target/arm/vfp.decode | 10 ++++++----
13
2 files changed, 10 insertions(+), 28 deletions(-)
14
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
20
uint32_t delta_d = 0;
21
int veclen = s->vec_len;
22
TCGv_i32 fd;
23
- uint32_t n, i, vd;
24
+ uint32_t vd;
25
26
vd = a->vd;
27
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
29
}
30
}
31
32
- n = (a->imm4h << 28) & 0x80000000;
33
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
34
- if (i & 0x40) {
35
- i |= 0x780;
36
- } else {
37
- i |= 0x800;
38
- }
39
- n |= i << 19;
40
-
41
- fd = tcg_temp_new_i32();
42
- tcg_gen_movi_i32(fd, n);
43
+ fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
44
45
for (;;) {
46
neon_store_reg32(fd, vd);
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
48
uint32_t delta_d = 0;
49
int veclen = s->vec_len;
50
TCGv_i64 fd;
51
- uint32_t n, i, vd;
52
+ uint32_t vd;
53
54
vd = a->vd;
55
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
57
}
58
}
59
60
- n = (a->imm4h << 28) & 0x80000000;
61
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
62
- if (i & 0x40) {
63
- i |= 0x3f80;
64
- } else {
65
- i |= 0x4000;
66
- }
67
- n |= i << 16;
68
-
69
- fd = tcg_temp_new_i64();
70
- tcg_gen_movi_i64(fd, ((uint64_t)n) << 32);
71
+ fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
72
73
for (;;) {
74
neon_store_reg64(fd, vd);
75
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/vfp.decode
78
+++ b/target/arm/vfp.decode
79
@@ -XXX,XX +XXX,XX @@
80
%vmov_idx_b 21:1 5:2
81
%vmov_idx_h 21:1 6:1
82
83
+%vmov_imm 16:4 0:4
84
+
85
# VMOV scalar to general-purpose register; note that this does
86
# include some Neon cases.
87
VMOV_to_gp ---- 1110 u:1 1. 1 .... rt:4 1011 ... 1 0000 \
88
@@ -XXX,XX +XXX,XX @@ VFM_sp ---- 1110 1.10 .... .... 1010 . o2:1 . 0 .... \
89
VFM_dp ---- 1110 1.10 .... .... 1011 . o2:1 . 0 .... \
90
vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=2
91
92
-VMOV_imm_sp ---- 1110 1.11 imm4h:4 .... 1010 0000 imm4l:4 \
93
- vd=%vd_sp
94
-VMOV_imm_dp ---- 1110 1.11 imm4h:4 .... 1011 0000 imm4l:4 \
95
- vd=%vd_dp
96
+VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
97
+ vd=%vd_sp imm=%vmov_imm
98
+VMOV_imm_dp ---- 1110 1.11 .... .... 1011 0000 .... \
99
+ vd=%vd_dp imm=%vmov_imm
100
101
VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... \
102
vd=%vd_sp vm=%vm_sp
103
--
104
2.20.1
105
106
diff view generated by jsdifflib
Deleted patch
1
Where Neon instructions are floating point operations, we
2
mostly use the old VFP utility functions like gen_vfp_abs()
3
which work on the TCG globals cpu_F0s and cpu_F1s. The
4
Neon for-each-element loop conditionally loads the inputs
5
into either a plain old TCG temporary for most operations
6
or into cpu_F0s for float operations, and similarly stores
7
back either cpu_F0s or the temporary.
8
1
9
Switch NEON_2RM_VABS_F away from using cpu_F0s, and
10
update neon_2rm_is_float_op() accordingly.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20190613163917.28589-4-peter.maydell@linaro.org
16
---
17
target/arm/translate.c | 19 ++++++++-----------
18
1 file changed, 8 insertions(+), 11 deletions(-)
19
20
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate.c
23
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
25
return statusptr;
26
}
27
28
-static inline void gen_vfp_abs(int dp)
29
-{
30
- if (dp)
31
- gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
32
- else
33
- gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
34
-}
35
-
36
static inline void gen_vfp_neg(int dp)
37
{
38
if (dp)
39
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
40
41
static int neon_2rm_is_float_op(int op)
42
{
43
- /* Return true if this neon 2reg-misc op is float-to-float */
44
- return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
45
+ /*
46
+ * Return true if this neon 2reg-misc op is float-to-float.
47
+ * This is not a property of the operation but of our code --
48
+ * what we are asking here is "does the code for this case in
49
+ * the Neon for-each-pass loop use cpu_F0s?".
50
+ */
51
+ return (op == NEON_2RM_VNEG_F ||
52
(op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
53
op == NEON_2RM_VRINTM ||
54
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
55
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
56
break;
57
}
58
case NEON_2RM_VABS_F:
59
- gen_vfp_abs(0);
60
+ gen_helper_vfp_abss(tmp, tmp);
61
break;
62
case NEON_2RM_VNEG_F:
63
gen_vfp_neg(0);
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Switch NEON_2RM_VABS_F away from using cpu_F0s.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-5-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 13 ++-----------
9
1 file changed, 2 insertions(+), 11 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
16
return statusptr;
17
}
18
19
-static inline void gen_vfp_neg(int dp)
20
-{
21
- if (dp)
22
- gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
23
- else
24
- gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
25
-}
26
-
27
#define VFP_GEN_ITOF(name) \
28
static inline void gen_vfp_##name(int dp, int neon) \
29
{ \
30
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
31
* what we are asking here is "does the code for this case in
32
* the Neon for-each-pass loop use cpu_F0s?".
33
*/
34
- return (op == NEON_2RM_VNEG_F ||
35
- (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
36
+ return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
37
op == NEON_2RM_VRINTM ||
38
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
39
op >= NEON_2RM_VRECPE_F);
40
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
gen_helper_vfp_abss(tmp, tmp);
42
break;
43
case NEON_2RM_VNEG_F:
44
- gen_vfp_neg(0);
45
+ gen_helper_vfp_negs(tmp, tmp);
46
break;
47
case NEON_2RM_VSWP:
48
tmp2 = neon_load_reg(rd, pass);
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
Switch NEON_2RM_VRINT* away from using cpu_F0s.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-6-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 8 +++-----
9
1 file changed, 3 insertions(+), 5 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
16
* what we are asking here is "does the code for this case in
17
* the Neon for-each-pass loop use cpu_F0s?".
18
*/
19
- return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
20
- op == NEON_2RM_VRINTM ||
21
- (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
22
+ return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
23
op >= NEON_2RM_VRECPE_F);
24
}
25
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
27
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
28
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
29
cpu_env);
30
- gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
31
+ gen_helper_rints(tmp, tmp, fpstatus);
32
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
33
cpu_env);
34
tcg_temp_free_ptr(fpstatus);
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
36
case NEON_2RM_VRINTX:
37
{
38
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
39
- gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
40
+ gen_helper_rints_exact(tmp, tmp, fpstatus);
41
tcg_temp_free_ptr(fpstatus);
42
break;
43
}
44
--
45
2.20.1
46
47
diff view generated by jsdifflib
1
Stop using cpu_F0s for the NEON_2RM_VCVT[ANPM][US] ops.
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Message-id: 20241219183211.3493974-4-pierrick.bouvier@linaro.org
5
[PMM: Removed a paragraph about using non-versioned models.]
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-7-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate.c | 7 +++----
8
docs/system/arm/virt.rst | 4 ++++
9
1 file changed, 3 insertions(+), 4 deletions(-)
9
1 file changed, 4 insertions(+)
10
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
13
--- a/docs/system/arm/virt.rst
14
+++ b/target/arm/translate.c
14
+++ b/docs/system/arm/virt.rst
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
15
@@ -XXX,XX +XXX,XX @@ of the 5.0 release and ``virt-5.0`` of the 5.1 release. Migration
16
* what we are asking here is "does the code for this case in
16
is not guaranteed to work between different QEMU releases for
17
* the Neon for-each-pass loop use cpu_F0s?".
17
the non-versioned ``virt`` machine type.
18
*/
18
19
- return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
19
+VM migration is not guaranteed when using ``-cpu max``, as features
20
- op >= NEON_2RM_VRECPE_F);
20
+supported may change between QEMU versions. To ensure your VM can be
21
+ return op >= NEON_2RM_VRECPE_F;
21
+migrated, it is recommended to use another cpu model instead.
22
}
22
+
23
23
Supported devices
24
static bool neon_2rm_is_v8_op(int op)
24
"""""""""""""""""
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
26
cpu_env);
27
28
if (is_signed) {
29
- gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
30
+ gen_helper_vfp_tosls(tmp, tmp,
31
tcg_shift, fpst);
32
} else {
33
- gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
34
+ gen_helper_vfp_touls(tmp, tmp,
35
tcg_shift, fpst);
36
}
37
25
38
--
26
--
39
2.20.1
27
2.34.1
40
41
diff view generated by jsdifflib
Deleted patch
1
Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-8-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 6 +++---
9
1 file changed, 3 insertions(+), 3 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
16
* what we are asking here is "does the code for this case in
17
* the Neon for-each-pass loop use cpu_F0s?".
18
*/
19
- return op >= NEON_2RM_VRECPE_F;
20
+ return op >= NEON_2RM_VCVT_FS;
21
}
22
23
static bool neon_2rm_is_v8_op(int op)
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
25
case NEON_2RM_VRECPE_F:
26
{
27
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
28
- gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
29
+ gen_helper_recpe_f32(tmp, tmp, fpstatus);
30
tcg_temp_free_ptr(fpstatus);
31
break;
32
}
33
case NEON_2RM_VRSQRTE_F:
34
{
35
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
36
- gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
37
+ gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
38
tcg_temp_free_ptr(fpstatus);
39
break;
40
}
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
Stop using cpu_F0s for the Neon f32/s32 VCVT operations.
2
Since this is the last user of cpu_F0s in the Neon 2rm-op
3
loop, we can remove the handling code for it too.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-9-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 82 ++++++++++++------------------------------
11
1 file changed, 22 insertions(+), 60 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
18
return statusptr;
19
}
20
21
-#define VFP_GEN_ITOF(name) \
22
-static inline void gen_vfp_##name(int dp, int neon) \
23
-{ \
24
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
25
- if (dp) { \
26
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
27
- } else { \
28
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
29
- } \
30
- tcg_temp_free_ptr(statusptr); \
31
-}
32
-
33
-VFP_GEN_ITOF(uito)
34
-VFP_GEN_ITOF(sito)
35
-#undef VFP_GEN_ITOF
36
-
37
-#define VFP_GEN_FTOI(name) \
38
-static inline void gen_vfp_##name(int dp, int neon) \
39
-{ \
40
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
41
- if (dp) { \
42
- gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
43
- } else { \
44
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
45
- } \
46
- tcg_temp_free_ptr(statusptr); \
47
-}
48
-
49
-VFP_GEN_FTOI(touiz)
50
-VFP_GEN_FTOI(tosiz)
51
-#undef VFP_GEN_FTOI
52
-
53
#define VFP_GEN_FIX(name, round) \
54
static inline void gen_vfp_##name(int dp, int shift, int neon) \
55
{ \
56
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
57
#define NEON_2RM_VCVT_SF 62
58
#define NEON_2RM_VCVT_UF 63
59
60
-static int neon_2rm_is_float_op(int op)
61
-{
62
- /*
63
- * Return true if this neon 2reg-misc op is float-to-float.
64
- * This is not a property of the operation but of our code --
65
- * what we are asking here is "does the code for this case in
66
- * the Neon for-each-pass loop use cpu_F0s?".
67
- */
68
- return op >= NEON_2RM_VCVT_FS;
69
-}
70
-
71
static bool neon_2rm_is_v8_op(int op)
72
{
73
/* Return true if this neon 2reg-misc op is ARMv8 and up */
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
75
default:
76
elementwise:
77
for (pass = 0; pass < (q ? 4 : 2); pass++) {
78
- if (neon_2rm_is_float_op(op)) {
79
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
80
- neon_reg_offset(rm, pass));
81
- tmp = NULL;
82
- } else {
83
- tmp = neon_load_reg(rm, pass);
84
- }
85
+ tmp = neon_load_reg(rm, pass);
86
switch (op) {
87
case NEON_2RM_VREV32:
88
switch (size) {
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
break;
91
}
92
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
93
- gen_vfp_sito(0, 1);
94
+ {
95
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
96
+ gen_helper_vfp_sitos(tmp, tmp, fpstatus);
97
+ tcg_temp_free_ptr(fpstatus);
98
break;
99
+ }
100
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
101
- gen_vfp_uito(0, 1);
102
+ {
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
104
+ gen_helper_vfp_uitos(tmp, tmp, fpstatus);
105
+ tcg_temp_free_ptr(fpstatus);
106
break;
107
+ }
108
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
109
- gen_vfp_tosiz(0, 1);
110
+ {
111
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
112
+ gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
113
+ tcg_temp_free_ptr(fpstatus);
114
break;
115
+ }
116
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
117
- gen_vfp_touiz(0, 1);
118
+ {
119
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
120
+ gen_helper_vfp_touizs(tmp, tmp, fpstatus);
121
+ tcg_temp_free_ptr(fpstatus);
122
break;
123
+ }
124
default:
125
/* Reserved op values were caught by the
126
* neon_2rm_sizes[] check earlier.
127
*/
128
abort();
129
}
130
- if (neon_2rm_is_float_op(op)) {
131
- tcg_gen_st_f32(cpu_F0s, cpu_env,
132
- neon_reg_offset(rd, pass));
133
- } else {
134
- neon_store_reg(rd, pass, tmp);
135
- }
136
+ neon_store_reg(rd, pass, tmp);
137
}
138
break;
139
}
140
--
141
2.20.1
142
143
diff view generated by jsdifflib