1
The following changes since commit ad1b4ec39caa5b3f17cbd8160283a03a3dcfe2ae:
1
Latest arm queue, half minor code cleanups and half minor
2
bug fixes.
2
3
3
Merge remote-tracking branch 'remotes/kraxel/tags/input-20180515-pull-request' into staging (2018-05-15 12:50:06 +0100)
4
-- PMM
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)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180515
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190617
8
13
9
for you to fetch changes up to ae7651804748c6b479d5ae09aeac4edb9c44f76e:
14
for you to fetch changes up to 1120827fa182f0e76226df7ffe7a86598d1df54f:
10
15
11
tcg: Optionally log FPU state in TCG -d cpu logging (2018-05-15 14:58:44 +0100)
16
target/arm: Only implement doubles if the FPU supports them (2019-06-17 15:15:06 +0100)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* Fix coverity nit in int_to_float code
20
* support large kernel images in bootloader (by avoiding
16
* Don't set Invalid for float-to-int(MAXINT)
21
putting the initrd over the top of them)
17
* Fix fp_status_f16 tininess before rounding
22
* correctly disable FPU/DSP in the CPU for the mps2-an521, musca-a boards
18
* Add various missing insns from the v8.2-FP16 extension
23
* arm_gicv3: Fix decoding of ID register range
19
* Fix sqrt_f16 exception raising
24
* arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
20
* sdcard: Correct CRC16 offset in sd_function_switch()
25
* some code cleanups following on from the VFP decodetree conversion
21
* tcg: Optionally log FPU state in TCG -d cpu logging
26
* Only implement doubles if the FPU supports them
27
(so we now correctly model Cortex-M4, -M33 as single precision only)
22
28
23
----------------------------------------------------------------
29
----------------------------------------------------------------
24
Alex Bennée (5):
30
Peter Maydell (24):
25
fpu/softfloat: int_to_float ensure r fully initialised
31
hw/arm/boot: Don't assume RAM starts at address zero
26
target/arm: Implement FCMP for fp16
32
hw/arm/boot: Diagnose layouts that put initrd or DTB off the end of RAM
27
target/arm: Implement FCSEL for fp16
33
hw/arm/boot: Avoid placing the initrd on top of the kernel
28
target/arm: Implement FMOV (immediate) for fp16
34
hw/arm/boot: Honour image size field in AArch64 Image format kernels
29
target/arm: Fix sqrt_f16 exception raising
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
30
55
31
Peter Maydell (3):
56
include/hw/arm/armsse.h | 7 ++
32
fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
57
include/hw/arm/armv7m.h | 4 +
33
target/arm: Fix fp_status_f16 tininess before rounding
58
target/arm/cpu.h | 12 +++
34
tcg: Optionally log FPU state in TCG -d cpu logging
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(-)
35
73
36
Philippe Mathieu-Daudé (1):
37
sdcard: Correct CRC16 offset in sd_function_switch()
38
39
Richard Henderson (7):
40
target/arm: Implement FMOV (general) for fp16
41
target/arm: Early exit after unallocated_encoding in disas_fp_int_conv
42
target/arm: Implement FCVT (scalar, integer) for fp16
43
target/arm: Implement FCVT (scalar, fixed-point) for fp16
44
target/arm: Introduce and use read_fp_hreg
45
target/arm: Implement FP data-processing (2 source) for fp16
46
target/arm: Implement FP data-processing (3 source) for fp16
47
48
include/qemu/log.h | 1 +
49
target/arm/helper-a64.h | 2 +
50
target/arm/helper.h | 6 +
51
accel/tcg/cpu-exec.c | 9 +-
52
fpu/softfloat.c | 6 +-
53
hw/sd/sd.c | 2 +-
54
target/arm/cpu.c | 2 +
55
target/arm/helper-a64.c | 10 ++
56
target/arm/helper.c | 38 +++-
57
target/arm/translate-a64.c | 421 ++++++++++++++++++++++++++++++++++++++-------
58
util/log.c | 2 +
59
11 files changed, 428 insertions(+), 71 deletions(-)
60
diff view generated by jsdifflib
New 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.
1
8
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
1
From: Alex Bennée <alex.bennee@linaro.org>
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.
2
5
3
These were missed out from the rest of the half-precision work.
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.)
4
9
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
11
[rth: Fix erroneous check vs type]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
14
---
15
target/arm/translate-a64.c | 31 +++++++++++++++++++++++++------
15
hw/arm/boot.c | 23 +++++++++++++++++++++++
16
1 file changed, 25 insertions(+), 6 deletions(-)
16
1 file changed, 23 insertions(+)
17
17
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
20
--- a/hw/arm/boot.c
21
+++ b/target/arm/translate-a64.c
21
+++ b/hw/arm/boot.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
23
unsigned int mos, type, rm, cond, rn, rd;
23
error_report("could not load kernel '%s'", info->kernel_filename);
24
TCGv_i64 t_true, t_false, t_zero;
24
exit(1);
25
DisasCompare64 c;
25
}
26
+ TCGMemOp sz;
26
+
27
27
+ if (kernel_size > info->ram_size) {
28
mos = extract32(insn, 29, 3);
28
+ error_report("kernel '%s' is too large to fit in RAM "
29
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
29
+ "(kernel size %d, RAM size %" PRId64 ")",
30
+ type = extract32(insn, 22, 2);
30
+ info->kernel_filename, kernel_size, info->ram_size);
31
rm = extract32(insn, 16, 5);
31
+ exit(1);
32
cond = extract32(insn, 12, 4);
33
rn = extract32(insn, 5, 5);
34
rd = extract32(insn, 0, 5);
35
36
- if (mos || type > 1) {
37
+ if (mos) {
38
+ unallocated_encoding(s);
39
+ return;
40
+ }
32
+ }
41
+
33
+
42
+ switch (type) {
34
info->entry = entry;
43
+ case 0:
35
if (is_linux) {
44
+ sz = MO_32;
36
uint32_t fixupcontext[FIXUP_MAX];
45
+ break;
37
46
+ case 1:
38
if (info->initrd_filename) {
47
+ sz = MO_64;
39
+
48
+ break;
40
+ if (info->initrd_start >= ram_end) {
49
+ case 3:
41
+ error_report("not enough space after kernel to load initrd");
50
+ sz = MO_16;
42
+ exit(1);
51
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
43
+ }
52
+ break;
44
+
53
+ }
45
initrd_size = load_ramdisk_as(info->initrd_filename,
54
+ /* fallthru */
46
info->initrd_start,
55
+ default:
47
ram_end - info->initrd_start, as);
56
unallocated_encoding(s);
48
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
57
return;
49
info->initrd_filename);
58
}
50
exit(1);
59
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
51
}
60
return;
52
+ if (info->initrd_start + initrd_size > info->ram_size) {
61
}
53
+ error_report("could not load initrd '%s': "
62
54
+ "too big to fit into RAM after the kernel",
63
- /* Zero extend sreg inputs to 64 bits now. */
55
+ info->initrd_filename);
64
+ /* Zero extend sreg & hreg inputs to 64 bits now. */
56
+ }
65
t_true = tcg_temp_new_i64();
57
} else {
66
t_false = tcg_temp_new_i64();
58
initrd_size = 0;
67
- read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32);
59
}
68
- read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32);
60
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
69
+ read_vec_element(s, t_true, rn, 0, sz);
61
/* Place the DTB after the initrd in memory with alignment. */
70
+ read_vec_element(s, t_false, rm, 0, sz);
62
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
71
63
align);
72
a64_test_cc(&c, cond);
64
+ if (info->dtb_start >= ram_end) {
73
t_zero = tcg_const_i64(0);
65
+ error_report("Not enough space for DTB after kernel/initrd");
74
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
66
+ exit(1);
75
tcg_temp_free_i64(t_false);
67
+ }
76
a64_free_cc(&c);
68
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
77
69
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
78
- /* Note that sregs write back zeros to the high bits,
70
} else {
79
+ /* Note that sregs & hregs write back zeros to the high bits,
80
and we've already done the zero-extension. */
81
write_fp_dreg(s, rd, t_true);
82
tcg_temp_free_i64(t_true);
83
--
71
--
84
2.17.0
72
2.20.1
85
73
86
74
diff view generated by jsdifflib
New 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).
1
5
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
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
2
8
3
Cc: qemu-stable@nongnu.org
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>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Tested-by: Mark Rutland <mark.rutland@arm.com>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20190516144733.32399-5-peter.maydell@linaro.org
7
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
target/arm/translate-a64.c | 17 +++++++++++++++--
20
hw/arm/boot.c | 17 +++++++++++++++--
11
1 file changed, 15 insertions(+), 2 deletions(-)
21
1 file changed, 15 insertions(+), 2 deletions(-)
12
22
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
25
--- a/hw/arm/boot.c
16
+++ b/target/arm/translate-a64.c
26
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
27
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
18
bool sf = extract32(insn, 31, 1);
28
hwaddr *entry, AddressSpace *as)
19
bool itof;
29
{
20
30
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
21
- if (sbit || (type > 1)
31
+ uint64_t kernel_size = 0;
22
- || (!sf && scale < 32)) {
32
uint8_t *buffer;
23
+ if (sbit || (!sf && scale < 32)) {
33
int size;
24
+ unallocated_encoding(s);
34
25
+ return;
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;
26
+ }
58
+ }
27
+
59
+
28
+ switch (type) {
60
*entry = mem_base + kernel_load_offset;
29
+ case 0: /* float32 */
61
rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
30
+ case 1: /* float64 */
62
31
+ break;
63
g_free(buffer);
32
+ case 3: /* float16 */
64
33
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
65
- return size;
34
+ break;
66
+ return kernel_size;
35
+ }
67
}
36
+ /* fallthru */
68
37
+ default:
69
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
38
unallocated_encoding(s);
39
return;
40
}
41
--
70
--
42
2.17.0
71
2.20.1
43
72
44
73
diff view generated by jsdifflib
New patch
1
1
Allow VFP and neon to be disabled via a CPU property. As with
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
6
The primary motivation here is to be able to optionally
7
create Cortex-M33 CPUs with no FPU, but we provide switches
8
for both VFP and Neon because the two interact:
9
* AArch64 can't have one without the other
10
* Some ID register fields only change if both are disabled
11
12
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
---
17
target/arm/cpu.h | 4 ++
18
target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++--
19
2 files changed, 148 insertions(+), 6 deletions(-)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
bool has_el3;
27
/* CPU has PMU (Performance Monitor Unit) */
28
bool has_pmu;
29
+ /* CPU has VFP */
30
+ bool has_vfp;
31
+ /* CPU has Neon */
32
+ bool has_neon;
33
34
/* CPU has memory protection unit */
35
bool has_mpu;
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_cfgend_property =
41
static Property arm_cpu_has_pmu_property =
42
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
43
44
+static Property arm_cpu_has_vfp_property =
45
+ DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
46
+
47
+static Property arm_cpu_has_neon_property =
48
+ DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
49
+
50
static Property arm_cpu_has_mpu_property =
51
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
52
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
54
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
55
set_feature(&cpu->env, ARM_FEATURE_PMSA);
56
}
57
+ /* Similarly for the VFP feature bits */
58
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
59
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
60
+ }
61
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
62
+ set_feature(&cpu->env, ARM_FEATURE_VFP);
63
+ }
64
65
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
66
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
67
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
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
--
226
2.20.1
227
228
diff view generated by jsdifflib
1
In commit d81ce0ef2c4f105 we added an extra float_status field
1
Allow the DSP extension to be disabled via a CPU property for
2
fp_status_fp16 for Arm, but forgot to initialize it correctly
2
M-profile CPUs. (A and R-profile CPUs don't have this extension
3
by setting it to float_tininess_before_rounding. This currently
3
as a defined separate optional architecture extension, so
4
will only cause problems for the new V8_FP16 feature, since the
4
they don't need the property.)
5
float-to-float conversion code doesn't use it yet. The effect
6
would be that we failed to set the Underflow IEEE exception flag
7
in all the cases where we should.
8
5
9
Add the missing initialization.
6
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
---
11
target/arm/cpu.h | 2 ++
12
target/arm/cpu.c | 29 +++++++++++++++++++++++++++++
13
2 files changed, 31 insertions(+)
10
14
11
Fixes: d81ce0ef2c4f105
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
Cc: qemu-stable@nongnu.org
16
index XXXXXXX..XXXXXXX 100644
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
--- a/target/arm/cpu.h
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
+++ b/target/arm/cpu.h
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
16
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
20
bool has_vfp;
17
---
21
/* CPU has Neon */
18
target/arm/cpu.c | 2 ++
22
bool has_neon;
19
1 file changed, 2 insertions(+)
23
+ /* CPU has M-profile DSP extension */
20
24
+ bool has_dsp;
25
26
/* CPU has memory protection unit */
27
bool has_mpu;
21
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.c
30
--- a/target/arm/cpu.c
24
+++ b/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
32
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_vfp_property =
26
&env->vfp.fp_status);
33
static Property arm_cpu_has_neon_property =
27
set_float_detect_tininess(float_tininess_before_rounding,
34
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
28
&env->vfp.standard_fp_status);
35
29
+ set_float_detect_tininess(float_tininess_before_rounding,
36
+static Property arm_cpu_has_dsp_property =
30
+ &env->vfp.fp_status_f16);
37
+ DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
31
#ifndef CONFIG_USER_ONLY
38
+
32
if (kvm_enabled()) {
39
static Property arm_cpu_has_mpu_property =
33
kvm_arm_reset_vcpu(cpu);
40
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
41
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
43
}
44
}
45
46
+ if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
47
+ arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
48
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property,
49
+ &error_abort);
50
+ }
51
+
52
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
54
&error_abort);
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
56
cpu->isar.mvfr0 = u;
57
}
58
59
+ if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
60
+ uint32_t u;
61
+
62
+ unset_feature(env, ARM_FEATURE_THUMB_DSP);
63
+
64
+ u = cpu->isar.id_isar1;
65
+ u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
66
+ cpu->isar.id_isar1 = u;
67
+
68
+ u = cpu->isar.id_isar2;
69
+ u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
70
+ u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
71
+ cpu->isar.id_isar2 = u;
72
+
73
+ u = cpu->isar.id_isar3;
74
+ u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
75
+ u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
76
+ cpu->isar.id_isar3 = u;
77
+ }
78
+
79
/* Some features automatically imply others: */
80
if (arm_feature(env, ARM_FEATURE_V8)) {
81
if (arm_feature(env, ARM_FEATURE_M)) {
34
--
82
--
35
2.17.0
83
2.20.1
36
84
37
85
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Create "vfp" and "dsp" properties on the armv7m container object
2
which will be forwarded to its CPU object, so that SoCs can
3
configure whether the CPU has these features.
2
4
3
Adding the fp16 moves to/from general registers.
5
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
---
10
include/hw/arm/armv7m.h | 4 ++++
11
hw/arm/armv7m.c | 18 ++++++++++++++++++
12
2 files changed, 22 insertions(+)
4
13
5
Cc: qemu-stable@nongnu.org
14
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 21 +++++++++++++++++++++
13
1 file changed, 21 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
16
--- a/include/hw/arm/armv7m.h
18
+++ b/target/arm/translate-a64.c
17
+++ b/include/hw/arm/armv7m.h
19
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
19
* devices will be automatically layered on top of this view.)
21
clear_vec_high(s, true, rd);
20
* + Property "idau": IDAU interface (forwarded to CPU object)
22
break;
21
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
23
+ case 3:
22
+ * + Property "vfp": enable VFP (forwarded to CPU object)
24
+ /* 16 bit */
23
+ * + Property "dsp": enable DSP (forwarded to CPU object)
25
+ tmp = tcg_temp_new_i64();
24
* + Property "enable-bitband": expose bitbanded IO
26
+ tcg_gen_ext16u_i64(tmp, tcg_rn);
25
*/
27
+ write_fp_dreg(s, rd, tmp);
26
typedef struct ARMv7MState {
28
+ tcg_temp_free_i64(tmp);
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
29
+ break;
28
uint32_t init_svtor;
30
+ default:
29
bool enable_bitband;
31
+ g_assert_not_reached();
30
bool start_powered_off;
32
}
31
+ bool vfp;
33
} else {
32
+ bool dsp;
34
TCGv_i64 tcg_rd = cpu_reg(s, rd);
33
} ARMv7MState;
35
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
34
36
/* 64 bits from top half */
35
#endif
37
tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
36
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
38
break;
37
index XXXXXXX..XXXXXXX 100644
39
+ case 3:
38
--- a/hw/arm/armv7m.c
40
+ /* 16 bit */
39
+++ b/hw/arm/armv7m.c
41
+ tcg_gen_ld16u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_16));
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
42
+ break;
41
return;
43
+ default:
44
+ g_assert_not_reached();
45
}
42
}
46
}
43
}
47
}
44
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
48
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
45
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
49
case 0xa: /* 64 bit */
46
+ "vfp", &err);
50
case 0xd: /* 64 bit to top half of quad */
47
+ if (err != NULL) {
51
break;
48
+ error_propagate(errp, err);
52
+ case 0x6: /* 16-bit float, 32-bit int */
49
+ return;
53
+ case 0xe: /* 16-bit float, 64-bit int */
50
+ }
54
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
51
+ }
55
+ break;
52
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
56
+ }
53
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
57
+ /* fallthru */
54
+ "dsp", &err);
58
default:
55
+ if (err != NULL) {
59
/* all other sf/type/rmode combinations are invalid */
56
+ error_propagate(errp, err);
60
unallocated_encoding(s);
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
};
71
61
--
72
--
62
2.17.0
73
2.20.1
63
74
64
75
diff view generated by jsdifflib
New patch
1
The SSE-200 hardware has configurable integration settings which
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)
1
7
8
Similarly, the IoTKit has settings for its single CPU:
9
* CPU0_FPU (default 1)
10
* CPU0_DSP (default 1)
11
12
Of our four boards that use either the IoTKit or the SSE-200:
13
* mps2-an505, mps2-an521 and musca-a use the default settings
14
* musca-b1 enables FPU and DSP on both CPUs
15
16
Currently QEMU models all these boards using CPUs with
17
both FPU and DSP enabled. This means that we are incorrect
18
for mps2-an521 and musca-a, which should not have FPU or DSP
19
on CPU0.
20
21
Create QOM properties on the ARMSSE devices corresponding to the
22
default h/w integration settings, and make the Musca-B1 board
23
enable FPU and DSP on both CPUs. This fixes the mps2-an521
24
and musca-a behaviour, and leaves the musca-b1 and mps2-an505
25
behaviour unchanged.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
38
--- a/include/hw/arm/armsse.h
39
+++ b/include/hw/arm/armsse.h
40
@@ -XXX,XX +XXX,XX @@
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
};
97
98
static const ARMSSEInfo armsse_variants[] = {
99
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
100
.has_cachectrl = false,
101
.has_cpusecctrl = false,
102
.has_cpuid = false,
103
+ .props = iotkit_properties,
104
},
105
{
106
.name = TYPE_SSE200,
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
};
114
115
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
116
return;
117
}
118
}
119
+ if (!s->cpu_fpu[i]) {
120
+ object_property_set_bool(cpuobj, false, "vfp", &err);
121
+ if (err) {
122
+ error_propagate(errp, err);
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
};
139
140
-static Property armsse_properties[] = {
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
--
190
2.20.1
191
192
diff view generated by jsdifflib
New 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.
1
4
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
New 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.
1
7
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
1
From: Richard Henderson <richard.henderson@linaro.org>
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).
2
4
3
We missed all of the scalar fp16 binary operations.
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(-)
4
15
5
Cc: qemu-stable@nongnu.org
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
index XXXXXXX..XXXXXXX 100644
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
--- a/target/arm/translate-a64.h
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
19
+++ b/target/arm/translate-a64.h
9
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
20
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
TCGv_ptr get_fpstatus_ptr(bool);
11
---
22
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
12
target/arm/translate-a64.c | 65 ++++++++++++++++++++++++++++++++++++++
23
unsigned int imms, unsigned int immr);
13
1 file changed, 65 insertions(+)
24
-uint64_t vfp_expand_imm(int size, uint8_t imm8);
14
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];
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
48
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
50
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
20
tcg_temp_free_i64(tcg_res);
51
}
21
}
52
}
22
53
23
+/* Floating-point data-processing (2 source) - half precision */
54
-/* The imm8 encodes the sign bit, enough bits to represent an exponent in
24
+static void handle_fp_2src_half(DisasContext *s, int opcode,
55
- * the range 01....1xx to 10....0xx, and the most significant 4 bits of
25
+ int rd, int rn, int rm)
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)
26
+{
103
+{
27
+ TCGv_i32 tcg_op1;
104
+ uint64_t imm;
28
+ TCGv_i32 tcg_op2;
29
+ TCGv_i32 tcg_res;
30
+ TCGv_ptr fpst;
31
+
105
+
32
+ tcg_res = tcg_temp_new_i32();
106
+ switch (size) {
33
+ fpst = get_fpstatus_ptr(true);
107
+ case MO_64:
34
+ tcg_op1 = read_fp_hreg(s, rn);
108
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
35
+ tcg_op2 = read_fp_hreg(s, rm);
109
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
36
+
110
+ extract32(imm8, 0, 6);
37
+ switch (opcode) {
111
+ imm <<= 48;
38
+ case 0x0: /* FMUL */
39
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
40
+ break;
112
+ break;
41
+ case 0x1: /* FDIV */
113
+ case MO_32:
42
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
114
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
115
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
116
+ (extract32(imm8, 0, 6) << 3);
117
+ imm <<= 16;
43
+ break;
118
+ break;
44
+ case 0x2: /* FADD */
119
+ case MO_16:
45
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
120
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
46
+ break;
121
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
47
+ case 0x3: /* FSUB */
122
+ (extract32(imm8, 0, 6) << 6);
48
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
49
+ break;
50
+ case 0x4: /* FMAX */
51
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
52
+ break;
53
+ case 0x5: /* FMIN */
54
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
55
+ break;
56
+ case 0x6: /* FMAXNM */
57
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
58
+ break;
59
+ case 0x7: /* FMINNM */
60
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
61
+ break;
62
+ case 0x8: /* FNMUL */
63
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
64
+ tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
65
+ break;
123
+ break;
66
+ default:
124
+ default:
67
+ g_assert_not_reached();
125
+ g_assert_not_reached();
68
+ }
126
+ }
69
+
127
+ return imm;
70
+ write_fp_sreg(s, rd, tcg_res);
71
+
72
+ tcg_temp_free_ptr(fpst);
73
+ tcg_temp_free_i32(tcg_op1);
74
+ tcg_temp_free_i32(tcg_op2);
75
+ tcg_temp_free_i32(tcg_res);
76
+}
128
+}
77
+
129
+
78
/* Floating point data-processing (2 source)
130
/*
79
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
131
* Return the offset of a 16-bit half of the specified VFP single-precision
80
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
132
* register. If top is true, returns the top 16 bits; otherwise the bottom
81
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
82
}
83
handle_fp_2src_double(s, opcode, rd, rn, rm);
84
break;
85
+ case 3:
86
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
87
+ unallocated_encoding(s);
88
+ return;
89
+ }
90
+ if (!fp_access_check(s)) {
91
+ return;
92
+ }
93
+ handle_fp_2src_half(s, opcode, rd, rn, rm);
94
+ break;
95
default:
96
unallocated_encoding(s);
97
}
98
--
133
--
99
2.17.0
134
2.20.1
100
135
101
136
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
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.
2
4
3
All the hard work is already done by vfp_expand_imm, we just need to
5
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
make sure we pick up the correct size.
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(-)
5
14
6
Cc: qemu-stable@nongnu.org
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180512003217.9105-11-richard.henderson@linaro.org
12
[rth: Merge unallocated_encoding check with TCGMemOp conversion.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/translate-a64.c | 20 +++++++++++++++++---
17
1 file changed, 17 insertions(+), 3 deletions(-)
18
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-vfp.inc.c
22
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-vfp.inc.c
23
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
24
{
20
uint32_t delta_d = 0;
25
int rd = extract32(insn, 0, 5);
21
int veclen = s->vec_len;
26
int imm8 = extract32(insn, 13, 8);
22
TCGv_i32 fd;
27
- int is_double = extract32(insn, 22, 2);
23
- uint32_t n, i, vd;
28
+ int type = extract32(insn, 22, 2);
24
+ uint32_t vd;
29
uint64_t imm;
25
30
TCGv_i64 tcg_res;
26
vd = a->vd;
31
+ TCGMemOp sz;
27
32
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
33
- if (is_double > 1) {
29
}
34
+ switch (type) {
35
+ case 0:
36
+ sz = MO_32;
37
+ break;
38
+ case 1:
39
+ sz = MO_64;
40
+ break;
41
+ case 3:
42
+ sz = MO_16;
43
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
44
+ break;
45
+ }
46
+ /* fallthru */
47
+ default:
48
unallocated_encoding(s);
49
return;
50
}
30
}
51
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
31
52
return;
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
}
53
}
58
}
54
59
55
- imm = vfp_expand_imm(MO_32 + is_double, imm8);
60
- n = (a->imm4h << 28) & 0x80000000;
56
+ imm = vfp_expand_imm(sz, imm8);
61
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
57
62
- if (i & 0x40) {
58
tcg_res = tcg_const_i64(imm);
63
- i |= 0x3f80;
59
write_fp_dreg(s, rd, tcg_res);
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
60
--
103
--
61
2.17.0
104
2.20.1
62
105
63
106
diff view generated by jsdifflib
New 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.
1
8
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
New patch
1
Switch NEON_2RM_VABS_F away from using cpu_F0s.
1
2
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
1
Usually the logging of the CPU state produced by -d cpu is sufficient
1
Switch NEON_2RM_VRINT* away from using cpu_F0s.
2
to diagnose problems, but sometimes you want to see the state of
3
the floating point registers as well. We don't want to enable that
4
by default as it adds a lot of extra data to the log; instead,
5
allow it to be optionally enabled via -d fpu.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180510130024.31678-1-peter.maydell@linaro.org
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-6-peter.maydell@linaro.org
10
---
7
---
11
include/qemu/log.h | 1 +
8
target/arm/translate.c | 8 +++-----
12
accel/tcg/cpu-exec.c | 9 ++++++---
9
1 file changed, 3 insertions(+), 5 deletions(-)
13
util/log.c | 2 ++
14
3 files changed, 9 insertions(+), 3 deletions(-)
15
10
16
diff --git a/include/qemu/log.h b/include/qemu/log.h
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/include/qemu/log.h
13
--- a/target/arm/translate.c
19
+++ b/include/qemu/log.h
14
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static inline bool qemu_log_separate(void)
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
21
#define CPU_LOG_PAGE (1 << 14)
16
* what we are asking here is "does the code for this case in
22
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
17
* the Neon for-each-pass loop use cpu_F0s?".
23
#define CPU_LOG_TB_OP_IND (1 << 16)
18
*/
24
+#define CPU_LOG_TB_FPU (1 << 17)
19
- return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
25
20
- op == NEON_2RM_VRINTM ||
26
/* Lock output for a series of related logs. Since this is not needed
21
- (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
27
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
22
+ return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
28
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
23
op >= NEON_2RM_VRECPE_F);
29
index XXXXXXX..XXXXXXX 100644
24
}
30
--- a/accel/tcg/cpu-exec.c
25
31
+++ b/accel/tcg/cpu-exec.c
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
27
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
33
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
28
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
34
&& qemu_log_in_addr_range(itb->pc)) {
29
cpu_env);
35
qemu_log_lock();
30
- gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
36
+ int flags = 0;
31
+ gen_helper_rints(tmp, tmp, fpstatus);
37
+ if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
32
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
38
+ flags |= CPU_DUMP_FPU;
33
cpu_env);
39
+ }
34
tcg_temp_free_ptr(fpstatus);
40
#if defined(TARGET_I386)
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
- log_cpu_state(cpu, CPU_DUMP_CCOP);
36
case NEON_2RM_VRINTX:
42
-#else
37
{
43
- log_cpu_state(cpu, 0);
38
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
44
+ flags |= CPU_DUMP_CCOP;
39
- gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
45
#endif
40
+ gen_helper_rints_exact(tmp, tmp, fpstatus);
46
+ log_cpu_state(cpu, flags);
41
tcg_temp_free_ptr(fpstatus);
47
qemu_log_unlock();
42
break;
48
}
43
}
49
#endif /* DEBUG_DISAS */
50
diff --git a/util/log.c b/util/log.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/util/log.c
53
+++ b/util/log.c
54
@@ -XXX,XX +XXX,XX @@ const QEMULogItem qemu_log_items[] = {
55
"show trace before each executed TB (lots of logs)" },
56
{ CPU_LOG_TB_CPU, "cpu",
57
"show CPU registers before entering a TB (lots of logs)" },
58
+ { CPU_LOG_TB_FPU, "fpu",
59
+ "include FPU registers in the 'cpu' logging" },
60
{ CPU_LOG_MMU, "mmu",
61
"log MMU-related activities" },
62
{ CPU_LOG_PCALL, "pcall",
63
--
44
--
64
2.17.0
45
2.20.1
65
46
66
47
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Stop using cpu_F0s for the NEON_2RM_VCVT[ANPM][US] ops.
2
2
3
Per the Physical Layer Simplified Spec. "4.3.10.4 Switch Function Status":
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-7-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 7 +++----
9
1 file changed, 3 insertions(+), 4 deletions(-)
4
10
5
The block length is predefined to 512 bits
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
6
7
and "4.10.2 SD Status":
8
9
The SD Status contains status bits that are related to the SD Memory Card
10
proprietary features and may be used for future application-specific usage.
11
The size of the SD Status is one data block of 512 bit. The content of this
12
register is transmitted to the Host over the DAT bus along with a 16-bit CRC.
13
14
Thus the 16-bit CRC goes at offset 64.
15
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20180509060104.4458-3-f4bug@amsat.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/sd/sd.c | 2 +-
22
1 file changed, 1 insertion(+), 1 deletion(-)
23
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
25
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
13
--- a/target/arm/translate.c
27
+++ b/hw/sd/sd.c
14
+++ b/target/arm/translate.c
28
@@ -XXX,XX +XXX,XX @@ static void sd_function_switch(SDState *sd, uint32_t arg)
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
29
sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
16
* what we are asking here is "does the code for this case in
30
}
17
* the Neon for-each-pass loop use cpu_F0s?".
31
memset(&sd->data[17], 0, 47);
18
*/
32
- stw_be_p(sd->data + 65, sd_crc16(sd->data, 64));
19
- return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
33
+ stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
20
- op >= NEON_2RM_VRECPE_F);
21
+ return op >= NEON_2RM_VRECPE_F;
34
}
22
}
35
23
36
static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
24
static bool neon_2rm_is_v8_op(int op)
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
37
--
38
--
38
2.17.0
39
2.20.1
39
40
40
41
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F.
2
2
3
We are meant to explicitly pass fpst, not cpu_env.
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(-)
4
10
5
Cc: qemu-stable@nongnu.org
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180512003217.9105-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-a64.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
13
--- a/target/arm/translate.c
19
+++ b/target/arm/translate-a64.c
14
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
21
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
16
* what we are asking here is "does the code for this case in
22
break;
17
* the Neon for-each-pass loop use cpu_F0s?".
23
case 0x3: /* FSQRT */
18
*/
24
- gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
19
- return op >= NEON_2RM_VRECPE_F;
25
+ fpst = get_fpstatus_ptr(true);
20
+ return op >= NEON_2RM_VCVT_FS;
26
+ gen_helper_sqrt_f16(tcg_res, tcg_op, fpst);
21
}
27
break;
22
28
case 0x8: /* FRINTN */
23
static bool neon_2rm_is_v8_op(int op)
29
case 0x9: /* FRINTP */
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
}
30
--
41
--
31
2.17.0
42
2.20.1
32
43
33
44
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
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.
2
4
3
These where missed out from the rest of the half-precision work.
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(-)
4
12
5
Cc: qemu-stable@nongnu.org
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-9-richard.henderson@linaro.org
11
[rth: Diagnose lack of FP16 before fp_access_check]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/helper-a64.h | 2 +
16
target/arm/helper-a64.c | 10 +++++
17
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++--------
18
3 files changed, 83 insertions(+), 17 deletions(-)
19
20
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.h
15
--- a/target/arm/translate.c
23
+++ b/target/arm/helper-a64.h
16
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
25
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
18
return statusptr;
26
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
27
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
28
+DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
29
+DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
30
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
31
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
32
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
33
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/helper-a64.c
36
+++ b/target/arm/helper-a64.c
37
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
38
return flags;
39
}
19
}
40
20
41
+uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
21
-#define VFP_GEN_ITOF(name) \
42
+{
22
-static inline void gen_vfp_##name(int dp, int neon) \
43
+ return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
23
-{ \
44
+}
24
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
45
+
25
- if (dp) { \
46
+uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
26
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
47
+{
27
- } else { \
48
+ return float_rel_to_flags(float16_compare(x, y, fp_status));
28
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
49
+}
29
- } \
50
+
30
- tcg_temp_free_ptr(statusptr); \
51
uint64_t HELPER(vfp_cmps_a64)(float32 x, float32 y, void *fp_status)
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)
52
{
72
{
53
return float_rel_to_flags(float32_compare_quiet(x, y, fp_status));
73
/* Return true if this neon 2reg-misc op is ARMv8 and up */
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
55
index XXXXXXX..XXXXXXX 100644
75
default:
56
--- a/target/arm/translate-a64.c
76
elementwise:
57
+++ b/target/arm/translate-a64.c
77
for (pass = 0; pass < (q ? 4 : 2); pass++) {
58
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
78
- if (neon_2rm_is_float_op(op)) {
59
}
79
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
60
}
80
- neon_reg_offset(rm, pass));
61
81
- tmp = NULL;
62
-static void handle_fp_compare(DisasContext *s, bool is_double,
82
- } else {
63
+static void handle_fp_compare(DisasContext *s, int size,
83
- tmp = neon_load_reg(rm, pass);
64
unsigned int rn, unsigned int rm,
84
- }
65
bool cmp_with_zero, bool signal_all_nans)
85
+ tmp = neon_load_reg(rm, pass);
66
{
86
switch (op) {
67
TCGv_i64 tcg_flags = tcg_temp_new_i64();
87
case NEON_2RM_VREV32:
68
- TCGv_ptr fpst = get_fpstatus_ptr(false);
88
switch (size) {
69
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
70
90
break;
71
- if (is_double) {
91
}
72
+ if (size == MO_64) {
92
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
73
TCGv_i64 tcg_vn, tcg_vm;
93
- gen_vfp_sito(0, 1);
74
94
+ {
75
tcg_vn = read_fp_dreg(s, rn);
95
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
76
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
96
+ gen_helper_vfp_sitos(tmp, tmp, fpstatus);
77
tcg_temp_free_i64(tcg_vn);
97
+ tcg_temp_free_ptr(fpstatus);
78
tcg_temp_free_i64(tcg_vm);
98
break;
79
} else {
99
+ }
80
- TCGv_i32 tcg_vn, tcg_vm;
100
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
81
+ TCGv_i32 tcg_vn = tcg_temp_new_i32();
101
- gen_vfp_uito(0, 1);
82
+ TCGv_i32 tcg_vm = tcg_temp_new_i32();
102
+ {
83
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
84
- tcg_vn = read_fp_sreg(s, rn);
104
+ gen_helper_vfp_uitos(tmp, tmp, fpstatus);
85
+ read_vec_element_i32(s, tcg_vn, rn, 0, size);
105
+ tcg_temp_free_ptr(fpstatus);
86
if (cmp_with_zero) {
106
break;
87
- tcg_vm = tcg_const_i32(0);
107
+ }
88
+ tcg_gen_movi_i32(tcg_vm, 0);
108
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
89
} else {
109
- gen_vfp_tosiz(0, 1);
90
- tcg_vm = read_fp_sreg(s, rm);
110
+ {
91
+ read_vec_element_i32(s, tcg_vm, rm, 0, size);
111
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
92
}
112
+ gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
93
- if (signal_all_nans) {
113
+ tcg_temp_free_ptr(fpstatus);
94
- gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
114
break;
95
- } else {
115
+ }
96
- gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
116
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
97
+
117
- gen_vfp_touiz(0, 1);
98
+ switch (size) {
118
+ {
99
+ case MO_32:
119
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
100
+ if (signal_all_nans) {
120
+ gen_helper_vfp_touizs(tmp, tmp, fpstatus);
101
+ gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
121
+ tcg_temp_free_ptr(fpstatus);
102
+ } else {
122
break;
103
+ gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
123
+ }
104
+ }
124
default:
105
+ break;
125
/* Reserved op values were caught by the
106
+ case MO_16:
126
* neon_2rm_sizes[] check earlier.
107
+ if (signal_all_nans) {
127
*/
108
+ gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
128
abort();
109
+ } else {
129
}
110
+ gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
130
- if (neon_2rm_is_float_op(op)) {
111
+ }
131
- tcg_gen_st_f32(cpu_F0s, cpu_env,
112
+ break;
132
- neon_reg_offset(rd, pass));
113
+ default:
133
- } else {
114
+ g_assert_not_reached();
134
- neon_store_reg(rd, pass, tmp);
115
}
135
- }
116
+
136
+ neon_store_reg(rd, pass, tmp);
117
tcg_temp_free_i32(tcg_vn);
137
}
118
tcg_temp_free_i32(tcg_vm);
138
break;
119
}
139
}
120
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
121
static void disas_fp_compare(DisasContext *s, uint32_t insn)
122
{
123
unsigned int mos, type, rm, op, rn, opc, op2r;
124
+ int size;
125
126
mos = extract32(insn, 29, 3);
127
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
128
+ type = extract32(insn, 22, 2);
129
rm = extract32(insn, 16, 5);
130
op = extract32(insn, 14, 2);
131
rn = extract32(insn, 5, 5);
132
opc = extract32(insn, 3, 2);
133
op2r = extract32(insn, 0, 3);
134
135
- if (mos || op || op2r || type > 1) {
136
+ if (mos || op || op2r) {
137
+ unallocated_encoding(s);
138
+ return;
139
+ }
140
+
141
+ switch (type) {
142
+ case 0:
143
+ size = MO_32;
144
+ break;
145
+ case 1:
146
+ size = MO_64;
147
+ break;
148
+ case 3:
149
+ size = MO_16;
150
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
151
+ break;
152
+ }
153
+ /* fallthru */
154
+ default:
155
unallocated_encoding(s);
156
return;
157
}
158
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
159
return;
160
}
161
162
- handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
163
+ handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2);
164
}
165
166
/* Floating point conditional compare
167
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
168
unsigned int mos, type, rm, cond, rn, op, nzcv;
169
TCGv_i64 tcg_flags;
170
TCGLabel *label_continue = NULL;
171
+ int size;
172
173
mos = extract32(insn, 29, 3);
174
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
175
+ type = extract32(insn, 22, 2);
176
rm = extract32(insn, 16, 5);
177
cond = extract32(insn, 12, 4);
178
rn = extract32(insn, 5, 5);
179
op = extract32(insn, 4, 1);
180
nzcv = extract32(insn, 0, 4);
181
182
- if (mos || type > 1) {
183
+ if (mos) {
184
+ unallocated_encoding(s);
185
+ return;
186
+ }
187
+
188
+ switch (type) {
189
+ case 0:
190
+ size = MO_32;
191
+ break;
192
+ case 1:
193
+ size = MO_64;
194
+ break;
195
+ case 3:
196
+ size = MO_16;
197
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
198
+ break;
199
+ }
200
+ /* fallthru */
201
+ default:
202
unallocated_encoding(s);
203
return;
204
}
205
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
206
gen_set_label(label_match);
207
}
208
209
- handle_fp_compare(s, type, rn, rm, false, op);
210
+ handle_fp_compare(s, size, rn, rm, false, op);
211
212
if (cond < 0x0e) {
213
gen_set_label(label_continue);
214
--
140
--
215
2.17.0
141
2.20.1
216
142
217
143
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Stop using cpu_F0s in the Neon VCVT fixed-point operations.
2
2
3
No sense in emitting code after the exception.
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-10-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 62 +++++++++++++++++++-----------------------
9
1 file changed, 28 insertions(+), 34 deletions(-)
4
10
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
13
--- a/target/arm/translate.c
17
+++ b/target/arm/translate-a64.c
14
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
19
default:
16
/* Function prototypes for gen_ functions calling Neon helpers. */
20
/* all other sf/type/rmode combinations are invalid */
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
21
unallocated_encoding(s);
18
TCGv_i32, TCGv_i32);
22
- break;
19
+/* Function prototypes for gen_ functions for fix point conversions */
23
+ return;
20
+typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
24
}
21
25
22
/* initialize TCG globals. */
26
if (!fp_access_check(s)) {
23
void arm_translate_init(void)
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
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
}
27
--
107
--
28
2.17.0
108
2.20.1
29
109
30
110
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Remove some old constructs from NEON_2RM_VCVT_F16_F32 code:
2
* don't use cpu_F0s
3
* don't use tcg_gen_ld_f32
2
4
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-11-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate-a64.c | 30 ++++++++++++++----------------
10
target/arm/translate.c | 27 ++++++++++++---------------
11
1 file changed, 14 insertions(+), 16 deletions(-)
11
1 file changed, 12 insertions(+), 15 deletions(-)
12
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
18
return v;
18
return ret;
19
}
19
}
20
20
21
+static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
21
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
22
+{
22
#define tcg_gen_st_f32 tcg_gen_st_i32
23
+ TCGv_i32 v = tcg_temp_new_i32();
23
24
+
24
#define ARM_CP_RW_BIT (1 << 20)
25
+ tcg_gen_ld16u_i32(v, cpu_env, fp_reg_offset(s, reg, MO_16));
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
26
+ return v;
26
q || (rm & 1)) {
27
+}
27
return 1;
28
+
28
}
29
/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
29
- tmp = tcg_temp_new_i32();
30
* If SVE is not enabled, then there are only 128 bits in the vector.
30
- tmp2 = tcg_temp_new_i32();
31
*/
31
fpst = get_fpstatus_ptr(true);
32
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
32
ahp = get_ahp_flag();
33
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
33
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
34
{
34
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
35
TCGv_ptr fpst = NULL;
35
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
36
- TCGv_i32 tcg_op = tcg_temp_new_i32();
36
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
37
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
37
+ tmp = neon_load_reg(rm, 0);
38
TCGv_i32 tcg_res = tcg_temp_new_i32();
38
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
39
39
+ tmp2 = neon_load_reg(rm, 1);
40
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
40
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
41
-
41
tcg_gen_shli_i32(tmp2, tmp2, 16);
42
switch (opcode) {
42
tcg_gen_or_i32(tmp2, tmp2, tmp);
43
case 0x0: /* FMOV */
43
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
44
tcg_gen_mov_i32(tcg_res, tcg_op);
44
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
45
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
45
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
46
tcg_temp_free_i64(tcg_op2);
46
+ tcg_temp_free_i32(tmp);
47
tcg_temp_free_i64(tcg_res);
47
+ tmp = neon_load_reg(rm, 2);
48
} else {
48
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
49
- TCGv_i32 tcg_op1 = tcg_temp_new_i32();
49
+ tmp3 = neon_load_reg(rm, 3);
50
- TCGv_i32 tcg_op2 = tcg_temp_new_i32();
50
neon_store_reg(rd, 0, tmp2);
51
+ TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
51
- tmp2 = tcg_temp_new_i32();
52
+ TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
52
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
53
TCGv_i64 tcg_res = tcg_temp_new_i64();
53
- tcg_gen_shli_i32(tmp2, tmp2, 16);
54
54
- tcg_gen_or_i32(tmp2, tmp2, tmp);
55
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
55
- neon_store_reg(rd, 1, tmp2);
56
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
56
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
57
-
57
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
58
gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
58
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
59
gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
59
+ neon_store_reg(rd, 1, tmp3);
60
60
tcg_temp_free_i32(tmp);
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
61
tcg_temp_free_i32(ahp);
62
62
tcg_temp_free_ptr(fpst);
63
fpst = get_fpstatus_ptr(true);
64
65
- tcg_op1 = tcg_temp_new_i32();
66
- tcg_op2 = tcg_temp_new_i32();
67
+ tcg_op1 = read_fp_hreg(s, rn);
68
+ tcg_op2 = read_fp_hreg(s, rm);
69
tcg_res = tcg_temp_new_i32();
70
71
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
72
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
73
-
74
switch (fpopcode) {
75
case 0x03: /* FMULX */
76
gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
77
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
78
}
79
80
if (is_scalar) {
81
- TCGv_i32 tcg_op = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
83
TCGv_i32 tcg_res = tcg_temp_new_i32();
84
85
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
86
-
87
switch (fpop) {
88
case 0x1a: /* FCVTNS */
89
case 0x1b: /* FCVTMS */
90
--
63
--
91
2.17.0
64
2.20.1
92
65
93
66
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Remove some old constructns from NEON_2RM_VCVT_F16_F32 code:
2
* don't use CPU_F0s
3
* don't use tcg_gen_st_f32
2
4
3
Reported by Coverity (CID1390635). We ensure this for uint_to_float
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
later on so we might as well mirror that.
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
---
10
target/arm/translate.c | 26 +++++++++++---------------
11
1 file changed, 11 insertions(+), 15 deletions(-)
5
12
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat.c
15
--- a/target/arm/translate.c
17
+++ b/fpu/softfloat.c
16
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_UINT(64, 64)
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
19
18
return ret;
20
static FloatParts int_to_float(int64_t a, float_status *status)
19
}
21
{
20
22
- FloatParts r;
21
-#define tcg_gen_st_f32 tcg_gen_st_i32
23
+ FloatParts r = {};
22
-
24
if (a == 0) {
23
#define ARM_CP_RW_BIT (1 << 20)
25
r.cls = float_class_zero;
24
26
r.sign = false;
25
/* Include the VFP decoder */
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
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;
27
--
58
--
28
2.17.0
59
2.20.1
29
60
30
61
diff view generated by jsdifflib
1
In float-to-integer conversion, if the floating point input
1
Remove the now unused TCG globals cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d.
2
converts exactly to the largest or smallest integer that
3
fits in to the result type, this is not an overflow.
4
In this situation we were producing the correct result value,
5
but were incorrectly setting the Invalid flag.
6
For example for Arm A64, "FCVTAS w0, d0" on an input of
7
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.
8
2
9
Fix the boundary case to take the right half of the if()
3
cpu_M0 is still used by the iwmmxt code, and cpu_V0 and
10
statements.
4
cpu_V1 are used by both iwmmxt and Neon.
11
5
12
This fixes a regression from 2.11 introduced by the softfloat
13
refactoring.
14
15
Cc: qemu-stable@nongnu.org
16
Fixes: ab52f973a50
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-13-peter.maydell@linaro.org
20
---
10
---
21
fpu/softfloat.c | 4 ++--
11
target/arm/translate.c | 12 ++----------
22
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+), 10 deletions(-)
23
13
24
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat.c
16
--- a/target/arm/translate.c
27
+++ b/fpu/softfloat.c
17
+++ b/target/arm/translate.c
28
@@ -XXX,XX +XXX,XX @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
18
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
29
r = UINT64_MAX;
19
TCGv_i64 cpu_exclusive_addr;
30
}
20
TCGv_i64 cpu_exclusive_val;
31
if (p.sign) {
21
32
- if (r < -(uint64_t) min) {
22
-/* FIXME: These should be removed. */
33
+ if (r <= -(uint64_t) min) {
23
-static TCGv_i32 cpu_F0s, cpu_F1s;
34
return -r;
24
-static TCGv_i64 cpu_F0d, cpu_F1d;
35
} else {
25
-
36
s->float_exception_flags = orig_flags | float_flag_invalid;
26
#include "exec/gen-icount.h"
37
return min;
27
38
}
28
static const char * const regnames[] =
39
} else {
29
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
40
- if (r < max) {
30
dc->base.max_insns = MIN(dc->base.max_insns, bound);
41
+ if (r <= max) {
31
}
42
return r;
32
43
} else {
33
- cpu_F0s = tcg_temp_new_i32();
44
s->float_exception_flags = orig_flags | float_flag_invalid;
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
}
45
--
44
--
46
2.17.0
45
2.20.1
47
46
48
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In several places cut and paste errors meant we were using the wrong
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.
2
8
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20190614104457.24703-2-peter.maydell@linaro.org
9
---
12
---
10
target/arm/helper.h | 6 +++
13
target/arm/translate-vfp.inc.c | 28 ++++++++++++++--------------
11
target/arm/helper.c | 38 ++++++++++++++-
14
1 file changed, 14 insertions(+), 14 deletions(-)
12
target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++-------
13
3 files changed, 122 insertions(+), 18 deletions(-)
14
15
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
18
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/helper.h
19
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
20
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
21
return true;
21
DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
22
DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
23
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
24
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
25
+DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr)
26
+DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr)
27
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
28
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
29
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
31
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
32
DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
33
DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
34
+DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
35
+DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
36
37
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
38
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
44
#undef VFP_CONV_FIX_A64
45
46
/* Conversion to/from f16 can overflow to infinity before/after scaling.
47
- * Therefore we convert to f64 (which does not round), scale,
48
- * and then convert f64 to f16 (which may round).
49
+ * Therefore we convert to f64, scale, and then convert f64 to f16; or
50
+ * vice versa for conversion to integer.
51
+ *
52
+ * For 16- and 32-bit integers, the conversion to f64 never rounds.
53
+ * For 64-bit integers, any integer that would cause rounding will also
54
+ * overflow to f16 infinity, so there is no double rounding problem.
55
*/
56
57
static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
58
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
59
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
60
}
22
}
61
23
62
+float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
24
-static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_sp *a)
63
+{
25
+static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
64
+ return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
65
+}
66
+
67
+float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
68
+{
69
+ return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
70
+}
71
+
72
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
73
{
26
{
74
if (unlikely(float16_is_any_nan(f))) {
27
TCGv_i32 tmp;
75
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
28
76
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
30
return true;
77
}
31
}
78
32
79
+uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
33
-static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a)
80
+{
34
+static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
81
+ return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
82
+}
83
+
84
+uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
85
+{
86
+ return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
87
+}
88
+
89
+uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
90
+{
91
+ return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
92
+}
93
+
94
+uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
95
+{
96
+ return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
97
+}
98
+
99
/* Set the current fp rounding mode and return the old one.
100
* The argument is a softfloat float_round_ value.
101
*/
102
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-a64.c
105
+++ b/target/arm/translate-a64.c
106
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
107
bool itof, int rmode, int scale, int sf, int type)
108
{
35
{
109
bool is_signed = !(opcode & 1);
36
uint32_t offset;
110
- bool is_double = type;
37
TCGv_i32 addr;
111
TCGv_ptr tcg_fpstatus;
38
@@ -XXX,XX +XXX,XX @@ static void gen_VMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
112
- TCGv_i32 tcg_shift;
39
tcg_temp_free_i64(tmp);
113
+ TCGv_i32 tcg_shift, tcg_single;
40
}
114
+ TCGv_i64 tcg_double;
41
115
42
-static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_sp *a)
116
- tcg_fpstatus = get_fpstatus_ptr(false);
43
+static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_dp *a)
117
+ tcg_fpstatus = get_fpstatus_ptr(type == 3);
44
{
118
45
return do_vfp_3op_dp(s, gen_VMLA_dp, a->vd, a->vn, a->vm, true);
119
tcg_shift = tcg_const_i32(64 - scale);
46
}
120
47
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
121
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
48
tcg_temp_free_i64(tmp);
122
tcg_int = tcg_extend;
49
}
123
}
50
124
51
-static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_sp *a)
125
- if (is_double) {
52
+static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_dp *a)
126
- TCGv_i64 tcg_double = tcg_temp_new_i64();
53
{
127
+ switch (type) {
54
return do_vfp_3op_dp(s, gen_VMLS_dp, a->vd, a->vn, a->vm, true);
128
+ case 1: /* float64 */
55
}
129
+ tcg_double = tcg_temp_new_i64();
56
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
130
if (is_signed) {
57
tcg_temp_free_i64(tmp);
131
gen_helper_vfp_sqtod(tcg_double, tcg_int,
58
}
132
tcg_shift, tcg_fpstatus);
59
133
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
60
-static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_sp *a)
134
}
61
+static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_dp *a)
135
write_fp_dreg(s, rd, tcg_double);
62
{
136
tcg_temp_free_i64(tcg_double);
63
return do_vfp_3op_dp(s, gen_VNMLS_dp, a->vd, a->vn, a->vm, true);
137
- } else {
64
}
138
- TCGv_i32 tcg_single = tcg_temp_new_i32();
65
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
139
+ break;
66
tcg_temp_free_i64(tmp);
140
+
67
}
141
+ case 0: /* float32 */
68
142
+ tcg_single = tcg_temp_new_i32();
69
-static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_sp *a)
143
if (is_signed) {
70
+static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_dp *a)
144
gen_helper_vfp_sqtos(tcg_single, tcg_int,
71
{
145
tcg_shift, tcg_fpstatus);
72
return do_vfp_3op_dp(s, gen_VNMLA_dp, a->vd, a->vn, a->vm, true);
146
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
73
}
147
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_sp(DisasContext *s, arg_VMUL_sp *a)
148
write_fp_sreg(s, rd, tcg_single);
75
return do_vfp_3op_sp(s, gen_helper_vfp_muls, a->vd, a->vn, a->vm, false);
149
tcg_temp_free_i32(tcg_single);
76
}
150
+ break;
77
151
+
78
-static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_sp *a)
152
+ case 3: /* float16 */
79
+static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_dp *a)
153
+ tcg_single = tcg_temp_new_i32();
80
{
154
+ if (is_signed) {
81
return do_vfp_3op_dp(s, gen_helper_vfp_muld, a->vd, a->vn, a->vm, false);
155
+ gen_helper_vfp_sqtoh(tcg_single, tcg_int,
82
}
156
+ tcg_shift, tcg_fpstatus);
83
@@ -XXX,XX +XXX,XX @@ static void gen_VNMUL_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
157
+ } else {
84
gen_helper_vfp_negd(vd, vd);
158
+ gen_helper_vfp_uqtoh(tcg_single, tcg_int,
85
}
159
+ tcg_shift, tcg_fpstatus);
86
160
+ }
87
-static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_sp *a)
161
+ write_fp_sreg(s, rd, tcg_single);
88
+static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
162
+ tcg_temp_free_i32(tcg_single);
89
{
163
+ break;
90
return do_vfp_3op_dp(s, gen_VNMUL_dp, a->vd, a->vn, a->vm, false);
164
+
91
}
165
+ default:
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VADD_sp(DisasContext *s, arg_VADD_sp *a)
166
+ g_assert_not_reached();
93
return do_vfp_3op_sp(s, gen_helper_vfp_adds, a->vd, a->vn, a->vm, false);
167
}
94
}
168
} else {
95
169
TCGv_i64 tcg_int = cpu_reg(s, rd);
96
-static bool trans_VADD_dp(DisasContext *s, arg_VADD_sp *a)
170
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
97
+static bool trans_VADD_dp(DisasContext *s, arg_VADD_dp *a)
171
98
{
172
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
99
return do_vfp_3op_dp(s, gen_helper_vfp_addd, a->vd, a->vn, a->vm, false);
173
100
}
174
- if (is_double) {
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUB_sp(DisasContext *s, arg_VSUB_sp *a)
175
- TCGv_i64 tcg_double = read_fp_dreg(s, rn);
102
return do_vfp_3op_sp(s, gen_helper_vfp_subs, a->vd, a->vn, a->vm, false);
176
+ switch (type) {
103
}
177
+ case 1: /* float64 */
104
178
+ tcg_double = read_fp_dreg(s, rn);
105
-static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_sp *a)
179
if (is_signed) {
106
+static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_dp *a)
180
if (!sf) {
107
{
181
gen_helper_vfp_tosld(tcg_int, tcg_double,
108
return do_vfp_3op_dp(s, gen_helper_vfp_subd, a->vd, a->vn, a->vm, false);
182
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
109
}
183
tcg_shift, tcg_fpstatus);
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_sp(DisasContext *s, arg_VDIV_sp *a)
184
}
111
return do_vfp_3op_sp(s, gen_helper_vfp_divs, a->vd, a->vn, a->vm, false);
185
}
112
}
186
+ if (!sf) {
113
187
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
114
-static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_sp *a)
188
+ }
115
+static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
189
tcg_temp_free_i64(tcg_double);
116
{
190
- } else {
117
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
191
- TCGv_i32 tcg_single = read_fp_sreg(s, rn);
118
}
192
+ break;
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
193
+
120
return true;
194
+ case 0: /* float32 */
121
}
195
+ tcg_single = read_fp_sreg(s, rn);
122
196
if (sf) {
123
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_sp *a)
197
if (is_signed) {
124
+static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
198
gen_helper_vfp_tosqs(tcg_int, tcg_single,
125
{
199
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
126
/*
200
tcg_temp_free_i32(tcg_dest);
127
* VFNMA : fd = muladd(-fd, fn, fm)
201
}
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
202
tcg_temp_free_i32(tcg_single);
129
return true;
203
+ break;
130
}
204
+
131
205
+ case 3: /* float16 */
132
-static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_sp *a)
206
+ tcg_single = read_fp_sreg(s, rn);
133
+static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
207
+ if (sf) {
134
{
208
+ if (is_signed) {
135
TCGv_ptr fpst;
209
+ gen_helper_vfp_tosqh(tcg_int, tcg_single,
136
TCGv_i64 tmp;
210
+ tcg_shift, tcg_fpstatus);
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
211
+ } else {
138
return true;
212
+ gen_helper_vfp_touqh(tcg_int, tcg_single,
139
}
213
+ tcg_shift, tcg_fpstatus);
140
214
+ }
141
-static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_sp *a)
215
+ } else {
142
+static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
216
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
143
{
217
+ if (is_signed) {
144
TCGv_ptr fpst;
218
+ gen_helper_vfp_toslh(tcg_dest, tcg_single,
145
TCGv_i64 tmp;
219
+ tcg_shift, tcg_fpstatus);
220
+ } else {
221
+ gen_helper_vfp_toulh(tcg_dest, tcg_single,
222
+ tcg_shift, tcg_fpstatus);
223
+ }
224
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
225
+ tcg_temp_free_i32(tcg_dest);
226
+ }
227
+ tcg_temp_free_i32(tcg_single);
228
+ break;
229
+
230
+ default:
231
+ g_assert_not_reached();
232
}
233
234
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
235
tcg_temp_free_i32(tcg_rmode);
236
-
237
- if (!sf) {
238
- tcg_gen_ext32u_i64(tcg_int, tcg_int);
239
- }
240
}
241
242
tcg_temp_free_ptr(tcg_fpstatus);
243
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
244
/* actual FP conversions */
245
bool itof = extract32(opcode, 1, 1);
246
247
- if (type > 1 || (rmode != 0 && opcode > 1)) {
248
+ if (rmode != 0 && opcode > 1) {
249
+ unallocated_encoding(s);
250
+ return;
251
+ }
252
+ switch (type) {
253
+ case 0: /* float32 */
254
+ case 1: /* float64 */
255
+ break;
256
+ case 3: /* float16 */
257
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
258
+ break;
259
+ }
260
+ /* fallthru */
261
+ default:
262
unallocated_encoding(s);
263
return;
264
}
265
--
146
--
266
2.17.0
147
2.20.1
267
148
268
149
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The architecture permits FPUs which have only single-precision
2
2
support, not double-precision; Cortex-M4 and Cortex-M33 are
3
We missed all of the scalar fp16 fma operations.
3
both like that. Add the necessary checks on the MVFR0 FPDP
4
4
field so that we UNDEF any double-precision instructions on
5
Cc: qemu-stable@nongnu.org
5
CPUs like this.
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Note that even if FPDP==0 the insns like VMOV-to/from-gpreg,
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
VLDM/VSTM, VLDR/VSTR which take double precision registers
9
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
9
still exist.
10
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190614104457.24703-3-peter.maydell@linaro.org
11
---
14
---
12
target/arm/translate-a64.c | 48 ++++++++++++++++++++++++++++++++++++++
15
target/arm/cpu.h | 6 +++
13
1 file changed, 48 insertions(+)
16
target/arm/translate-vfp.inc.c | 84 ++++++++++++++++++++++++++++++++++
14
17
2 files changed, 90 insertions(+)
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
21
--- a/target/arm/cpu.h
18
+++ b/target/arm/translate-a64.c
22
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
20
tcg_temp_free_i64(tcg_res);
24
return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
21
}
25
}
22
26
23
+/* Floating-point data-processing (3 source) - half precision */
27
+static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
24
+static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
25
+ int rd, int rn, int rm, int ra)
26
+{
28
+{
27
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
29
+ /* Return true if CPU supports double precision floating point */
28
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
30
+ return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
29
+ TCGv_ptr fpst = get_fpstatus_ptr(true);
30
+
31
+ tcg_op1 = read_fp_hreg(s, rn);
32
+ tcg_op2 = read_fp_hreg(s, rm);
33
+ tcg_op3 = read_fp_hreg(s, ra);
34
+
35
+ /* These are fused multiply-add, and must be done as one
36
+ * floating point operation with no rounding between the
37
+ * multiplication and addition steps.
38
+ * NB that doing the negations here as separate steps is
39
+ * correct : an input NaN should come out with its sign bit
40
+ * flipped if it is a negated-input.
41
+ */
42
+ if (o1 == true) {
43
+ tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
44
+ }
45
+
46
+ if (o0 != o1) {
47
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
48
+ }
49
+
50
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
51
+
52
+ write_fp_sreg(s, rd, tcg_res);
53
+
54
+ tcg_temp_free_ptr(fpst);
55
+ tcg_temp_free_i32(tcg_op1);
56
+ tcg_temp_free_i32(tcg_op2);
57
+ tcg_temp_free_i32(tcg_op3);
58
+ tcg_temp_free_i32(tcg_res);
59
+}
31
+}
60
+
32
+
61
/* Floating point data-processing (3 source)
33
/*
62
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
34
* We always set the FP and SIMD FP16 fields to indicate identical
63
* +---+---+---+-----------+------+----+------+----+------+------+------+
35
* levels of support (assuming SIMD is implemented at all), so
64
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
36
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
65
}
37
index XXXXXXX..XXXXXXX 100644
66
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
38
--- a/target/arm/translate-vfp.inc.c
67
break;
39
+++ b/target/arm/translate-vfp.inc.c
68
+ case 3:
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
69
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
41
((a->vm | a->vn | a->vd) & 0x10)) {
70
+ unallocated_encoding(s);
42
return false;
71
+ return;
43
}
72
+ }
44
+
73
+ if (!fp_access_check(s)) {
45
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
74
+ return;
46
+ return false;
75
+ }
47
+ }
76
+ handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
48
+
77
+ break;
49
rd = a->vd;
78
default:
50
rn = a->vn;
79
unallocated_encoding(s);
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;
80
}
263
}
81
--
264
--
82
2.17.0
265
2.20.1
83
266
84
267
diff view generated by jsdifflib