1
The following changes since commit 0d3e41d5efd638a0c5682f6813b26448c3c51624:
1
v3: really fix the format string nit (oops)
2
2
3
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-pull-request' into staging (2019-02-14 17:42:25 +0000)
3
The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5:
4
5
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190214
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-2
8
10
9
for you to fetch changes up to 497bc12b1b374ecd62903bf062229bd93f8924af:
11
for you to fetch changes up to eec607843ca81eccab238fce86222be9c78b3675:
10
12
11
gdbstub: Send a reply to the vKill packet. (2019-02-14 18:45:49 +0000)
13
hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 19:45:02 +0100)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
target-arm queue:
16
target-arm queue:
15
* gdbstub: Send a reply to the vKill packet
17
* mark MPS2/MPS3 board-internal i2c buses as 'full' so that command
16
* Improve codegen for neon min/max and saturating arithmetic
18
line user-created devices are not plugged into them
17
* Fix a bug in clearing FPSCR exception status bits
19
* Take an exception if PSTATE.IL is set
18
* hw/arm/armsse: Fix miswiring of expansion IRQs
20
* Support an emulated ITS in the virt board
19
* hw/intc/armv7m_nvic: Allow byte accesses to SHPR1
21
* Add support for kudo-bmc board
20
* MAINTAINERS: Remove Peter Crosthwaite from various entries
22
* Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
21
* arm: Allow system registers for KVM guests to be changed by QEMU code
23
* cadence_uart: Fix clock handling issues that prevented
22
* linux-user: support HWCAP_CPUID which exposes ID registers to user code
24
u-boot from running
23
* Fix bug in 128-bit cmpxchg for BE Arm guests
24
* Implement (no-op) HACR_EL2
25
* Fix CRn to be 14 for PMEVTYPER/PMEVCNTR
26
25
27
----------------------------------------------------------------
26
----------------------------------------------------------------
28
Aaron Lindsay OS (1):
27
Bin Meng (6):
29
target/arm: Fix CRn to be 14 for PMEVTYPER/PMEVCNTR
28
hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase
29
hw/char: cadence_uart: Disable transmit when input clock is disabled
30
hw/char: cadence_uart: Move clock/reset check to uart_can_receive()
31
hw/char: cadence_uart: Convert to memop_with_attrs() ops
32
hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}()
33
hw/char: cadence_uart: Log a guest error when device is unclocked or in reset
30
34
31
Alex Bennée (5):
35
Chris Rauer (1):
32
target/arm: relax permission checks for HWCAP_CPUID registers
36
hw/arm: Add support for kudo-bmc board.
33
target/arm: expose CPUID registers to userspace
34
target/arm: expose MPIDR_EL1 to userspace
35
target/arm: expose remaining CPUID registers as RAZ
36
linux-user/elfload: enable HWCAP_CPUID for AArch64
37
37
38
Catherine Ho (1):
38
Marc Zyngier (1):
39
target/arm: Fix int128_make128 lo, hi order in paired_cmpxchg64_be
39
hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
40
40
41
Peter Maydell (5):
41
Peter Maydell (5):
42
target/arm: Implement HACR_EL2
42
target/arm: Take an exception if PSTATE.IL is set
43
arm: Allow system registers for KVM guests to be changed by QEMU code
43
qdev: Support marking individual buses as 'full'
44
MAINTAINERS: Remove Peter Crosthwaite from various entries
44
hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn
45
hw/intc/armv7m_nvic: Allow byte accesses to SHPR1
45
hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full'
46
hw/arm/armsse: Fix miswiring of expansion IRQs
46
hw/arm/mps2.c: Mark internal-only I2C buses as 'full'
47
47
48
Richard Henderson (14):
48
Richard Henderson (1):
49
target/arm: Force result size into dp after operation
49
target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn
50
target/arm: Restructure disas_fp_int_conv
51
target/arm: Rely on optimization within tcg_gen_gvec_or
52
target/arm: Use vector minmax expanders for aarch64
53
target/arm: Use vector minmax expanders for aarch32
54
target/arm: Use tcg integer min/max primitives for neon
55
target/arm: Remove neon min/max helpers
56
target/arm: Fix vfp_gdb_get/set_reg vs FPSCR
57
target/arm: Fix arm_cpu_dump_state vs FPSCR
58
target/arm: Split out flags setting from vfp compares
59
target/arm: Fix set of bits kept in xregs[ARM_VFP_FPSCR]
60
target/arm: Split out FPSCR.QC to a vector field
61
target/arm: Use vector operations for saturation
62
target/arm: Add missing clear_tail calls
63
50
64
Sandra Loosemore (1):
51
Shashi Mallela (9):
65
gdbstub: Send a reply to the vKill packet.
52
hw/intc: GICv3 ITS initial framework
53
hw/intc: GICv3 ITS register definitions added
54
hw/intc: GICv3 ITS command queue framework
55
hw/intc: GICv3 ITS Command processing
56
hw/intc: GICv3 ITS Feature enablement
57
hw/intc: GICv3 redistributor ITS processing
58
tests/data/acpi/virt: Add IORT files for ITS
59
hw/arm/virt: add ITS support in virt GIC
60
tests/data/acpi/virt: Update IORT files for ITS
66
61
67
target/arm/cpu.h | 50 ++++++++-
62
docs/system/arm/nuvoton.rst | 1 +
68
target/arm/helper.h | 45 +++++---
63
hw/intc/gicv3_internal.h | 188 ++++-
69
target/arm/translate.h | 4 +
64
include/hw/arm/virt.h | 2 +
70
gdbstub.c | 1 +
65
include/hw/intc/arm_gicv3_common.h | 13 +
71
hw/arm/armsse.c | 2 +-
66
include/hw/intc/arm_gicv3_its_common.h | 32 +-
72
hw/intc/armv7m_nvic.c | 4 +-
67
include/hw/qdev-core.h | 24 +
73
linux-user/elfload.c | 1 +
68
target/arm/cpu.h | 1 +
74
target/arm/helper-a64.c | 4 +-
69
target/arm/kvm_arm.h | 4 +-
75
target/arm/helper.c | 228 ++++++++++++++++++++++++++++++++--------
70
target/arm/syndrome.h | 5 +
76
target/arm/kvm32.c | 20 +---
71
target/arm/translate.h | 2 +
77
target/arm/kvm64.c | 2 +
72
hw/arm/mps2-tz.c | 92 ++-
78
target/arm/machine.c | 2 +-
73
hw/arm/mps2.c | 12 +-
79
target/arm/neon_helper.c | 14 +--
74
hw/arm/npcm7xx_boards.c | 34 +
80
target/arm/translate-a64.c | 171 +++++++++++++++---------------
75
hw/arm/virt.c | 29 +-
81
target/arm/translate-sve.c | 6 +-
76
hw/char/cadence_uart.c | 61 +-
82
target/arm/translate.c | 251 ++++++++++++++++++++++++++++++++++-----------
77
hw/intc/arm_gicv3.c | 14 +
83
target/arm/vec_helper.c | 134 +++++++++++++++++++++++-
78
hw/intc/arm_gicv3_common.c | 13 +
84
MAINTAINERS | 4 -
79
hw/intc/arm_gicv3_cpuif.c | 7 +-
85
18 files changed, 687 insertions(+), 256 deletions(-)
80
hw/intc/arm_gicv3_dist.c | 5 +-
81
hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++
82
hw/intc/arm_gicv3_its_common.c | 7 +-
83
hw/intc/arm_gicv3_its_kvm.c | 2 +-
84
hw/intc/arm_gicv3_redist.c | 153 +++-
85
hw/misc/zynq_slcr.c | 31 +-
86
softmmu/qdev-monitor.c | 7 +-
87
target/arm/helper-a64.c | 1 +
88
target/arm/helper.c | 8 +
89
target/arm/kvm.c | 7 +-
90
target/arm/translate-a64.c | 255 +++---
91
target/arm/translate.c | 21 +
92
hw/intc/meson.build | 1 +
93
tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes
94
tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes
95
tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes
96
tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes
97
35 files changed, 2144 insertions(+), 210 deletions(-)
98
create mode 100644 hw/intc/arm_gicv3_its.c
99
create mode 100644 tests/data/acpi/virt/IORT
100
create mode 100644 tests/data/acpi/virt/IORT.memhp
101
create mode 100644 tests/data/acpi/virt/IORT.numamem
102
create mode 100644 tests/data/acpi/virt/IORT.pxb
86
103
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
1
3
This bug was introduced in:
4
commit 5ecdd3e47cadae83a62dc92b472f1fe163b56f59
5
target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190205135129.19338-1-aaron@os.amperecomputing.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
21
char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
22
char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
23
ARMCPRegInfo pmev_regs[] = {
24
- { .name = pmevcntr_name, .cp = 15, .crn = 15,
25
+ { .name = pmevcntr_name, .cp = 15, .crn = 14,
26
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
27
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
28
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
29
.accessfn = pmreg_access },
30
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
31
- .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)),
32
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
33
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
34
.type = ARM_CP_IO,
35
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
36
.raw_readfn = pmevcntr_rawread,
37
.raw_writefn = pmevcntr_rawwrite },
38
- { .name = pmevtyper_name, .cp = 15, .crn = 15,
39
+ { .name = pmevtyper_name, .cp = 15, .crn = 14,
40
.crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
41
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
42
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
43
.accessfn = pmreg_access },
44
{ .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
45
- .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)),
46
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
47
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
48
.type = ARM_CP_IO,
49
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
HACR_EL2 is a register with IMPDEF behaviour, which allows
2
implementation specific trapping to EL2. Implement it as RAZ/WI,
3
since QEMU's implementation has no extra traps. This also
4
matches what h/w implementations like Cortex-A53 and A57 do.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190205181218.8995-1-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
18
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
19
.access = PL2_RW,
20
.type = ARM_CP_CONST, .resetvalue = 0 },
21
+ { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
22
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
23
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
24
{ .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
25
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
26
.access = PL2_RW,
27
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
28
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
29
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
30
.writefn = hcr_writelow },
31
+ { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
32
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
33
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
34
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
35
.type = ARM_CP_ALIAS,
36
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Catherine Ho <catherine.hecx@gmail.com>
2
1
3
The lo,hi order is different from the comments. And in commit
4
1ec182c33379 ("target/arm: Convert to HAVE_CMPXCHG128"), it changes
5
the original code logic. So just restore the old code logic before this
6
commit:
7
do_paired_cmpxchg64_be():
8
cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
9
newv = int128_make128(new_hi, new_lo);
10
11
This fixes a bug that would only be visible for big-endian
12
AArch64 guest code.
13
14
Fixes: 1ec182c33379 ("target/arm: Convert to HAVE_CMPXCHG128")
15
Signed-off-by: Catherine Ho <catherine.hecx@gmail.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 1548985244-24523-1-git-send-email-catherine.hecx@gmail.com
18
[PMM: added note that bug only affects BE guests]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
target/arm/helper-a64.c | 4 ++--
22
1 file changed, 2 insertions(+), 2 deletions(-)
23
24
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper-a64.c
27
+++ b/target/arm/helper-a64.c
28
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
29
* High and low need to be switched here because this is not actually a
30
* 128bit store but two doublewords stored consecutively
31
*/
32
- Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
33
- Int128 newv = int128_make128(new_lo, new_hi);
34
+ Int128 cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
35
+ Int128 newv = int128_make128(new_hi, new_lo);
36
Int128 oldv;
37
uintptr_t ra = GETPC();
38
uint64_t o0, o1;
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rather than a complex set of cases testing for writeback,
4
adjust DP after performing the operation.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190206052857.5077-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate.c | 32 ++++++++++++++++----------------
12
1 file changed, 16 insertions(+), 16 deletions(-)
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
19
tcg_gen_or_i32(tmp, tmp, tmp2);
20
tcg_temp_free_i32(tmp2);
21
gen_vfp_msr(tmp);
22
+ dp = 0; /* always a single precision result */
23
break;
24
}
25
case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
26
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
27
tcg_gen_or_i32(tmp, tmp, tmp2);
28
tcg_temp_free_i32(tmp2);
29
gen_vfp_msr(tmp);
30
+ dp = 0; /* always a single precision result */
31
break;
32
}
33
case 8: /* cmp */
34
gen_vfp_cmp(dp);
35
+ dp = -1; /* no write back */
36
break;
37
case 9: /* cmpe */
38
gen_vfp_cmpe(dp);
39
+ dp = -1; /* no write back */
40
break;
41
case 10: /* cmpz */
42
gen_vfp_cmp(dp);
43
+ dp = -1; /* no write back */
44
break;
45
case 11: /* cmpez */
46
gen_vfp_F1_ld0(dp);
47
gen_vfp_cmpe(dp);
48
+ dp = -1; /* no write back */
49
break;
50
case 12: /* vrintr */
51
{
52
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
53
break;
54
}
55
case 15: /* single<->double conversion */
56
- if (dp)
57
+ if (dp) {
58
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
59
- else
60
+ } else {
61
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
62
+ }
63
+ dp = !dp; /* result size is opposite */
64
break;
65
case 16: /* fuito */
66
gen_vfp_uito(dp, 0);
67
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
68
break;
69
case 24: /* ftoui */
70
gen_vfp_toui(dp, 0);
71
+ dp = 0; /* always an integer result */
72
break;
73
case 25: /* ftouiz */
74
gen_vfp_touiz(dp, 0);
75
+ dp = 0; /* always an integer result */
76
break;
77
case 26: /* ftosi */
78
gen_vfp_tosi(dp, 0);
79
+ dp = 0; /* always an integer result */
80
break;
81
case 27: /* ftosiz */
82
gen_vfp_tosiz(dp, 0);
83
+ dp = 0; /* always an integer result */
84
break;
85
case 28: /* ftosh */
86
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
87
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
88
return 1;
89
}
90
91
- /* Write back the result. */
92
- if (op == 15 && (rn >= 8 && rn <= 11)) {
93
- /* Comparison, do nothing. */
94
- } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
95
- (rn & 0x1e) == 0x6)) {
96
- /* VCVT double to int: always integer result.
97
- * VCVT double to half precision is always a single
98
- * precision result.
99
- */
100
- gen_mov_vreg_F0(0, rd);
101
- } else if (op == 15 && rn == 15) {
102
- /* conversion */
103
- gen_mov_vreg_F0(!dp, rd);
104
- } else {
105
+ /* Write back the result, if any. */
106
+ if (dp >= 0) {
107
gen_mov_vreg_F0(dp, rd);
108
}
109
110
--
111
2.20.1
112
113
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
For opcodes 0-5, move some if conditions into the structure
4
of a switch statement. For opcodes 6 & 7, decode everything
5
at once with a second switch.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190206052857.5077-3-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 | 94 ++++++++++++++++++++------------------
13
1 file changed, 49 insertions(+), 45 deletions(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
20
int type = extract32(insn, 22, 2);
21
bool sbit = extract32(insn, 29, 1);
22
bool sf = extract32(insn, 31, 1);
23
+ bool itof = false;
24
25
if (sbit) {
26
- unallocated_encoding(s);
27
- return;
28
+ goto do_unallocated;
29
}
30
31
- if (opcode > 5) {
32
- /* FMOV */
33
- bool itof = opcode & 1;
34
-
35
- if (rmode >= 2) {
36
- unallocated_encoding(s);
37
- return;
38
- }
39
-
40
- switch (sf << 3 | type << 1 | rmode) {
41
- case 0x0: /* 32 bit */
42
- case 0xa: /* 64 bit */
43
- case 0xd: /* 64 bit to top half of quad */
44
- break;
45
- case 0x6: /* 16-bit float, 32-bit int */
46
- case 0xe: /* 16-bit float, 64-bit int */
47
- if (dc_isar_feature(aa64_fp16, s)) {
48
- break;
49
- }
50
- /* fallthru */
51
- default:
52
- /* all other sf/type/rmode combinations are invalid */
53
- unallocated_encoding(s);
54
- return;
55
- }
56
-
57
- if (!fp_access_check(s)) {
58
- return;
59
- }
60
- handle_fmov(s, rd, rn, type, itof);
61
- } else {
62
- /* actual FP conversions */
63
- bool itof = extract32(opcode, 1, 1);
64
-
65
- if (rmode != 0 && opcode > 1) {
66
- unallocated_encoding(s);
67
- return;
68
+ switch (opcode) {
69
+ case 2: /* SCVTF */
70
+ case 3: /* UCVTF */
71
+ itof = true;
72
+ /* fallthru */
73
+ case 4: /* FCVTAS */
74
+ case 5: /* FCVTAU */
75
+ if (rmode != 0) {
76
+ goto do_unallocated;
77
}
78
+ /* fallthru */
79
+ case 0: /* FCVT[NPMZ]S */
80
+ case 1: /* FCVT[NPMZ]U */
81
switch (type) {
82
case 0: /* float32 */
83
case 1: /* float64 */
84
break;
85
case 3: /* float16 */
86
- if (dc_isar_feature(aa64_fp16, s)) {
87
- break;
88
+ if (!dc_isar_feature(aa64_fp16, s)) {
89
+ goto do_unallocated;
90
}
91
- /* fallthru */
92
+ break;
93
default:
94
- unallocated_encoding(s);
95
- return;
96
+ goto do_unallocated;
97
}
98
-
99
if (!fp_access_check(s)) {
100
return;
101
}
102
handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
103
+ break;
104
+
105
+ default:
106
+ switch (sf << 7 | type << 5 | rmode << 3 | opcode) {
107
+ case 0b01100110: /* FMOV half <-> 32-bit int */
108
+ case 0b01100111:
109
+ case 0b11100110: /* FMOV half <-> 64-bit int */
110
+ case 0b11100111:
111
+ if (!dc_isar_feature(aa64_fp16, s)) {
112
+ goto do_unallocated;
113
+ }
114
+ /* fallthru */
115
+ case 0b00000110: /* FMOV 32-bit */
116
+ case 0b00000111:
117
+ case 0b10100110: /* FMOV 64-bit */
118
+ case 0b10100111:
119
+ case 0b11001110: /* FMOV top half of 128-bit */
120
+ case 0b11001111:
121
+ if (!fp_access_check(s)) {
122
+ return;
123
+ }
124
+ itof = opcode & 1;
125
+ handle_fmov(s, rd, rn, type, itof);
126
+ break;
127
+
128
+ default:
129
+ do_unallocated:
130
+ unallocated_encoding(s);
131
+ return;
132
+ }
133
+ break;
134
}
135
}
136
137
--
138
2.20.1
139
140
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
Although technically not visible to userspace the kernel does make
4
them visible via a trap and emulate ABI. We provide a new permission
5
mask (PL0U_R) which maps to PL0_R for CONFIG_USER builds and adjust
6
the minimum permission check accordingly.
7
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20190205190224.2198-2-alex.bennee@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 12 ++++++++++++
14
target/arm/helper.c | 6 +++++-
15
2 files changed, 17 insertions(+), 1 deletion(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
22
#define PL0_R (0x02 | PL1_R)
23
#define PL0_W (0x01 | PL1_W)
24
25
+/*
26
+ * For user-mode some registers are accessible to EL0 via a kernel
27
+ * trap-and-emulate ABI. In this case we define the read permissions
28
+ * as actually being PL0_R. However some bits of any given register
29
+ * may still be masked.
30
+ */
31
+#ifdef CONFIG_USER_ONLY
32
+#define PL0U_R PL0_R
33
+#else
34
+#define PL0U_R PL1_R
35
+#endif
36
+
37
#define PL3_RW (PL3_R | PL3_W)
38
#define PL2_RW (PL2_R | PL2_W)
39
#define PL1_RW (PL1_R | PL1_W)
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.c
43
+++ b/target/arm/helper.c
44
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
45
if (r->state != ARM_CP_STATE_AA32) {
46
int mask = 0;
47
switch (r->opc1) {
48
- case 0: case 1: case 2:
49
+ case 0:
50
+ /* min_EL EL1, but some accessible to EL0 via kernel ABI */
51
+ mask = PL0U_R | PL1_RW;
52
+ break;
53
+ case 1: case 2:
54
/* min_EL EL1 */
55
mask = PL1_RW;
56
break;
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
A number of CPUID registers are exposed to userspace by modern Linux
4
kernels thanks to the "ARM64 CPU Feature Registers" ABI. For QEMU's
5
user-mode emulation we don't need to emulate the kernels trap but just
6
return the value the trap would have done. To avoid too much #ifdef
7
hackery we process ARMCPRegInfo with a new helper (modify_arm_cp_regs)
8
before defining the registers. The modify routine is driven by a
9
simple data structure which describes which bits are exported and
10
which are fixed.
11
12
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20190205190224.2198-3-alex.bennee@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 21 ++++++++++++++++
18
target/arm/helper.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 80 insertions(+)
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 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
26
}
27
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
28
29
+/*
30
+ * Definition of an ARM co-processor register as viewed from
31
+ * userspace. This is used for presenting sanitised versions of
32
+ * registers to userspace when emulating the Linux AArch64 CPU
33
+ * ID/feature ABI (advertised as HWCAP_CPUID).
34
+ */
35
+typedef struct ARMCPRegUserSpaceInfo {
36
+ /* Name of register */
37
+ const char *name;
38
+
39
+ /* Only some bits are exported to user space */
40
+ uint64_t exported_bits;
41
+
42
+ /* Fixed bits are applied after the mask */
43
+ uint64_t fixed_bits;
44
+} ARMCPRegUserSpaceInfo;
45
+
46
+#define REGUSERINFO_SENTINEL { .name = NULL }
47
+
48
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
49
+
50
/* CPWriteFn that can be used to implement writes-ignored behaviour */
51
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
52
uint64_t value);
53
diff --git a/target/arm/helper.c b/target/arm/helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/helper.c
56
+++ b/target/arm/helper.c
57
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
58
.resetvalue = cpu->pmceid1 },
59
REGINFO_SENTINEL
60
};
61
+#ifdef CONFIG_USER_ONLY
62
+ ARMCPRegUserSpaceInfo v8_user_idregs[] = {
63
+ { .name = "ID_AA64PFR0_EL1",
64
+ .exported_bits = 0x000f000f00ff0000,
65
+ .fixed_bits = 0x0000000000000011 },
66
+ { .name = "ID_AA64PFR1_EL1",
67
+ .exported_bits = 0x00000000000000f0 },
68
+ { .name = "ID_AA64ZFR0_EL1" },
69
+ { .name = "ID_AA64MMFR0_EL1",
70
+ .fixed_bits = 0x00000000ff000000 },
71
+ { .name = "ID_AA64MMFR1_EL1" },
72
+ { .name = "ID_AA64DFR0_EL1",
73
+ .fixed_bits = 0x0000000000000006 },
74
+ { .name = "ID_AA64DFR1_EL1" },
75
+ { .name = "ID_AA64AFR0_EL1" },
76
+ { .name = "ID_AA64AFR1_EL1" },
77
+ { .name = "ID_AA64ISAR0_EL1",
78
+ .exported_bits = 0x00fffffff0fffff0 },
79
+ { .name = "ID_AA64ISAR1_EL1",
80
+ .exported_bits = 0x000000f0ffffffff },
81
+ REGUSERINFO_SENTINEL
82
+ };
83
+ modify_arm_cp_regs(v8_idregs, v8_user_idregs);
84
+#endif
85
/* RVBAR_EL1 is only implemented if EL1 is the highest EL */
86
if (!arm_feature(env, ARM_FEATURE_EL3) &&
87
!arm_feature(env, ARM_FEATURE_EL2)) {
88
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
89
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
90
.type = ARM_CP_NOP | ARM_CP_OVERRIDE
91
};
92
+#ifdef CONFIG_USER_ONLY
93
+ ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
94
+ { .name = "MIDR_EL1",
95
+ .exported_bits = 0x00000000ffffffff },
96
+ { .name = "REVIDR_EL1" },
97
+ REGUSERINFO_SENTINEL
98
+ };
99
+ modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
100
+#endif
101
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
102
arm_feature(env, ARM_FEATURE_STRONGARM)) {
103
ARMCPRegInfo *r;
104
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
105
}
106
}
107
108
+/*
109
+ * Modify ARMCPRegInfo for access from userspace.
110
+ *
111
+ * This is a data driven modification directed by
112
+ * ARMCPRegUserSpaceInfo. All registers become ARM_CP_CONST as
113
+ * user-space cannot alter any values and dynamic values pertaining to
114
+ * execution state are hidden from user space view anyway.
115
+ */
116
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
117
+{
118
+ const ARMCPRegUserSpaceInfo *m;
119
+ ARMCPRegInfo *r;
120
+
121
+ for (m = mods; m->name; m++) {
122
+ for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
123
+ if (strcmp(r->name, m->name) == 0) {
124
+ r->type = ARM_CP_CONST;
125
+ r->access = PL0U_R;
126
+ r->resetvalue &= m->exported_bits;
127
+ r->resetvalue |= m->fixed_bits;
128
+ break;
129
+ }
130
+ }
131
+ }
132
+}
133
+
134
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
135
{
136
return g_hash_table_lookup(cpregs, &encoded_cp);
137
--
138
2.20.1
139
140
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
As this is a single register we could expose it with a simple ifdef
4
but we use the existing modify_arm_cp_regs mechanism for consistency.
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20190205190224.2198-4-alex.bennee@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/helper.c | 21 ++++++++++++++-------
12
1 file changed, 14 insertions(+), 7 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
19
return mpidr_read_val(env);
20
}
21
22
-static const ARMCPRegInfo mpidr_cp_reginfo[] = {
23
- { .name = "MPIDR", .state = ARM_CP_STATE_BOTH,
24
- .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
25
- .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
26
- REGINFO_SENTINEL
27
-};
28
-
29
static const ARMCPRegInfo lpae_cp_reginfo[] = {
30
/* NOP AMAIR0/1 */
31
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
33
}
34
35
if (arm_feature(env, ARM_FEATURE_MPIDR)) {
36
+ ARMCPRegInfo mpidr_cp_reginfo[] = {
37
+ { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
38
+ .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
39
+ .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
40
+ REGINFO_SENTINEL
41
+ };
42
+#ifdef CONFIG_USER_ONLY
43
+ ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
44
+ { .name = "MPIDR_EL1",
45
+ .fixed_bits = 0x0000000080000000 },
46
+ REGUSERINFO_SENTINEL
47
+ };
48
+ modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
49
+#endif
50
define_arm_cp_regs(cpu, mpidr_cp_reginfo);
51
}
52
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
There are a whole bunch more registers in the CPUID space which are
4
currently not used but are exposed as RAZ. To avoid too much
5
duplication we expand ARMCPRegUserSpaceInfo to understand glob
6
patterns so we only need one entry to tweak whole ranges of registers.
7
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20190205190224.2198-5-alex.bennee@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 3 +++
14
target/arm/helper.c | 26 +++++++++++++++++++++++---
15
2 files changed, 26 insertions(+), 3 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPRegUserSpaceInfo {
22
/* Name of register */
23
const char *name;
24
25
+ /* Is the name actually a glob pattern */
26
+ bool is_glob;
27
+
28
/* Only some bits are exported to user space */
29
uint64_t exported_bits;
30
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
36
.fixed_bits = 0x0000000000000011 },
37
{ .name = "ID_AA64PFR1_EL1",
38
.exported_bits = 0x00000000000000f0 },
39
+ { .name = "ID_AA64PFR*_EL1_RESERVED",
40
+ .is_glob = true },
41
{ .name = "ID_AA64ZFR0_EL1" },
42
{ .name = "ID_AA64MMFR0_EL1",
43
.fixed_bits = 0x00000000ff000000 },
44
{ .name = "ID_AA64MMFR1_EL1" },
45
+ { .name = "ID_AA64MMFR*_EL1_RESERVED",
46
+ .is_glob = true },
47
{ .name = "ID_AA64DFR0_EL1",
48
.fixed_bits = 0x0000000000000006 },
49
{ .name = "ID_AA64DFR1_EL1" },
50
- { .name = "ID_AA64AFR0_EL1" },
51
- { .name = "ID_AA64AFR1_EL1" },
52
+ { .name = "ID_AA64DFR*_EL1_RESERVED",
53
+ .is_glob = true },
54
+ { .name = "ID_AA64AFR*",
55
+ .is_glob = true },
56
{ .name = "ID_AA64ISAR0_EL1",
57
.exported_bits = 0x00fffffff0fffff0 },
58
{ .name = "ID_AA64ISAR1_EL1",
59
.exported_bits = 0x000000f0ffffffff },
60
+ { .name = "ID_AA64ISAR*_EL1_RESERVED",
61
+ .is_glob = true },
62
REGUSERINFO_SENTINEL
63
};
64
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
65
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
66
ARMCPRegInfo *r;
67
68
for (m = mods; m->name; m++) {
69
+ GPatternSpec *pat = NULL;
70
+ if (m->is_glob) {
71
+ pat = g_pattern_spec_new(m->name);
72
+ }
73
for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
74
- if (strcmp(r->name, m->name) == 0) {
75
+ if (pat && g_pattern_match_string(pat, r->name)) {
76
+ r->type = ARM_CP_CONST;
77
+ r->access = PL0U_R;
78
+ r->resetvalue = 0;
79
+ /* continue */
80
+ } else if (strcmp(r->name, m->name) == 0) {
81
r->type = ARM_CP_CONST;
82
r->access = PL0U_R;
83
r->resetvalue &= m->exported_bits;
84
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
85
break;
86
}
87
}
88
+ if (pat) {
89
+ g_pattern_spec_free(pat);
90
+ }
91
}
92
}
93
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
Userspace programs should (in theory) query the ELF HWCAP before
4
probing these registers. Now we have implemented them all make it
5
public.
6
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190205190224.2198-6-alex.bennee@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
linux-user/elfload.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
18
+++ b/linux-user/elfload.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
20
21
hwcaps |= ARM_HWCAP_A64_FP;
22
hwcaps |= ARM_HWCAP_A64_ASIMD;
23
+ hwcaps |= ARM_HWCAP_A64_CPUID;
24
25
/* probe for the extra features */
26
#define GET_FEATURE_ID(feat, hwcap) \
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
At the moment the Arm implementations of kvm_arch_{get,put}_registers()
2
don't support having QEMU change the values of system registers
3
(aka coprocessor registers for AArch32). This is because although
4
kvm_arch_get_registers() calls write_list_to_cpustate() to
5
update the CPU state struct fields (so QEMU code can read the
6
values in the usual way), kvm_arch_put_registers() does not
7
call write_cpustate_to_list(), meaning that any changes to
8
the CPU state struct fields will not be passed back to KVM.
9
1
10
The rationale for this design is documented in a comment in the
11
AArch32 kvm_arch_put_registers() -- writing the values in the
12
cpregs list into the CPU state struct is "lossy" because the
13
write of a register might not succeed, and so if we blindly
14
copy the CPU state values back again we will incorrectly
15
change register values for the guest. The assumption was that
16
no QEMU code would need to write to the registers.
17
18
However, when we implemented debug support for KVM guests, we
19
broke that assumption: the code to handle "set the guest up
20
to take a breakpoint exception" does so by updating various
21
guest registers including ESR_EL1.
22
23
Support this by making kvm_arch_put_registers() synchronize
24
CPU state back into the list. We sync only those registers
25
where the initial write succeeds, which should be sufficient.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
29
Tested-by: Alex Bennée <alex.bennee@linaro.org>
30
Tested-by: Dongjiu Geng <gengdongjiu@huawei.com>
31
---
32
target/arm/cpu.h | 9 ++++++++-
33
target/arm/helper.c | 27 +++++++++++++++++++++++++--
34
target/arm/kvm32.c | 20 ++------------------
35
target/arm/kvm64.c | 2 ++
36
target/arm/machine.c | 2 +-
37
5 files changed, 38 insertions(+), 22 deletions(-)
38
39
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/cpu.h
42
+++ b/target/arm/cpu.h
43
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu);
44
/**
45
* write_cpustate_to_list:
46
* @cpu: ARMCPU
47
+ * @kvm_sync: true if this is for syncing back to KVM
48
*
49
* For each register listed in the ARMCPU cpreg_indexes list, write
50
* its value from the ARMCPUState structure into the cpreg_values list.
51
* This is used to copy info from TCG's working data structures into
52
* KVM or for outbound migration.
53
*
54
+ * @kvm_sync is true if we are doing this in order to sync the
55
+ * register state back to KVM. In this case we will only update
56
+ * values in the list if the previous list->cpustate sync actually
57
+ * successfully wrote the CPU state. Otherwise we will keep the value
58
+ * that is in the list.
59
+ *
60
* Returns: true if all register values were read correctly,
61
* false if some register was unknown or could not be read.
62
* Note that we do not stop early on failure -- we will attempt
63
* reading all registers in the list.
64
*/
65
-bool write_cpustate_to_list(ARMCPU *cpu);
66
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
67
68
#define ARM_CPUID_TI915T 0x54029152
69
#define ARM_CPUID_TI925T 0x54029252
70
diff --git a/target/arm/helper.c b/target/arm/helper.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/helper.c
73
+++ b/target/arm/helper.c
74
@@ -XXX,XX +XXX,XX @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
75
return true;
76
}
77
78
-bool write_cpustate_to_list(ARMCPU *cpu)
79
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
80
{
81
/* Write the coprocessor state from cpu->env to the (index,value) list. */
82
int i;
83
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
84
for (i = 0; i < cpu->cpreg_array_len; i++) {
85
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
86
const ARMCPRegInfo *ri;
87
+ uint64_t newval;
88
89
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
90
if (!ri) {
91
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
92
if (ri->type & ARM_CP_NO_RAW) {
93
continue;
94
}
95
- cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
96
+
97
+ newval = read_raw_cp_reg(&cpu->env, ri);
98
+ if (kvm_sync) {
99
+ /*
100
+ * Only sync if the previous list->cpustate sync succeeded.
101
+ * Rather than tracking the success/failure state for every
102
+ * item in the list, we just recheck "does the raw write we must
103
+ * have made in write_list_to_cpustate() read back OK" here.
104
+ */
105
+ uint64_t oldval = cpu->cpreg_values[i];
106
+
107
+ if (oldval == newval) {
108
+ continue;
109
+ }
110
+
111
+ write_raw_cp_reg(&cpu->env, ri, oldval);
112
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
113
+ continue;
114
+ }
115
+
116
+ write_raw_cp_reg(&cpu->env, ri, newval);
117
+ }
118
+ cpu->cpreg_values[i] = newval;
119
}
120
return ok;
121
}
122
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/kvm32.c
125
+++ b/target/arm/kvm32.c
126
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
127
return ret;
128
}
129
130
- /* Note that we do not call write_cpustate_to_list()
131
- * here, so we are only writing the tuple list back to
132
- * KVM. This is safe because nothing can change the
133
- * CPUARMState cp15 fields (in particular gdb accesses cannot)
134
- * and so there are no changes to sync. In fact syncing would
135
- * be wrong at this point: for a constant register where TCG and
136
- * KVM disagree about its value, the preceding write_list_to_cpustate()
137
- * would not have had any effect on the CPUARMState value (since the
138
- * register is read-only), and a write_cpustate_to_list() here would
139
- * then try to write the TCG value back into KVM -- this would either
140
- * fail or incorrectly change the value the guest sees.
141
- *
142
- * If we ever want to allow the user to modify cp15 registers via
143
- * the gdb stub, we would need to be more clever here (for instance
144
- * tracking the set of registers kvm_arch_get_registers() successfully
145
- * managed to update the CPUARMState with, and only allowing those
146
- * to be written back up into the kernel).
147
- */
148
+ write_cpustate_to_list(cpu, true);
149
+
150
if (!write_list_to_kvmstate(cpu, level)) {
151
return EINVAL;
152
}
153
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/target/arm/kvm64.c
156
+++ b/target/arm/kvm64.c
157
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
158
return ret;
159
}
160
161
+ write_cpustate_to_list(cpu, true);
162
+
163
if (!write_list_to_kvmstate(cpu, level)) {
164
return EINVAL;
165
}
166
diff --git a/target/arm/machine.c b/target/arm/machine.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/arm/machine.c
169
+++ b/target/arm/machine.c
170
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
171
abort();
172
}
173
} else {
174
- if (!write_cpustate_to_list(cpu)) {
175
+ if (!write_cpustate_to_list(cpu, false)) {
176
/* This should never fail. */
177
abort();
178
}
179
--
180
2.20.1
181
182
diff view generated by jsdifflib
Deleted patch
1
Peter Crosthwaite hasn't had the bandwidth to do code review or
2
other QEMU work for some time now -- remove his email address
3
from MAINTAINERS file entries so we don't bombard him with
4
patch emails.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190207181422.4907-1-peter.maydell@linaro.org
8
---
9
MAINTAINERS | 4 ----
10
1 file changed, 4 deletions(-)
11
12
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
14
--- a/MAINTAINERS
15
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ Guest CPU cores (TCG):
17
----------------------
18
Overall
19
L: qemu-devel@nongnu.org
20
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
21
M: Richard Henderson <rth@twiddle.net>
22
R: Paolo Bonzini <pbonzini@redhat.com>
23
S: Maintained
24
@@ -XXX,XX +XXX,XX @@ F: tests/virtio-scsi-test.c
25
T: git https://github.com/bonzini/qemu.git scsi-next
26
27
SSI
28
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
29
M: Alistair Francis <alistair@alistair23.me>
30
S: Maintained
31
F: hw/ssi/*
32
@@ -XXX,XX +XXX,XX @@ F: tests/m25p80-test.c
33
34
Xilinx SPI
35
M: Alistair Francis <alistair@alistair23.me>
36
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
37
S: Maintained
38
F: hw/ssi/xilinx_*
39
40
@@ -XXX,XX +XXX,XX @@ F: qom/cpu.c
41
F: include/qom/cpu.h
42
43
Device Tree
44
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
45
M: Alexander Graf <agraf@suse.de>
46
S: Maintained
47
F: device_tree.c
48
--
49
2.20.1
50
51
diff view generated by jsdifflib
Deleted patch
1
The code for handling the NVIC SHPR1 register intends to permit
2
byte and halfword accesses (as the architecture requires). However
3
the 'case' line for it only lists the base address of the
4
register, so attempts to access bytes other than the first one
5
end up in the "bad write" default logic. This bug was added
6
accidentally when we split out the SHPR1 logic from SHPR2 and
7
SHPR3 to support v6M.
8
1
9
Fixes: 7c9140afd594 ("nvic: Handle ARMv6-M SCS reserved registers")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
13
The Zephyr RTOS happens to access SHPR1 byte at a time,
14
which is how I spotted this.
15
---
16
hw/intc/armv7m_nvic.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/armv7m_nvic.c
22
+++ b/hw/intc/armv7m_nvic.c
23
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
24
}
25
}
26
break;
27
- case 0xd18: /* System Handler Priority (SHPR1) */
28
+ case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
29
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
30
val = 0;
31
break;
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
33
}
34
nvic_irq_update(s);
35
return MEMTX_OK;
36
- case 0xd18: /* System Handler Priority (SHPR1) */
37
+ case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
38
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
39
return MEMTX_OK;
40
}
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
In commit 91c1e9fcbd7548db368 where we added dual-CPU support to
2
the ARMSSE, we set up the wiring of the expansion IRQs via nested
3
loops: the outer loop on 'i' loops for each CPU, and the inner loop
4
on 'j' loops for each interrupt. Fix a typo which meant we were
5
wiring every expansion IRQ line to external IRQ 0 on CPU 0 and
6
to external IRQ 1 on CPU 1.
7
1
8
Fixes: 91c1e9fcbd7548db368 ("hw/arm/armsse: Support dual-CPU configuration")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
---
12
hw/arm/armsse.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/armsse.c
18
+++ b/hw/arm/armsse.c
19
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
20
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
21
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
22
for (j = 0; j < s->exp_numirq; j++) {
23
- s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
24
+ s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
25
}
26
if (i == 0) {
27
gpioname = g_strdup("EXP_IRQ");
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Since we're now handling a == b generically, we no longer need
4
to do it by hand within target/arm/.
5
6
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190209033847.9014-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 6 +-----
12
target/arm/translate-sve.c | 6 +-----
13
target/arm/translate.c | 12 +++---------
14
3 files changed, 5 insertions(+), 19 deletions(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
21
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
22
return;
23
case 2: /* ORR */
24
- if (rn == rm) { /* MOV */
25
- gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_mov, 0);
26
- } else {
27
- gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
28
- }
29
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
30
return;
31
case 3: /* ORN */
32
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
36
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
38
39
static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a)
40
{
41
- if (a->rn == a->rm) { /* MOV */
42
- return do_mov_z(s, a->rd, a->rn);
43
- } else {
44
- return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
45
- }
46
+ return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
47
}
48
49
static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a)
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate.c
53
+++ b/target/arm/translate.c
54
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
55
tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
56
vec_size, vec_size);
57
break;
58
- case 2:
59
- if (rn == rm) {
60
- /* VMOV */
61
- tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
62
- } else {
63
- /* VORR */
64
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
65
- vec_size, vec_size);
66
- }
67
+ case 2: /* VORR */
68
+ tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
69
+ vec_size, vec_size);
70
break;
71
case 3: /* VORN */
72
tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190209033847.9014-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 35 ++++++++++++++---------------------
9
1 file changed, 14 insertions(+), 21 deletions(-)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
16
}
17
18
switch (opcode) {
19
+ case 0x0c: /* SMAX, UMAX */
20
+ if (u) {
21
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
22
+ } else {
23
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smax, size);
24
+ }
25
+ return;
26
+ case 0x0d: /* SMIN, UMIN */
27
+ if (u) {
28
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umin, size);
29
+ } else {
30
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
31
+ }
32
+ return;
33
case 0x10: /* ADD, SUB */
34
if (u) {
35
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
37
genenvfn = fns[size][u];
38
break;
39
}
40
- case 0xc: /* SMAX, UMAX */
41
- {
42
- static NeonGenTwoOpFn * const fns[3][2] = {
43
- { gen_helper_neon_max_s8, gen_helper_neon_max_u8 },
44
- { gen_helper_neon_max_s16, gen_helper_neon_max_u16 },
45
- { tcg_gen_smax_i32, tcg_gen_umax_i32 },
46
- };
47
- genfn = fns[size][u];
48
- break;
49
- }
50
-
51
- case 0xd: /* SMIN, UMIN */
52
- {
53
- static NeonGenTwoOpFn * const fns[3][2] = {
54
- { gen_helper_neon_min_s8, gen_helper_neon_min_u8 },
55
- { gen_helper_neon_min_s16, gen_helper_neon_min_u16 },
56
- { tcg_gen_smin_i32, tcg_gen_umin_i32 },
57
- };
58
- genfn = fns[size][u];
59
- break;
60
- }
61
case 0xe: /* SABD, UABD */
62
case 0xf: /* SABA, UABA */
63
{
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190209033847.9014-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 25 +++++++++++++++++++------
9
1 file changed, 19 insertions(+), 6 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
16
tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
17
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
18
return 0;
19
+
20
+ case NEON_3R_VMAX:
21
+ if (u) {
22
+ tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
23
+ vec_size, vec_size);
24
+ } else {
25
+ tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
26
+ vec_size, vec_size);
27
+ }
28
+ return 0;
29
+ case NEON_3R_VMIN:
30
+ if (u) {
31
+ tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
32
+ vec_size, vec_size);
33
+ } else {
34
+ tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
35
+ vec_size, vec_size);
36
+ }
37
+ return 0;
38
}
39
40
if (size == 3) {
41
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
42
case NEON_3R_VQRSHL:
43
GEN_NEON_INTEGER_OP_ENV(qrshl);
44
break;
45
- case NEON_3R_VMAX:
46
- GEN_NEON_INTEGER_OP(max);
47
- break;
48
- case NEON_3R_VMIN:
49
- GEN_NEON_INTEGER_OP(min);
50
- break;
51
case NEON_3R_VABD:
52
GEN_NEON_INTEGER_OP(abd);
53
break;
54
--
55
2.20.1
56
57
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The 32-bit PMIN/PMAX has been decomposed to scalars,
4
and so can be trivially expanded inline.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190209033847.9014-5-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.c | 8 ++++----
12
1 file changed, 4 insertions(+), 4 deletions(-)
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
19
}
20
21
/* 32-bit pairwise ops end up the same as the elementwise versions. */
22
-#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
23
-#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
24
-#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
25
-#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
26
+#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
27
+#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
28
+#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
29
+#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
30
31
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
32
switch ((size << 1) | u) { \
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
These are now unused.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190209033847.9014-6-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.h | 12 ------------
11
target/arm/neon_helper.c | 12 ------------
12
2 files changed, 24 deletions(-)
13
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
17
+++ b/target/arm/helper.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_cge_s16, i32, i32, i32)
19
DEF_HELPER_2(neon_cge_u32, i32, i32, i32)
20
DEF_HELPER_2(neon_cge_s32, i32, i32, i32)
21
22
-DEF_HELPER_2(neon_min_u8, i32, i32, i32)
23
-DEF_HELPER_2(neon_min_s8, i32, i32, i32)
24
-DEF_HELPER_2(neon_min_u16, i32, i32, i32)
25
-DEF_HELPER_2(neon_min_s16, i32, i32, i32)
26
-DEF_HELPER_2(neon_min_u32, i32, i32, i32)
27
-DEF_HELPER_2(neon_min_s32, i32, i32, i32)
28
-DEF_HELPER_2(neon_max_u8, i32, i32, i32)
29
-DEF_HELPER_2(neon_max_s8, i32, i32, i32)
30
-DEF_HELPER_2(neon_max_u16, i32, i32, i32)
31
-DEF_HELPER_2(neon_max_s16, i32, i32, i32)
32
-DEF_HELPER_2(neon_max_u32, i32, i32, i32)
33
-DEF_HELPER_2(neon_max_s32, i32, i32, i32)
34
DEF_HELPER_2(neon_pmin_u8, i32, i32, i32)
35
DEF_HELPER_2(neon_pmin_s8, i32, i32, i32)
36
DEF_HELPER_2(neon_pmin_u16, i32, i32, i32)
37
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/neon_helper.c
40
+++ b/target/arm/neon_helper.c
41
@@ -XXX,XX +XXX,XX @@ NEON_VOP(cge_u32, neon_u32, 1)
42
#undef NEON_FN
43
44
#define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
45
-NEON_VOP(min_s8, neon_s8, 4)
46
-NEON_VOP(min_u8, neon_u8, 4)
47
-NEON_VOP(min_s16, neon_s16, 2)
48
-NEON_VOP(min_u16, neon_u16, 2)
49
-NEON_VOP(min_s32, neon_s32, 1)
50
-NEON_VOP(min_u32, neon_u32, 1)
51
NEON_POP(pmin_s8, neon_s8, 4)
52
NEON_POP(pmin_u8, neon_u8, 4)
53
NEON_POP(pmin_s16, neon_s16, 2)
54
@@ -XXX,XX +XXX,XX @@ NEON_POP(pmin_u16, neon_u16, 2)
55
#undef NEON_FN
56
57
#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
58
-NEON_VOP(max_s8, neon_s8, 4)
59
-NEON_VOP(max_u8, neon_u8, 4)
60
-NEON_VOP(max_s16, neon_s16, 2)
61
-NEON_VOP(max_u16, neon_u16, 2)
62
-NEON_VOP(max_s32, neon_s32, 1)
63
-NEON_VOP(max_u32, neon_u32, 1)
64
NEON_POP(pmax_s8, neon_s8, 4)
65
NEON_POP(pmax_u8, neon_u8, 4)
66
NEON_POP(pmax_s16, neon_s16, 2)
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The components of this register is stored in several
4
different locations.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190209033847.9014-7-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/helper.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
19
}
20
switch (reg - nregs) {
21
case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
22
- case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
23
+ case 1: stl_p(buf, vfp_get_fpscr(env)); return 4;
24
case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
25
}
26
return 0;
27
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
28
}
29
switch (reg - nregs) {
30
case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
31
- case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
32
+ case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
33
case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
34
}
35
return 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190209033847.9014-8-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
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 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
16
i * 2 + 1, (uint32_t)(v >> 32),
17
i, v);
18
}
19
- cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
20
+ cpu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
21
}
22
}
23
24
--
25
2.20.1
26
27
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Minimize the code within a macro by splitting out a helper function.
4
Use deposit32 instead of manual bit manipulation.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190209033847.9014-9-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/helper.c | 45 +++++++++++++++++++++++++++------------------
12
1 file changed, 27 insertions(+), 18 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
19
return float64_sqrt(a, &env->vfp.fp_status);
20
}
21
22
+static void softfloat_to_vfp_compare(CPUARMState *env, int cmp)
23
+{
24
+ uint32_t flags;
25
+ switch (cmp) {
26
+ case float_relation_equal:
27
+ flags = 0x6;
28
+ break;
29
+ case float_relation_less:
30
+ flags = 0x8;
31
+ break;
32
+ case float_relation_greater:
33
+ flags = 0x2;
34
+ break;
35
+ case float_relation_unordered:
36
+ flags = 0x3;
37
+ break;
38
+ default:
39
+ g_assert_not_reached();
40
+ }
41
+ env->vfp.xregs[ARM_VFP_FPSCR] =
42
+ deposit32(env->vfp.xregs[ARM_VFP_FPSCR], 28, 4, flags);
43
+}
44
+
45
/* XXX: check quiet/signaling case */
46
#define DO_VFP_cmp(p, type) \
47
void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
48
{ \
49
- uint32_t flags; \
50
- switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
51
- case 0: flags = 0x6; break; \
52
- case -1: flags = 0x8; break; \
53
- case 1: flags = 0x2; break; \
54
- default: case 2: flags = 0x3; break; \
55
- } \
56
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
57
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
58
+ softfloat_to_vfp_compare(env, \
59
+ type ## _compare_quiet(a, b, &env->vfp.fp_status)); \
60
} \
61
void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
62
{ \
63
- uint32_t flags; \
64
- switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
65
- case 0: flags = 0x6; break; \
66
- case -1: flags = 0x8; break; \
67
- case 1: flags = 0x2; break; \
68
- default: case 2: flags = 0x3; break; \
69
- } \
70
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
71
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
72
+ softfloat_to_vfp_compare(env, \
73
+ type ## _compare(a, b, &env->vfp.fp_status)); \
74
}
75
DO_VFP_cmp(s, float32)
76
DO_VFP_cmp(d, float64)
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Given that we mask bits properly on set, there is no reason
4
to mask them again on get. We failed to clear the exception
5
status bits, 0x9f, which means that the wrong value would be
6
returned on get. Except in the (probably normal) case in which
7
the set clears all of the bits.
8
9
Simplify the code in set to also clear the RES0 bits.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190209033847.9014-10-richard.henderson@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper.c | 15 ++++++++-------
17
1 file changed, 8 insertions(+), 7 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
24
int i;
25
uint32_t fpscr;
26
27
- fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
28
+ fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
29
| (env->vfp.vec_len << 16)
30
| (env->vfp.vec_stride << 20);
31
32
@@ -XXX,XX +XXX,XX @@ static inline int vfp_exceptbits_to_host(int target_bits)
33
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
34
{
35
int i;
36
- uint32_t changed;
37
+ uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
38
39
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
40
if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
41
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
42
43
/*
44
* We don't implement trapped exception handling, so the
45
- * trap enable bits are all RAZ/WI (not RES0!)
46
+ * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
47
+ *
48
+ * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
49
+ * (which are stored in fp_status), and the other RES0 bits
50
+ * in between, then we clear all of the low 16 bits.
51
*/
52
- val &= ~(FPCR_IDE | FPCR_IXE | FPCR_UFE | FPCR_OFE | FPCR_DZE | FPCR_IOE);
53
-
54
- changed = env->vfp.xregs[ARM_VFP_FPSCR];
55
- env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
56
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xffc80000;
57
env->vfp.vec_len = (val >> 16) & 7;
58
env->vfp.vec_stride = (val >> 20) & 3;
59
60
--
61
2.20.1
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Change the representation of this field such that it is easy
4
to set from vector code.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190209033847.9014-11-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/cpu.h | 5 ++++-
12
target/arm/helper.c | 19 +++++++++++++++----
13
target/arm/neon_helper.c | 2 +-
14
target/arm/vec_helper.c | 2 +-
15
4 files changed, 21 insertions(+), 7 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
ARMPredicateReg preg_tmp;
23
#endif
24
25
- uint32_t xregs[16];
26
/* We store these fpcsr fields separately for convenience. */
27
+ uint32_t qc[4] QEMU_ALIGNED(16);
28
int vec_len;
29
int vec_stride;
30
31
+ uint32_t xregs[16];
32
+
33
/* Scratch space for aa32 neon expansion. */
34
uint32_t scratch[8];
35
36
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
37
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
38
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
39
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
40
+#define FPCR_QC (1 << 27) /* Cumulative saturation bit */
41
42
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
43
{
44
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper.c
47
+++ b/target/arm/helper.c
48
@@ -XXX,XX +XXX,XX @@ static inline int vfp_exceptbits_from_host(int host_bits)
49
50
uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
51
{
52
- int i;
53
- uint32_t fpscr;
54
+ uint32_t i, fpscr;
55
56
fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
57
| (env->vfp.vec_len << 16)
58
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
59
/* FZ16 does not generate an input denormal exception. */
60
i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
61
& ~float_flag_input_denormal);
62
-
63
fpscr |= vfp_exceptbits_from_host(i);
64
+
65
+ i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
66
+ fpscr |= i ? FPCR_QC : 0;
67
+
68
return fpscr;
69
}
70
71
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
72
* (which are stored in fp_status), and the other RES0 bits
73
* in between, then we clear all of the low 16 bits.
74
*/
75
- env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xffc80000;
76
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
77
env->vfp.vec_len = (val >> 16) & 7;
78
env->vfp.vec_stride = (val >> 20) & 3;
79
80
+ /*
81
+ * The bit we set within fpscr_q is arbitrary; the register as a
82
+ * whole being zero/non-zero is what counts.
83
+ */
84
+ env->vfp.qc[0] = val & FPCR_QC;
85
+ env->vfp.qc[1] = 0;
86
+ env->vfp.qc[2] = 0;
87
+ env->vfp.qc[3] = 0;
88
+
89
changed ^= val;
90
if (changed & (3 << 22)) {
91
i = (val >> 22) & 3;
92
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/neon_helper.c
95
+++ b/target/arm/neon_helper.c
96
@@ -XXX,XX +XXX,XX @@
97
#define SIGNBIT (uint32_t)0x80000000
98
#define SIGNBIT64 ((uint64_t)1 << 63)
99
100
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
101
+#define SET_QC() env->vfp.qc[0] = 1
102
103
#define NEON_TYPE1(name, type) \
104
typedef struct \
105
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/vec_helper.c
108
+++ b/target/arm/vec_helper.c
109
@@ -XXX,XX +XXX,XX @@
110
#define H4(x) (x)
111
#endif
112
113
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
114
+#define SET_QC() env->vfp.qc[0] = 1
115
116
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
117
{
118
--
119
2.20.1
120
121
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
For same-sign saturation, we have tcg vector operations. We can
4
compute the QC bit by comparing the saturated value against the
5
unsaturated value.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190209033847.9014-12-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/helper.h | 33 +++++++
13
target/arm/translate.h | 4 +
14
target/arm/translate-a64.c | 36 ++++----
15
target/arm/translate.c | 172 +++++++++++++++++++++++++++++++------
16
target/arm/vec_helper.c | 130 ++++++++++++++++++++++++++++
17
5 files changed, 331 insertions(+), 44 deletions(-)
18
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
22
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
24
DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
25
void, ptr, ptr, ptr, ptr, ptr, i32)
26
27
+DEF_HELPER_FLAGS_5(gvec_uqadd_b, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(gvec_uqadd_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(gvec_uqadd_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(gvec_uqadd_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(gvec_sqadd_b, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_5(gvec_sqadd_h, TCG_CALL_NO_RWG,
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(gvec_sqadd_s, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(gvec_sqadd_d, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_5(gvec_uqsub_b, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(gvec_uqsub_h, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_5(gvec_uqsub_s, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_5(gvec_uqsub_d, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(gvec_sqsub_b, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_5(gvec_sqsub_h, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(gvec_sqsub_s, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, i32)
57
+DEF_HELPER_FLAGS_5(gvec_sqsub_d, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, i32)
59
+
60
#ifdef TARGET_AARCH64
61
#include "helper-a64.h"
62
#include "helper-sve.h"
63
diff --git a/target/arm/translate.h b/target/arm/translate.h
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.h
66
+++ b/target/arm/translate.h
67
@@ -XXX,XX +XXX,XX @@ extern const GVecGen2i ssra_op[4];
68
extern const GVecGen2i usra_op[4];
69
extern const GVecGen2i sri_op[4];
70
extern const GVecGen2i sli_op[4];
71
+extern const GVecGen4 uqadd_op[4];
72
+extern const GVecGen4 sqadd_op[4];
73
+extern const GVecGen4 uqsub_op[4];
74
+extern const GVecGen4 sqsub_op[4];
75
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
76
77
/*
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
83
}
84
85
switch (opcode) {
86
+ case 0x01: /* SQADD, UQADD */
87
+ tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
88
+ offsetof(CPUARMState, vfp.qc),
89
+ vec_full_reg_offset(s, rn),
90
+ vec_full_reg_offset(s, rm),
91
+ is_q ? 16 : 8, vec_full_reg_size(s),
92
+ (u ? uqadd_op : sqadd_op) + size);
93
+ return;
94
+ case 0x05: /* SQSUB, UQSUB */
95
+ tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
96
+ offsetof(CPUARMState, vfp.qc),
97
+ vec_full_reg_offset(s, rn),
98
+ vec_full_reg_offset(s, rm),
99
+ is_q ? 16 : 8, vec_full_reg_size(s),
100
+ (u ? uqsub_op : sqsub_op) + size);
101
+ return;
102
case 0x0c: /* SMAX, UMAX */
103
if (u) {
104
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
105
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
106
genfn = fns[size][u];
107
break;
108
}
109
- case 0x1: /* SQADD, UQADD */
110
- {
111
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
112
- { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
113
- { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
114
- { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
115
- };
116
- genenvfn = fns[size][u];
117
- break;
118
- }
119
case 0x2: /* SRHADD, URHADD */
120
{
121
static NeonGenTwoOpFn * const fns[3][2] = {
122
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
123
genfn = fns[size][u];
124
break;
125
}
126
- case 0x5: /* SQSUB, UQSUB */
127
- {
128
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
129
- { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
130
- { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
131
- { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
132
- };
133
- genenvfn = fns[size][u];
134
- break;
135
- }
136
case 0x8: /* SSHL, USHL */
137
{
138
static NeonGenTwoOpFn * const fns[3][2] = {
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ const GVecGen3 cmtst_op[4] = {
144
.vece = MO_64 },
145
};
146
147
+static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
148
+ TCGv_vec a, TCGv_vec b)
149
+{
150
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
151
+ tcg_gen_add_vec(vece, x, a, b);
152
+ tcg_gen_usadd_vec(vece, t, a, b);
153
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
154
+ tcg_gen_or_vec(vece, sat, sat, x);
155
+ tcg_temp_free_vec(x);
156
+}
157
+
158
+const GVecGen4 uqadd_op[4] = {
159
+ { .fniv = gen_uqadd_vec,
160
+ .fno = gen_helper_gvec_uqadd_b,
161
+ .opc = INDEX_op_usadd_vec,
162
+ .write_aofs = true,
163
+ .vece = MO_8 },
164
+ { .fniv = gen_uqadd_vec,
165
+ .fno = gen_helper_gvec_uqadd_h,
166
+ .opc = INDEX_op_usadd_vec,
167
+ .write_aofs = true,
168
+ .vece = MO_16 },
169
+ { .fniv = gen_uqadd_vec,
170
+ .fno = gen_helper_gvec_uqadd_s,
171
+ .opc = INDEX_op_usadd_vec,
172
+ .write_aofs = true,
173
+ .vece = MO_32 },
174
+ { .fniv = gen_uqadd_vec,
175
+ .fno = gen_helper_gvec_uqadd_d,
176
+ .opc = INDEX_op_usadd_vec,
177
+ .write_aofs = true,
178
+ .vece = MO_64 },
179
+};
180
+
181
+static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
182
+ TCGv_vec a, TCGv_vec b)
183
+{
184
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
185
+ tcg_gen_add_vec(vece, x, a, b);
186
+ tcg_gen_ssadd_vec(vece, t, a, b);
187
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
188
+ tcg_gen_or_vec(vece, sat, sat, x);
189
+ tcg_temp_free_vec(x);
190
+}
191
+
192
+const GVecGen4 sqadd_op[4] = {
193
+ { .fniv = gen_sqadd_vec,
194
+ .fno = gen_helper_gvec_sqadd_b,
195
+ .opc = INDEX_op_ssadd_vec,
196
+ .write_aofs = true,
197
+ .vece = MO_8 },
198
+ { .fniv = gen_sqadd_vec,
199
+ .fno = gen_helper_gvec_sqadd_h,
200
+ .opc = INDEX_op_ssadd_vec,
201
+ .write_aofs = true,
202
+ .vece = MO_16 },
203
+ { .fniv = gen_sqadd_vec,
204
+ .fno = gen_helper_gvec_sqadd_s,
205
+ .opc = INDEX_op_ssadd_vec,
206
+ .write_aofs = true,
207
+ .vece = MO_32 },
208
+ { .fniv = gen_sqadd_vec,
209
+ .fno = gen_helper_gvec_sqadd_d,
210
+ .opc = INDEX_op_ssadd_vec,
211
+ .write_aofs = true,
212
+ .vece = MO_64 },
213
+};
214
+
215
+static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
216
+ TCGv_vec a, TCGv_vec b)
217
+{
218
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
219
+ tcg_gen_sub_vec(vece, x, a, b);
220
+ tcg_gen_ussub_vec(vece, t, a, b);
221
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
222
+ tcg_gen_or_vec(vece, sat, sat, x);
223
+ tcg_temp_free_vec(x);
224
+}
225
+
226
+const GVecGen4 uqsub_op[4] = {
227
+ { .fniv = gen_uqsub_vec,
228
+ .fno = gen_helper_gvec_uqsub_b,
229
+ .opc = INDEX_op_ussub_vec,
230
+ .write_aofs = true,
231
+ .vece = MO_8 },
232
+ { .fniv = gen_uqsub_vec,
233
+ .fno = gen_helper_gvec_uqsub_h,
234
+ .opc = INDEX_op_ussub_vec,
235
+ .write_aofs = true,
236
+ .vece = MO_16 },
237
+ { .fniv = gen_uqsub_vec,
238
+ .fno = gen_helper_gvec_uqsub_s,
239
+ .opc = INDEX_op_ussub_vec,
240
+ .write_aofs = true,
241
+ .vece = MO_32 },
242
+ { .fniv = gen_uqsub_vec,
243
+ .fno = gen_helper_gvec_uqsub_d,
244
+ .opc = INDEX_op_ussub_vec,
245
+ .write_aofs = true,
246
+ .vece = MO_64 },
247
+};
248
+
249
+static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
250
+ TCGv_vec a, TCGv_vec b)
251
+{
252
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
253
+ tcg_gen_sub_vec(vece, x, a, b);
254
+ tcg_gen_sssub_vec(vece, t, a, b);
255
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
256
+ tcg_gen_or_vec(vece, sat, sat, x);
257
+ tcg_temp_free_vec(x);
258
+}
259
+
260
+const GVecGen4 sqsub_op[4] = {
261
+ { .fniv = gen_sqsub_vec,
262
+ .fno = gen_helper_gvec_sqsub_b,
263
+ .opc = INDEX_op_sssub_vec,
264
+ .write_aofs = true,
265
+ .vece = MO_8 },
266
+ { .fniv = gen_sqsub_vec,
267
+ .fno = gen_helper_gvec_sqsub_h,
268
+ .opc = INDEX_op_sssub_vec,
269
+ .write_aofs = true,
270
+ .vece = MO_16 },
271
+ { .fniv = gen_sqsub_vec,
272
+ .fno = gen_helper_gvec_sqsub_s,
273
+ .opc = INDEX_op_sssub_vec,
274
+ .write_aofs = true,
275
+ .vece = MO_32 },
276
+ { .fniv = gen_sqsub_vec,
277
+ .fno = gen_helper_gvec_sqsub_d,
278
+ .opc = INDEX_op_sssub_vec,
279
+ .write_aofs = true,
280
+ .vece = MO_64 },
281
+};
282
+
283
/* Translate a NEON data processing instruction. Return nonzero if the
284
instruction is invalid.
285
We process data in a mixture of 32-bit and 64-bit chunks.
286
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
287
}
288
return 0;
289
290
+ case NEON_3R_VQADD:
291
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
292
+ rn_ofs, rm_ofs, vec_size, vec_size,
293
+ (u ? uqadd_op : sqadd_op) + size);
294
+ break;
295
+
296
+ case NEON_3R_VQSUB:
297
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
298
+ rn_ofs, rm_ofs, vec_size, vec_size,
299
+ (u ? uqsub_op : sqsub_op) + size);
300
+ break;
301
+
302
case NEON_3R_VMUL: /* VMUL */
303
if (u) {
304
/* Polynomial case allows only P8 and is handled below. */
305
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
306
neon_load_reg64(cpu_V0, rn + pass);
307
neon_load_reg64(cpu_V1, rm + pass);
308
switch (op) {
309
- case NEON_3R_VQADD:
310
- if (u) {
311
- gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
312
- cpu_V0, cpu_V1);
313
- } else {
314
- gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
315
- cpu_V0, cpu_V1);
316
- }
317
- break;
318
- case NEON_3R_VQSUB:
319
- if (u) {
320
- gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
321
- cpu_V0, cpu_V1);
322
- } else {
323
- gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
324
- cpu_V0, cpu_V1);
325
- }
326
- break;
327
case NEON_3R_VSHL:
328
if (u) {
329
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
330
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
331
case NEON_3R_VHADD:
332
GEN_NEON_INTEGER_OP(hadd);
333
break;
334
- case NEON_3R_VQADD:
335
- GEN_NEON_INTEGER_OP_ENV(qadd);
336
- break;
337
case NEON_3R_VRHADD:
338
GEN_NEON_INTEGER_OP(rhadd);
339
break;
340
case NEON_3R_VHSUB:
341
GEN_NEON_INTEGER_OP(hsub);
342
break;
343
- case NEON_3R_VQSUB:
344
- GEN_NEON_INTEGER_OP_ENV(qsub);
345
- break;
346
case NEON_3R_VSHL:
347
GEN_NEON_INTEGER_OP(shl);
348
break;
349
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
350
index XXXXXXX..XXXXXXX 100644
351
--- a/target/arm/vec_helper.c
352
+++ b/target/arm/vec_helper.c
353
@@ -XXX,XX +XXX,XX @@ DO_FMLA_IDX(gvec_fmla_idx_s, float32, H4)
354
DO_FMLA_IDX(gvec_fmla_idx_d, float64, )
355
356
#undef DO_FMLA_IDX
357
+
358
+#define DO_SAT(NAME, WTYPE, TYPEN, TYPEM, OP, MIN, MAX) \
359
+void HELPER(NAME)(void *vd, void *vq, void *vn, void *vm, uint32_t desc) \
360
+{ \
361
+ intptr_t i, oprsz = simd_oprsz(desc); \
362
+ TYPEN *d = vd, *n = vn; TYPEM *m = vm; \
363
+ bool q = false; \
364
+ for (i = 0; i < oprsz / sizeof(TYPEN); i++) { \
365
+ WTYPE dd = (WTYPE)n[i] OP m[i]; \
366
+ if (dd < MIN) { \
367
+ dd = MIN; \
368
+ q = true; \
369
+ } else if (dd > MAX) { \
370
+ dd = MAX; \
371
+ q = true; \
372
+ } \
373
+ d[i] = dd; \
374
+ } \
375
+ if (q) { \
376
+ uint32_t *qc = vq; \
377
+ qc[0] = 1; \
378
+ } \
379
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
380
+}
381
+
382
+DO_SAT(gvec_uqadd_b, int, uint8_t, uint8_t, +, 0, UINT8_MAX)
383
+DO_SAT(gvec_uqadd_h, int, uint16_t, uint16_t, +, 0, UINT16_MAX)
384
+DO_SAT(gvec_uqadd_s, int64_t, uint32_t, uint32_t, +, 0, UINT32_MAX)
385
+
386
+DO_SAT(gvec_sqadd_b, int, int8_t, int8_t, +, INT8_MIN, INT8_MAX)
387
+DO_SAT(gvec_sqadd_h, int, int16_t, int16_t, +, INT16_MIN, INT16_MAX)
388
+DO_SAT(gvec_sqadd_s, int64_t, int32_t, int32_t, +, INT32_MIN, INT32_MAX)
389
+
390
+DO_SAT(gvec_uqsub_b, int, uint8_t, uint8_t, -, 0, UINT8_MAX)
391
+DO_SAT(gvec_uqsub_h, int, uint16_t, uint16_t, -, 0, UINT16_MAX)
392
+DO_SAT(gvec_uqsub_s, int64_t, uint32_t, uint32_t, -, 0, UINT32_MAX)
393
+
394
+DO_SAT(gvec_sqsub_b, int, int8_t, int8_t, -, INT8_MIN, INT8_MAX)
395
+DO_SAT(gvec_sqsub_h, int, int16_t, int16_t, -, INT16_MIN, INT16_MAX)
396
+DO_SAT(gvec_sqsub_s, int64_t, int32_t, int32_t, -, INT32_MIN, INT32_MAX)
397
+
398
+#undef DO_SAT
399
+
400
+void HELPER(gvec_uqadd_d)(void *vd, void *vq, void *vn,
401
+ void *vm, uint32_t desc)
402
+{
403
+ intptr_t i, oprsz = simd_oprsz(desc);
404
+ uint64_t *d = vd, *n = vn, *m = vm;
405
+ bool q = false;
406
+
407
+ for (i = 0; i < oprsz / 8; i++) {
408
+ uint64_t nn = n[i], mm = m[i], dd = nn + mm;
409
+ if (dd < nn) {
410
+ dd = UINT64_MAX;
411
+ q = true;
412
+ }
413
+ d[i] = dd;
414
+ }
415
+ if (q) {
416
+ uint32_t *qc = vq;
417
+ qc[0] = 1;
418
+ }
419
+ clear_tail(d, oprsz, simd_maxsz(desc));
420
+}
421
+
422
+void HELPER(gvec_uqsub_d)(void *vd, void *vq, void *vn,
423
+ void *vm, uint32_t desc)
424
+{
425
+ intptr_t i, oprsz = simd_oprsz(desc);
426
+ uint64_t *d = vd, *n = vn, *m = vm;
427
+ bool q = false;
428
+
429
+ for (i = 0; i < oprsz / 8; i++) {
430
+ uint64_t nn = n[i], mm = m[i], dd = nn - mm;
431
+ if (nn < mm) {
432
+ dd = 0;
433
+ q = true;
434
+ }
435
+ d[i] = dd;
436
+ }
437
+ if (q) {
438
+ uint32_t *qc = vq;
439
+ qc[0] = 1;
440
+ }
441
+ clear_tail(d, oprsz, simd_maxsz(desc));
442
+}
443
+
444
+void HELPER(gvec_sqadd_d)(void *vd, void *vq, void *vn,
445
+ void *vm, uint32_t desc)
446
+{
447
+ intptr_t i, oprsz = simd_oprsz(desc);
448
+ int64_t *d = vd, *n = vn, *m = vm;
449
+ bool q = false;
450
+
451
+ for (i = 0; i < oprsz / 8; i++) {
452
+ int64_t nn = n[i], mm = m[i], dd = nn + mm;
453
+ if (((dd ^ nn) & ~(nn ^ mm)) & INT64_MIN) {
454
+ dd = (nn >> 63) ^ ~INT64_MIN;
455
+ q = true;
456
+ }
457
+ d[i] = dd;
458
+ }
459
+ if (q) {
460
+ uint32_t *qc = vq;
461
+ qc[0] = 1;
462
+ }
463
+ clear_tail(d, oprsz, simd_maxsz(desc));
464
+}
465
+
466
+void HELPER(gvec_sqsub_d)(void *vd, void *vq, void *vn,
467
+ void *vm, uint32_t desc)
468
+{
469
+ intptr_t i, oprsz = simd_oprsz(desc);
470
+ int64_t *d = vd, *n = vn, *m = vm;
471
+ bool q = false;
472
+
473
+ for (i = 0; i < oprsz / 8; i++) {
474
+ int64_t nn = n[i], mm = m[i], dd = nn - mm;
475
+ if (((dd ^ nn) & (nn ^ mm)) & INT64_MIN) {
476
+ dd = (nn >> 63) ^ ~INT64_MIN;
477
+ q = true;
478
+ }
479
+ d[i] = dd;
480
+ }
481
+ if (q) {
482
+ uint32_t *qc = vq;
483
+ qc[0] = 1;
484
+ }
485
+ clear_tail(d, oprsz, simd_maxsz(desc));
486
+}
487
--
488
2.20.1
489
490
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Fortunately, the functions affected are so far only called from SVE,
4
so there is no tail to be cleared. But as we convert more of AdvSIMD
5
to gvec, this will matter.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190209033847.9014-13-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/vec_helper.c | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
18
+++ b/target/arm/vec_helper.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \
20
for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
21
d[i] = FUNC(n[i], stat); \
22
} \
23
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
24
}
25
26
DO_2OP(gvec_frecpe_h, helper_recpe_f16, float16)
27
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
28
for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
29
d[i] = FUNC(n[i], m[i], stat); \
30
} \
31
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
32
}
33
34
DO_3OP(gvec_fadd_h, float16_add, float16)
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Sandra Loosemore <sandra@codesourcery.com>
2
1
3
Per the GDB remote protocol documentation
4
5
https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html#index-vKill-packet
6
7
the debug stub is expected to send a reply to the 'vKill' packet. At
8
least some versions of GDB crash if the gdb stub simply exits without
9
sending a reply. This patch fixes QEMU's gdb stub to conform to the
10
expected behavior.
11
12
Note that QEMU's existing handling of the legacy 'k' packet is
13
correct: in that case GDB does not expect a reply, and QEMU does not
14
send one.
15
16
Signed-off-by: Sandra Loosemore <sandra@codesourcery.com>
17
Message-id: 1550008033-26540-1-git-send-email-sandra@codesourcery.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
gdbstub.c | 1 +
22
1 file changed, 1 insertion(+)
23
24
diff --git a/gdbstub.c b/gdbstub.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/gdbstub.c
27
+++ b/gdbstub.c
28
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
29
break;
30
} else if (strncmp(p, "Kill;", 5) == 0) {
31
/* Kill the target */
32
+ put_packet(s, "OK");
33
error_report("QEMU: Terminated via GDBstub");
34
exit(0);
35
} else {
36
--
37
2.20.1
38
39
diff view generated by jsdifflib